From cd064dd8cce624a541b5c966d9449aa5df4072b3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Sep 2024 10:03:58 -0700 Subject: [PATCH 01/34] [release/9.0] Consider existence of EETypes and metadata for typeof checks (#107598) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Under some circumstances, the compiler could assume code under if (someType == typeof(Foo)) is unreachable and optimize it into an infinite loop. This can happen when type Foo was only visible in metadata and not actually used at runtime. Fixes #107300. --------- Co-authored-by: Michal Strehovský --- .../Compiler/SubstitutedILProvider.cs | 10 +++++++- .../IL/ILImporter.Scanner.cs | 11 ++++++++- src/coreclr/tools/aot/ILCompiler/Program.cs | 2 +- .../TrimmingBehaviors/DeadCodeElimination.cs | 23 +++++++++++++++++++ 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/SubstitutedILProvider.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/SubstitutedILProvider.cs index 00b0d1143f168..6b339f8a89d2e 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/SubstitutedILProvider.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/SubstitutedILProvider.cs @@ -23,12 +23,14 @@ public class SubstitutedILProvider : ILProvider private readonly ILProvider _nestedILProvider; private readonly SubstitutionProvider _substitutionProvider; private readonly DevirtualizationManager _devirtualizationManager; + private readonly MetadataManager _metadataManager; - public SubstitutedILProvider(ILProvider nestedILProvider, SubstitutionProvider substitutionProvider, DevirtualizationManager devirtualizationManager) + public SubstitutedILProvider(ILProvider nestedILProvider, SubstitutionProvider substitutionProvider, DevirtualizationManager devirtualizationManager, MetadataManager metadataManager = null) { _nestedILProvider = nestedILProvider; _substitutionProvider = substitutionProvider; _devirtualizationManager = devirtualizationManager; + _metadataManager = metadataManager; } public override MethodIL GetMethodIL(MethodDesc method) @@ -989,9 +991,15 @@ private bool TryExpandTypeEquality(in TypeEqualityPatternAnalyzer analyzer, Meth if (!ConstructedEETypeNode.CreationAllowed(knownType)) return false; + // If a constructed MethodTable for this type exists, the comparison could succeed. if (_devirtualizationManager.CanReferenceConstructedTypeOrCanonicalFormOfType(knownType.NormalizeInstantiation())) return false; + // If we can have metadata for the type the comparison could succeed even if no MethodTable present. + // (This is the case of metadata-only types, where we were able to optimize the MethodTable away.) + if (_metadataManager != null && knownType.GetTypeDefinition() is MetadataType mdType && _metadataManager.CanGenerateMetadata(mdType)) + return false; + constant = 0; } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs index 7fec5bbe20d74..406649bdc60e5 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs @@ -836,7 +836,16 @@ private void ImportBranch(ILOpcode opcode, BasicBlock target, BasicBlock fallthr && ConstructedEETypeNode.CreationAllowed(typeEqualityCheckType) && !typeEqualityCheckType.ConvertToCanonForm(CanonicalFormKind.Specific).IsCanonicalSubtype(CanonicalFormKind.Any)) { - condition = _factory.MaximallyConstructableType(typeEqualityCheckType); + // If the type could generate metadata, we set the condition to the presence of the metadata. + // This covers situations where the typeof is compared against metadata-only types. + // Note this assumes a constructed MethodTable always implies having metadata. + // This will likely remain true because anyone can call Object.GetType on a constructed type. + // If the type cannot generate metadata, we only condition on the MethodTable itself. + if (!_factory.MetadataManager.IsReflectionBlocked(typeEqualityCheckType) + && typeEqualityCheckType.GetTypeDefinition() is MetadataType typeEqualityCheckMetadataType) + condition = _factory.TypeMetadata(typeEqualityCheckMetadataType); + else + condition = _factory.MaximallyConstructableType(typeEqualityCheckType); } } diff --git a/src/coreclr/tools/aot/ILCompiler/Program.cs b/src/coreclr/tools/aot/ILCompiler/Program.cs index 30fd2028f3862..589fdf8b53848 100644 --- a/src/coreclr/tools/aot/ILCompiler/Program.cs +++ b/src/coreclr/tools/aot/ILCompiler/Program.cs @@ -499,7 +499,7 @@ void RunScanner() interopStubManager = scanResults.GetInteropStubManager(interopStateManager, pinvokePolicy); - ilProvider = new SubstitutedILProvider(unsubstitutedILProvider, substitutionProvider, devirtualizationManager); + ilProvider = new SubstitutedILProvider(unsubstitutedILProvider, substitutionProvider, devirtualizationManager, metadataManager); // Use a more precise IL provider that uses whole program analysis for dead branch elimination builder.UseILProvider(ilProvider); diff --git a/src/tests/nativeaot/SmokeTests/TrimmingBehaviors/DeadCodeElimination.cs b/src/tests/nativeaot/SmokeTests/TrimmingBehaviors/DeadCodeElimination.cs index 9fe236cef1f13..0a6090f809243 100644 --- a/src/tests/nativeaot/SmokeTests/TrimmingBehaviors/DeadCodeElimination.cs +++ b/src/tests/nativeaot/SmokeTests/TrimmingBehaviors/DeadCodeElimination.cs @@ -529,13 +529,27 @@ class TestTypeEqualityDeadBranchScanRemoval { class NeverAllocated1 { } class NeverAllocated2 { } + class NeverAllocated3 { } class PossiblyAllocated1 { } class PossiblyAllocated2 { } + class MyAttribute : Attribute + { + public Type TheType; + + public MyAttribute(Type t) => TheType = t; + } + + [My(typeof(NeverAllocated3))] + class AttributeHolder { } + [MethodImpl(MethodImplOptions.NoInlining)] static Type GetNeverObject() => null; + [MethodImpl(MethodImplOptions.NoInlining)] + static Type GetNeverAllocated3Type() => typeof(AttributeHolder).GetCustomAttribute().TheType; + static volatile Type s_sink; public static void Run() @@ -557,6 +571,15 @@ public static void Run() } if (Environment.GetEnvironmentVariable("SURETHING") != null) s_sink = typeof(PossiblyAllocated1); + + if (GetNeverAllocated3Type() == typeof(NeverAllocated3)) + { + Console.WriteLine($"{nameof(NeverAllocated3)} check succeeded"); + } + else + { + throw new Exception(); + } } } From b2d53cce80eda18d618c087f04a97ed6e72bfa0b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Sep 2024 13:26:20 -0700 Subject: [PATCH 02/34] [release/9.0] Track that kmov instructions may write to GPR register (#107476) * kmov*_gpr writes to gpr * add test * Add using --------- Co-authored-by: Kunal Pathak Co-authored-by: Jeff Schwartz --- src/coreclr/jit/emitxarch.cpp | 9 ++++- .../JitBlue/Runtime_106545/Runtime_106545.cs | 35 +++++++++++++++++++ .../Runtime_106545/Runtime_106545.csproj | 8 +++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_106545/Runtime_106545.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_106545/Runtime_106545.csproj diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index 71cafb0d5f488..500d827ab29ca 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -2789,7 +2789,14 @@ bool emitter::emitInsCanOnlyWriteSSE2OrAVXReg(instrDesc* id) // These SSE instructions write to a general purpose integer register. return false; } - + case INS_kmovb_gpr: + case INS_kmovw_gpr: + case INS_kmovd_gpr: + case INS_kmovq_gpr: + { + // These kmov writes to a general purpose integer register + return !isGeneralRegister(id->idReg1()); + } default: { return true; diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106545/Runtime_106545.cs b/src/tests/JIT/Regression/JitBlue/Runtime_106545/Runtime_106545.cs new file mode 100644 index 0000000000000..3212840a85056 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106545/Runtime_106545.cs @@ -0,0 +1,35 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +/* +Found by Fuzzlyn + +Assertion failed '(emitThisGCrefRegs & regMask) == 0' in 'TestClass:Method4(short,System.Runtime.Intrinsics.Vector512`1[long],byref,short,byref,byref,TestClass+S1,byref):byte:this' during 'Emit code' (IL size 47; hash 0x0a275b75; FullOpts) + + File: D:\a\_work\1\s\src\coreclr\jit\emitxarch.cpp Line: 1498 +*/ +using System; +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +using Xunit; + +public class Runtime_106545 +{ + Vector512 v512_byte_97 = Vector512.CreateScalar((byte)1); + + public ulong Method0() + { + v512_byte_97 = Vector512.AllBitsSet; + return (0 - Vector512.ExtractMostSignificantBits(v512_byte_97)); + } + + [Fact] + public static void TestEntryPoint() + { + if (Avx2.IsSupported) + { + new Runtime_106545().Method0(); + } + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106545/Runtime_106545.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_106545/Runtime_106545.csproj new file mode 100644 index 0000000000000..de6d5e08882e8 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106545/Runtime_106545.csproj @@ -0,0 +1,8 @@ + + + True + + + + + From 972562c87ca9c010faea914e4098e240944cef6c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Sep 2024 13:26:46 -0700 Subject: [PATCH 03/34] [release/9.0] JIT ARM64: Don't emit `mov` for zero case in jump tables for shift intrinsics (#107487) * Don't emit mov for zero shift amount * Add test * Revert "Don't emit mov for zero shift amount" This reverts commit cd2656fcca259e9cec56afcf5303f2b7237a9e8a. * Don't emit mov for zero left-shift amount * Update test * Use fallback intrinsic for >> by zero; remove mov special case * Feedback --------- Co-authored-by: Aman Khalid (from Dev Box) Co-authored-by: Jeff Schwartz --- src/coreclr/jit/gentree.cpp | 10 +++++ src/coreclr/jit/hwintrinsiccodegenarm64.cpp | 14 +----- .../JitBlue/Runtime_107173/Runtime_107173.cs | 45 +++++++++++++++++++ .../Runtime_107173/Runtime_107173.csproj | 8 ++++ 4 files changed, 65 insertions(+), 12 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_107173/Runtime_107173.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_107173/Runtime_107173.csproj diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index adb85ddda13a7..0142eb9481b03 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -20818,6 +20818,16 @@ GenTree* Compiler::gtNewSimdBinOpNode( if (op2->IsCnsIntOrI()) { op2->AsIntCon()->gtIconVal &= shiftCountMask; +#ifdef TARGET_ARM64 + // On ARM64, ShiftRight* intrinsics cannot encode a shift value of zero, + // so use the generic Shift* fallback intrinsic. + // GenTreeHWIntrinsic::GetHWIntrinsicIdForBinOp will see that the immediate node is not const, + // and return the correct fallback intrinsic. + if ((op != GT_LSH) && (op2->AsIntCon()->IconValue() == 0)) + { + op2 = gtNewZeroConNode(type); + } +#endif // TARGET_ARM64 } else { diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp index 5bf021ac90b55..32492363d548a 100644 --- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp @@ -443,18 +443,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) for (helper.EmitBegin(); !helper.Done(); helper.EmitCaseEnd()) { const int shiftAmount = helper.ImmValue(); - - if (shiftAmount == 0) - { - // TODO: Use emitIns_Mov instead. - // We do not use it currently because it will still elide the 'mov' - // even if 'canSkip' is false. We cannot elide the 'mov' here. - GetEmitter()->emitIns_R_R_R(INS_mov, emitTypeSize(node), targetReg, reg, reg); - } - else - { - GetEmitter()->emitIns_R_R_I(ins, emitSize, targetReg, reg, shiftAmount, opt); - } + assert((shiftAmount != 0) || (intrin.category == HW_Category_ShiftLeftByImmediate)); + GetEmitter()->emitIns_R_R_I(ins, emitSize, targetReg, reg, shiftAmount, opt); } }; diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_107173/Runtime_107173.cs b/src/tests/JIT/Regression/JitBlue/Runtime_107173/Runtime_107173.cs new file mode 100644 index 0000000000000..147b25e47c49d --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_107173/Runtime_107173.cs @@ -0,0 +1,45 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Generated by Fuzzlyn v2.4 on 2024-08-26 23:38:13 +// Run on Arm64 Linux +// Seed: 8716802894387291290-vectort,vector64,vector128,armadvsimd,armadvsimdarm64,armaes,armarmbase,armarmbasearm64,armcrc32,armcrc32arm64,armdp,armrdm,armrdmarm64,armsha1,armsha256 +// Reduced from 19.5 KiB to 0.5 KiB in 00:00:27 +// Debug: Outputs <0, 0, 0, 0> +// Release: Outputs <0, 0, 4457472, 0> +using System; +using System.Numerics; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; +using Xunit; + +public class C0 +{ + public ushort F2; + public ushort F8; +} + +public class Runtime_107173 +{ + public static C0 s_8 = new C0(); + + [Fact] + public static void TestLeftShift() + { + if (AdvSimd.IsSupported) + { + var vr6 = s_8.F8; + var vr7 = s_8.F2; + var vr8 = Vector64.Create(vr6, vr7, 0, 0); + Vector128 vr9 = AdvSimd.ShiftLeftLogicalWideningLower(vr8, 0); + Assert.Equal(vr9, Vector128.Zero); + } + } + + [Fact] + public static void TestRightShift() + { + var result = Vector128.AllBitsSet >> 8; + Assert.Equal(result, Vector128.AllBitsSet); + } +} \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_107173/Runtime_107173.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_107173/Runtime_107173.csproj new file mode 100644 index 0000000000000..de6d5e08882e8 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_107173/Runtime_107173.csproj @@ -0,0 +1,8 @@ + + + True + + + + + From fd36441cb87d144f267b1d055f0570974ee723a6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Sep 2024 13:27:43 -0700 Subject: [PATCH 04/34] JIT: don't create vector constants from relocatable constants (#107500) We can't represent relocations in data currently. Fixes #107396. Co-authored-by: Andy Ayers Co-authored-by: Jeff Schwartz --- src/coreclr/jit/lower.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index 77776a903d4fa..636ae757c063d 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -8823,12 +8823,22 @@ void Lowering::LowerStoreIndirCoalescing(GenTreeIndir* ind) assert(prevData.IsStore()); assert(currData.IsStore()); - // For now, only constants are supported for data. + // For now, only non-relocatable constants are supported for data. if (!prevData.value->OperIsConst() || !currData.value->OperIsConst()) { return; } + if (prevData.value->IsCnsIntOrI() && prevData.value->AsIntCon()->ImmedValNeedsReloc(comp)) + { + return; + } + + if (currData.value->IsCnsIntOrI() && currData.value->AsIntCon()->ImmedValNeedsReloc(comp)) + { + return; + } + // Otherwise, the difference between two offsets has to match the size of the type. // We don't support overlapping stores. if (abs(prevData.offset - currData.offset) != (int)genTypeSize(prevData.targetType)) From 3de6ae2001e65683ac5ef1b4804db31fede2719b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Sep 2024 13:28:11 -0700 Subject: [PATCH 05/34] [release/9.0] ARM64-SVE: Allow op inside conditionalselect to be non HWintrinsic (#107581) * ARM64-SVE: Allow op inside conditionselect to be non HWintrinsic * Add Sve.IsSupported check to test --------- Co-authored-by: Alan Hayward Co-authored-by: Jeff Schwartz --- src/coreclr/jit/lowerarmarch.cpp | 66 ++++++++++--------- .../JitBlue/Runtime_106869/Runtime_106869.cs | 59 +++++++++++++++++ .../Runtime_106869/Runtime_106869.csproj | 9 +++ 3 files changed, 102 insertions(+), 32 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_106869/Runtime_106869.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_106869/Runtime_106869.csproj diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp index 978c066be998a..56cfa8f6ed1d7 100644 --- a/src/coreclr/jit/lowerarmarch.cpp +++ b/src/coreclr/jit/lowerarmarch.cpp @@ -4050,46 +4050,48 @@ GenTree* Lowering::LowerHWIntrinsicCndSel(GenTreeHWIntrinsic* cndSelNode) GenTree* nestedOp1 = nestedCndSel->Op(1); GenTree* nestedOp2 = nestedCndSel->Op(2); assert(varTypeIsMask(nestedOp1)); - assert(nestedOp2->OperIsHWIntrinsic()); - NamedIntrinsic nestedOp2Id = nestedOp2->AsHWIntrinsic()->GetHWIntrinsicId(); - - // If the nested op uses Pg/Z, then inactive lanes will result in zeros, so can only transform if - // op3 is all zeros. - - if (nestedOp1->IsMaskAllBitsSet() && - (!HWIntrinsicInfo::IsZeroingMaskedOperation(nestedOp2Id) || op3->IsVectorZero())) + if (nestedOp2->OperIsHWIntrinsic()) { - GenTree* nestedOp2 = nestedCndSel->Op(2); - GenTree* nestedOp3 = nestedCndSel->Op(3); + NamedIntrinsic nestedOp2Id = nestedOp2->AsHWIntrinsic()->GetHWIntrinsicId(); - JITDUMP("lowering nested ConditionalSelect HWIntrinisic (before):\n"); - DISPTREERANGE(BlockRange(), cndSelNode); - JITDUMP("\n"); + // If the nested op uses Pg/Z, then inactive lanes will result in zeros, so can only transform if + // op3 is all zeros. - // Transform: - // - // CndSel(mask, CndSel(AllTrue, embeddedMask(trueValOp2), trueValOp3), op3) to - // CndSel(mask, embedded(trueValOp2), op3) - // - cndSelNode->Op(2) = nestedCndSel->Op(2); - if (nestedOp3->IsMaskZero()) - { - BlockRange().Remove(nestedOp3); - } - else + if (nestedOp1->IsMaskAllBitsSet() && + (!HWIntrinsicInfo::IsZeroingMaskedOperation(nestedOp2Id) || op3->IsVectorZero())) { - nestedOp3->SetUnusedValue(); - } + GenTree* nestedOp2 = nestedCndSel->Op(2); + GenTree* nestedOp3 = nestedCndSel->Op(3); + + JITDUMP("lowering nested ConditionalSelect HWIntrinisic (before):\n"); + DISPTREERANGE(BlockRange(), cndSelNode); + JITDUMP("\n"); + + // Transform: + // + // CndSel(mask, CndSel(AllTrue, embeddedMask(trueValOp2), trueValOp3), op3) to + // CndSel(mask, embedded(trueValOp2), op3) + // + cndSelNode->Op(2) = nestedCndSel->Op(2); + if (nestedOp3->IsMaskZero()) + { + BlockRange().Remove(nestedOp3); + } + else + { + nestedOp3->SetUnusedValue(); + } - BlockRange().Remove(nestedOp1); - BlockRange().Remove(nestedCndSel); + BlockRange().Remove(nestedOp1); + BlockRange().Remove(nestedCndSel); - JITDUMP("lowering nested ConditionalSelect HWIntrinisic (after):\n"); - DISPTREERANGE(BlockRange(), cndSelNode); - JITDUMP("\n"); + JITDUMP("lowering nested ConditionalSelect HWIntrinisic (after):\n"); + DISPTREERANGE(BlockRange(), cndSelNode); + JITDUMP("\n"); - return cndSelNode; + return cndSelNode; + } } } else if (op1->IsMaskAllBitsSet()) diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106869/Runtime_106869.cs b/src/tests/JIT/Regression/JitBlue/Runtime_106869/Runtime_106869.cs new file mode 100644 index 0000000000000..b4b9856c79595 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106869/Runtime_106869.cs @@ -0,0 +1,59 @@ +// 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; + +// Generated by Fuzzlyn v2.3 on 2024-08-23 10:25:51 +// Run on Arm64 Windows +// Seed: 13938901376337307772-vectort,vector64,vector128,armsve +// Reduced from 210.5 KiB to 1.1 KiB in 00:02:19 +// Hits JIT assert in Release: +// Assertion failed 'nestedOp2->OperIsHWIntrinsic()' in 'Program:Main(Fuzzlyn.ExecutionServer.IRuntime)' during 'Lowering nodeinfo' (IL size 119; hash 0xade6b36b; FullOpts) +// +// File: C:\dev\dotnet\runtime2\src\coreclr\jit\lowerarmarch.cpp Line: 4062 +// +using System; +using System.Numerics; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; + +public struct S0 +{ + public ulong F5; +} + +public class C0 +{ + public int F1; +} + +public class Runtime_1068867 +{ + public static S0 s_7; + public static byte s_14; + + [Fact] + public static void TestEntryPoint() + { + if (Sve.IsSupported) + { + var vr12 = new C0(); + var vr14 = vr12.F1; + var vr15 = Vector128.CreateScalar(vr14).AsVector(); + var vr16 = Vector128.CreateScalar(0).AsVector(); + var vr17 = Vector128.CreateScalar(0).AsVector(); + var vr18 = Vector128.CreateScalar(0).AsVector(); + var vr19 = Vector128.CreateScalar(1).AsVector(); + var vr20 = Sve.ConditionalSelect(vr17, vr18, vr19); + var vr21 = Vector128.CreateScalar(0).AsVector(); + var vr22 = Sve.ConditionalSelect(vr16, vr20, vr21); + Consume(vr22); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static void Consume(T val) + { + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106869/Runtime_106869.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_106869/Runtime_106869.csproj new file mode 100644 index 0000000000000..1352ebe3277bc --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106869/Runtime_106869.csproj @@ -0,0 +1,9 @@ + + + True + $(NoWarn),SYSLIB5003 + + + + + From 35e3c876977a4195a97c2eb1d6569b067ba1934c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Sep 2024 13:28:44 -0700 Subject: [PATCH 06/34] [release/9.0] Arm: Fix the base register used for restoring register from stack (#107584) * Use correct baseReg for vstr, similar to vldr * add test cases * Mark internal test methods private --------- Co-authored-by: Kunal Pathak Co-authored-by: Jeff Schwartz --- src/coreclr/jit/emitarm.cpp | 5 +- .../JitBlue/Runtime_105620/Runtime_105620.cs | 199 ++++++++++++++++++ .../Runtime_105620/Runtime_105620.csproj | 8 + 3 files changed, 208 insertions(+), 4 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_105620/Runtime_105620.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_105620/Runtime_105620.csproj diff --git a/src/coreclr/jit/emitarm.cpp b/src/coreclr/jit/emitarm.cpp index fd0a27f61818e..902399f58e4fe 100644 --- a/src/coreclr/jit/emitarm.cpp +++ b/src/coreclr/jit/emitarm.cpp @@ -3914,10 +3914,7 @@ void emitter::emitIns_S_R(instruction ins, emitAttr attr, regNumber reg1, int va { regNumber rsvdReg = codeGen->rsGetRsvdReg(); emitIns_genStackOffset(rsvdReg, varx, offs, /* isFloatUsage */ true, &baseRegUsed); - - // Ensure the baseReg calculated is correct. - assert(baseRegUsed == reg2); - emitIns_R_R(INS_add, EA_4BYTE, rsvdReg, reg2); + emitIns_R_R(INS_add, EA_4BYTE, rsvdReg, baseRegUsed); emitIns_R_R_I(ins, attr, reg1, rsvdReg, 0); return; } diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_105620/Runtime_105620.cs b/src/tests/JIT/Regression/JitBlue/Runtime_105620/Runtime_105620.cs new file mode 100644 index 0000000000000..486afcffb12c0 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_105620/Runtime_105620.cs @@ -0,0 +1,199 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Generated by Fuzzlyn v2.1 on 2024-07-28 20:48:11 +// Run on Arm Linux +// Seed: 7638843082097772896 +// Reduced from 1010.6 KiB to 5.3 KiB in 00:18:13 +// Hits JIT assert in Release: +// Assertion failed 'baseRegUsed == reg2' in 'Program:M48(S0,S3,S2,S2)' during 'Generate code' (IL size 2164; hash 0x03983244; FullOpts) +// +// File: /__w/1/s/src/coreclr/jit/emitarm.cpp Line: 3919 +// +using System; +using System.Runtime.CompilerServices; +using Xunit; + +public struct S0 +{ + public ulong F0; + public int F1; + public long F2; + public uint F3; + public byte F4; + public float F5; + public sbyte F6; + public double F7; + public sbyte F8; +} + +public struct S1 +{ + public double F0; + public short F1; + public bool F2; + public S0 F3; + public sbyte F4; + public ushort F5; + public ulong F6; + public int F7; + public S0 F8; +} + +public struct S2 +{ + public double F0; + public S0 F1; + public S1 F2; + public ushort F4; + public S2(S1 f2) + { + F2 = f2; + } +} + +public class C0 +{ +} + +public struct S3 +{ + public double F0; + public float F1; + public ushort F2; + public long F3; + public S1 F4; + public S2 F5; + public S2 F6; + public uint F7; + public S2 F8; + public S3(S2 f5, S2 f8) : this() + { + F5 = f5; + F8 = f8; + } +} + +public struct S4 +{ + public double F0; + public double F1; + public float F2; + public ulong F3; + public bool F4; + public int F5; + public bool F6; + public S3 F7; + public float F8; + public S4(S3 f7) + { + F7 = f7; + } +} + +public class Program +{ + public static IRuntime s_rt; + public static S4 s_2; + public static S4 s_3; + public static S4[][] s_6; + public static S3[] s_23 = new S3[] + { + new S3(new S2(new S1()), new S2(new S1())) + }; + + [Fact] + public static void TestEntryPoint() + { + try + { + var vr8 = new S4(new S3(new S2(new S1()), new S2(new S1()))); + var vr9 = s_23[0].F6.F1; + var vr13 = s_2.F7; + var vr14 = vr8.F7.F6; + var vr15 = vr8.F7.F6; + M48(vr9, vr13, vr14, vr15); + } catch {} + } + + private static void M48(S0 argThis, S3 arg0, S2 arg1, S2 arg2) + { + arg2.F2.F0 = arg2.F2.F0; + S4 var1 = new S4(new S3(new S2(new S1()), new S2(new S1()))); + var1.F7.F5.F2.F8.F5 = s_6[0][0].F7.F8.F2.F3.F5; + var vr2 = new C0(); + M49(0, vr2, ref arg2.F2.F1, ref s_3.F7, ref arg1.F1.F8); + S4 var2 = var1; + s_rt.WriteLine(System.BitConverter.DoubleToUInt64Bits(var2.F7.F0)); + s_rt.WriteLine(System.BitConverter.SingleToUInt32Bits(var2.F7.F1)); + s_rt.WriteLine(var2.F7.F2); + s_rt.WriteLine(var2.F7.F3); + s_rt.WriteLine(System.BitConverter.DoubleToUInt64Bits(var2.F7.F4.F0)); + s_rt.WriteLine(var2.F7.F4.F1); + s_rt.WriteLine(var2.F7.F4.F2); + s_rt.WriteLine(var2.F7.F4.F3.F0); + s_rt.WriteLine(var2.F7.F4.F3.F1); + s_rt.WriteLine(var2.F7.F4.F3.F2); + s_rt.WriteLine(var2.F7.F4.F3.F3); + s_rt.WriteLine(var2.F7.F4.F3.F4); + s_rt.WriteLine(System.BitConverter.SingleToUInt32Bits(var2.F7.F4.F3.F5)); + s_rt.WriteLine(var2.F7.F4.F3.F6); + s_rt.WriteLine(System.BitConverter.DoubleToUInt64Bits(var2.F7.F4.F3.F7)); + s_rt.WriteLine(var2.F7.F4.F3.F8); + s_rt.WriteLine(var2.F7.F4.F4); + s_rt.WriteLine(var2.F7.F4.F5); + s_rt.WriteLine(var2.F7.F4.F6); + s_rt.WriteLine(var2.F7.F4.F7); + s_rt.WriteLine(var2.F7.F4.F8.F0); + s_rt.WriteLine(var2.F7.F4.F8.F1); + s_rt.WriteLine(var2.F7.F4.F8.F2); + s_rt.WriteLine(var2.F7.F4.F8.F3); + s_rt.WriteLine(var2.F7.F4.F8.F4); + s_rt.WriteLine(System.BitConverter.SingleToUInt32Bits(var2.F7.F4.F8.F5)); + s_rt.WriteLine(var2.F7.F4.F8.F6); + s_rt.WriteLine(System.BitConverter.DoubleToUInt64Bits(var2.F7.F4.F8.F7)); + s_rt.WriteLine(var2.F7.F4.F8.F8); + s_rt.WriteLine(System.BitConverter.DoubleToUInt64Bits(var2.F7.F5.F0)); + s_rt.WriteLine(var2.F7.F5.F1.F0); + s_rt.WriteLine(var2.F7.F5.F1.F1); + s_rt.WriteLine(var2.F7.F5.F1.F2); + s_rt.WriteLine(var2.F7.F5.F1.F3); + s_rt.WriteLine(var2.F7.F5.F1.F4); + s_rt.WriteLine(System.BitConverter.SingleToUInt32Bits(var2.F7.F5.F1.F5)); + s_rt.WriteLine(var2.F7.F5.F1.F6); + s_rt.WriteLine(System.BitConverter.DoubleToUInt64Bits(var2.F7.F5.F1.F7)); + s_rt.WriteLine(var2.F7.F5.F1.F8); + s_rt.WriteLine(System.BitConverter.DoubleToUInt64Bits(var2.F7.F5.F2.F0)); + s_rt.WriteLine(var2.F7.F5.F2.F1); + s_rt.WriteLine(var2.F7.F5.F2.F2); + s_rt.WriteLine(var2.F7.F5.F2.F3.F0); + s_rt.WriteLine(var2.F7.F5.F2.F3.F1); + s_rt.WriteLine(var2.F7.F5.F2.F3.F2); + s_rt.WriteLine(var2.F7.F5.F2.F3.F3); + s_rt.WriteLine(var2.F7.F5.F2.F3.F4); + s_rt.WriteLine(System.BitConverter.SingleToUInt32Bits(var2.F7.F5.F2.F3.F5)); + s_rt.WriteLine(var2.F7.F5.F2.F3.F6); + s_rt.WriteLine(System.BitConverter.DoubleToUInt64Bits(var2.F7.F5.F2.F3.F7)); + s_rt.WriteLine(var2.F7.F5.F2.F3.F8); + s_rt.WriteLine(var2.F7.F5.F2.F4); + s_rt.WriteLine(var2.F7.F5.F2.F5); + s_rt.WriteLine(var2.F7.F5.F2.F6); + s_rt.WriteLine(var2.F7.F5.F2.F7); + s_rt.WriteLine(var2.F7.F5.F2.F8.F0); + } + + private static void M49(short arg0, C0 arg2, ref short arg3, ref S3 arg4, ref sbyte arg5) + { + s_rt.WriteLine(arg0); + } +} + +public interface IRuntime +{ + void WriteLine(T value); +} + +public class Runtime : IRuntime +{ + public void WriteLine(T value) => System.Console.WriteLine(value); +} \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_105620/Runtime_105620.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_105620/Runtime_105620.csproj new file mode 100644 index 0000000000000..de6d5e08882e8 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_105620/Runtime_105620.csproj @@ -0,0 +1,8 @@ + + + True + + + + + From 3b4a3e878df66d2fd2765639ea23b9d5ded6c776 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Sep 2024 13:29:16 -0700 Subject: [PATCH 07/34] Fix SSP issue with HW exceptions from JIT helpers (#107676) The recent change that was fixing bad SSP updating during exception handling with funceval has also modified the way SSP is extracted for hardware exceptions. That works fine for many cases, but there is a problem when the exception occurs in a JIT helper. The `AjustContextForJITHelpers` uses only the basic `CONTEXT` structure for unwinding to the managed caller and so the SSP is not properly updated. That makes it off by one slot when we set it when continuing execution after catch. This change removes storing SSP for hardware exceptions in the FaultingExceptionFrame to mitigate the issue. It effectively returns to the way software exceptions use - scanning shadow stack for the instruction pointer of the frame to which it is going to resume after catch. Co-authored-by: Jan Vorlicek Co-authored-by: Jeff Schwartz --- src/coreclr/vm/amd64/RedirectedHandledJITCase.asm | 6 ++++-- src/coreclr/vm/excep.cpp | 9 +++++---- src/coreclr/vm/threads.h | 3 +++ src/coreclr/vm/threadsuspend.cpp | 7 +++++++ 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/coreclr/vm/amd64/RedirectedHandledJITCase.asm b/src/coreclr/vm/amd64/RedirectedHandledJITCase.asm index c0d586bd9d2cc..47b1ecfd50fb3 100644 --- a/src/coreclr/vm/amd64/RedirectedHandledJITCase.asm +++ b/src/coreclr/vm/amd64/RedirectedHandledJITCase.asm @@ -144,7 +144,7 @@ STUB&_RspAligned: mov dword ptr [rcx], 0 ; Initialize vtbl (it is not strictly necessary) mov dword ptr [rcx + OFFSETOF__FaultingExceptionFrame__m_fFilterExecuted], 0 ; Initialize BOOL for personality routine - mov qword ptr [rcx + OFFSETOF__FaultingExceptionFrame__m_SSP], rax + mov r8, rax call TARGET @@ -185,6 +185,7 @@ NESTED_ENTRY RedirectForThrowControl2, _TEXT save_reg_postrsp rcx, REDIRECT_FOR_THROW_CONTROL_FRAME_SIZE + 8h ; FaultingExceptionFrame save_reg_postrsp rdx, REDIRECT_FOR_THROW_CONTROL_FRAME_SIZE + 10h ; Original RSP + save_reg_postrsp r8, REDIRECT_FOR_THROW_CONTROL_FRAME_SIZE + 18h ; SSP END_PROLOGUE @@ -197,7 +198,8 @@ NESTED_ENTRY RedirectForThrowControl2, _TEXT mov rdx, [rsp + REDIRECT_FOR_THROW_CONTROL_FRAME_SIZE + 10h] ; Original RSP mov [rdx - 8], rax - mov rcx, [rsp + REDIRECT_FOR_THROW_CONTROL_FRAME_SIZE + 8h] ; FaultingExceptionFrame + mov rcx, [rsp + REDIRECT_FOR_THROW_CONTROL_FRAME_SIZE + 8h] ; FaultingExceptionFrame + mov rdx, [rsp + REDIRECT_FOR_THROW_CONTROL_FRAME_SIZE + 18h] ; SSP call ThrowControlForThread ; ThrowControlForThread doesn't return. diff --git a/src/coreclr/vm/excep.cpp b/src/coreclr/vm/excep.cpp index 64a9d7c23cbca..8418202b93389 100644 --- a/src/coreclr/vm/excep.cpp +++ b/src/coreclr/vm/excep.cpp @@ -6279,10 +6279,6 @@ void HandleManagedFaultNew(EXCEPTION_RECORD* pExceptionRecord, CONTEXT* pContext #endif // FEATURE_EH_FUNCLETS frame->InitAndLink(pContext); -#if defined(TARGET_AMD64) && defined(TARGET_WINDOWS) - frame->SetSSP(GetSSP(pContext)); -#endif - Thread *pThread = GetThread(); ExInfo exInfo(pThread, pExceptionRecord, pContext, ExKind::HardwareFault); @@ -6364,6 +6360,11 @@ void FaultingExceptionFrame::Init(CONTEXT *pContext) m_ReturnAddress = ::GetIP(pContext); CopyOSContext(&m_ctx, pContext); #endif // !FEATURE_EH_FUNCLETS + +#if defined(TARGET_AMD64) && defined(TARGET_WINDOWS) + m_SSP = 0; +#endif + } // diff --git a/src/coreclr/vm/threads.h b/src/coreclr/vm/threads.h index 4a4bd2ff867fa..8d3e74ee6fedb 100644 --- a/src/coreclr/vm/threads.h +++ b/src/coreclr/vm/threads.h @@ -378,6 +378,9 @@ EXTERN_C void ThrowControlForThread( #ifdef FEATURE_EH_FUNCLETS FaultingExceptionFrame *pfef #endif // FEATURE_EH_FUNCLETS +#if defined(TARGET_AMD64) && defined(TARGET_WINDOWS) + , TADDR ssp +#endif // TARGET_AMD64 && TARGET_WINDOWS ); #if defined(_DEBUG) diff --git a/src/coreclr/vm/threadsuspend.cpp b/src/coreclr/vm/threadsuspend.cpp index f8ecdcba72417..1506516f12447 100644 --- a/src/coreclr/vm/threadsuspend.cpp +++ b/src/coreclr/vm/threadsuspend.cpp @@ -3735,6 +3735,9 @@ ThrowControlForThread( #ifdef FEATURE_EH_FUNCLETS FaultingExceptionFrame *pfef #endif // FEATURE_EH_FUNCLETS +#if defined(TARGET_AMD64) && defined(TARGET_WINDOWS) + , TADDR ssp +#endif // TARGET_AMD64 && TARGET_WINDOWS ) { STATIC_CONTRACT_THROWS; @@ -3784,6 +3787,10 @@ ThrowControlForThread( #endif // FEATURE_EH_FUNCLETS pfef->InitAndLink(pThread->m_OSContext); +#if defined(TARGET_AMD64) && defined(TARGET_WINDOWS) + pfef->SetSSP(ssp); +#endif + // !!! Can not assert here. Sometimes our EHInfo for catch clause extends beyond // !!! Jit_EndCatch. Not sure if we have guarantee on catch clause. //_ASSERTE (pThread->ReadyForAbort()); From 8dc3e061063b473af6a7a84c00e714f0681fa1b6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Sep 2024 13:32:35 -0700 Subject: [PATCH 08/34] Fix IL reference tokens to another generated assembly members (#107691) Co-authored-by: Buyaa Namnan --- .../Reflection/Emit/ModuleBuilderImpl.cs | 33 +++-- .../System/Reflection/Emit/TypeBuilderImpl.cs | 2 +- .../AssemblySaveILGeneratorTests.cs | 138 +++++++++++++++++- 3 files changed, 155 insertions(+), 18 deletions(-) diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs index 513df134b75a5..5d242a710ae2b 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/ModuleBuilderImpl.cs @@ -809,7 +809,7 @@ internal static SignatureCallingConvention GetSignatureConvention(CallingConvent return convention; } - private static MemberInfo GetOriginalMemberIfConstructedType(MethodBase methodBase) + private MemberInfo GetOriginalMemberIfConstructedType(MethodBase methodBase) { Type declaringType = methodBase.DeclaringType!; if (declaringType.IsConstructedGenericType && @@ -1068,7 +1068,7 @@ internal TypeBuilder DefineNestedType(string name, TypeAttributes attr, [Dynamic internal EntityHandle TryGetFieldHandle(FieldInfo field) { - if (field is FieldBuilderImpl fb) + if (field is FieldBuilderImpl fb && Equals(fb.Module)) { return fb._handle; } @@ -1096,27 +1096,28 @@ private EntityHandle GetHandleForMember(MemberInfo member) return GetMemberReferenceHandle(member); } - private static bool IsConstructedFromTypeBuilder(Type type) + private bool IsConstructedFromTypeBuilder(Type type) { if (type.IsConstructedGenericType) { - return type.GetGenericTypeDefinition() is TypeBuilderImpl || ContainsTypeBuilder(type.GetGenericArguments()); + return (type.GetGenericTypeDefinition() is TypeBuilderImpl tb && Equals(tb.Module)) || + ContainsTypeBuilder(type.GetGenericArguments()); } - Type? elementType = type.GetElementType(); - if (elementType is not null) + if (type.HasElementType) { - return (elementType is TypeBuilderImpl) || IsConstructedFromTypeBuilder(elementType); + Type elementType = type.GetElementType()!; + return (elementType is TypeBuilderImpl tbi && Equals(tbi.Module)) || IsConstructedFromTypeBuilder(elementType); } return false; } - internal static bool ContainsTypeBuilder(Type[] genericArguments) + internal bool ContainsTypeBuilder(Type[] genericArguments) { foreach (Type type in genericArguments) { - if (type is TypeBuilderImpl || type is GenericTypeParameterBuilderImpl) + if ((type is TypeBuilderImpl tb && Equals(tb.Module)) || (type is GenericTypeParameterBuilderImpl gtb && Equals(gtb.Module))) { return true; } @@ -1154,7 +1155,7 @@ internal EntityHandle TryGetTypeHandle(Type type) internal EntityHandle TryGetConstructorHandle(ConstructorInfo constructor) { - if (constructor is ConstructorBuilderImpl cb) + if (constructor is ConstructorBuilderImpl cb && Equals(cb.Module)) { return cb._methodBuilder._handle; } @@ -1166,7 +1167,7 @@ internal EntityHandle TryGetConstructorHandle(ConstructorInfo constructor) internal EntityHandle TryGetMethodHandle(MethodInfo method) { - if (method is MethodBuilderImpl mb) + if (method is MethodBuilderImpl mb && Equals(mb.Module)) { return mb._handle; } @@ -1180,11 +1181,11 @@ internal EntityHandle TryGetMethodHandle(MethodInfo method) return GetHandleForMember(method); } - private static bool IsArrayMethodTypeIsTypeBuilder(MethodInfo method) => method is ArrayMethod arrayMethod && - arrayMethod.DeclaringType!.GetElementType() is TypeBuilderImpl; + private bool IsArrayMethodTypeIsTypeBuilder(MethodInfo method) => method is ArrayMethod arrayMethod && + arrayMethod.DeclaringType!.GetElementType() is TypeBuilderImpl tb && Equals(tb.Module); - private static bool IsConstructedFromMethodBuilderOrTypeBuilder(MethodInfo method) => method.IsConstructedGenericMethod && - (method.GetGenericMethodDefinition() is MethodBuilderImpl || ContainsTypeBuilder(method.GetGenericArguments())); + private bool IsConstructedFromMethodBuilderOrTypeBuilder(MethodInfo method) => method.IsConstructedGenericMethod && + ((method.GetGenericMethodDefinition() is MethodBuilderImpl mb && Equals(mb.Module)) || ContainsTypeBuilder(method.GetGenericArguments())); internal EntityHandle TryGetMethodHandle(MethodInfo method, Type[] optionalParameterTypes) { @@ -1194,7 +1195,7 @@ internal EntityHandle TryGetMethodHandle(MethodInfo method, Type[] optionalParam throw new InvalidOperationException(SR.InvalidOperation_NotAVarArgCallingConvention); } - if (method is MethodBuilderImpl mb) + if (method is MethodBuilderImpl mb && Equals(mb.Module)) { return mb._handle; } diff --git a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs index 4a48349359e71..469b229b20dc7 100644 --- a/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs +++ b/src/libraries/System.Reflection.Emit/src/System/Reflection/Emit/TypeBuilderImpl.cs @@ -212,7 +212,7 @@ private ConstructorBuilderImpl DefineDefaultConstructorInternal(MethodAttributes // Get the parent class's default constructor and add it to the IL ConstructorInfo? con; if (_typeParent!.IsConstructedGenericType && - (_typeParent.GetGenericTypeDefinition() is TypeBuilderImpl || ModuleBuilderImpl.ContainsTypeBuilder(_typeParent.GetGenericArguments()))) + (_typeParent.GetGenericTypeDefinition() is TypeBuilderImpl || _module.ContainsTypeBuilder(_typeParent.GetGenericArguments()))) { // When TypeBuilder involved need to construct the parent constructor using TypeBuilder.GetConstructor() static method con = GetConstructor(_typeParent, _typeParent.GetGenericTypeDefinition().GetConstructor( diff --git a/src/libraries/System.Reflection.Emit/tests/PersistedAssemblyBuilder/AssemblySaveILGeneratorTests.cs b/src/libraries/System.Reflection.Emit/tests/PersistedAssemblyBuilder/AssemblySaveILGeneratorTests.cs index 7496a9c24193d..2b155556c5f2a 100644 --- a/src/libraries/System.Reflection.Emit/tests/PersistedAssemblyBuilder/AssemblySaveILGeneratorTests.cs +++ b/src/libraries/System.Reflection.Emit/tests/PersistedAssemblyBuilder/AssemblySaveILGeneratorTests.cs @@ -643,7 +643,7 @@ void Main(int a) ILGenerator il = methodMultiply.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, field); - il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Mul); il.Emit(OpCodes.Ret); @@ -2908,5 +2908,141 @@ public void ExplicitFieldOffsetSavesAndLoads() var assembly = AssemblyLoadContext.Default.LoadFromStream(stream); var method = assembly.GetType("ExplicitLayoutType")!; } + + [Fact] + public void ReferenceMemberInOtherGeneratedAssembly() + { + using (TempFile file = TempFile.Create()) + using (TempFile file2 = TempFile.Create()) + { + PersistedAssemblyBuilder ab1 = new PersistedAssemblyBuilder(new AssemblyName("MyAssembly1"), typeof(object).Assembly); + ModuleBuilder mb1 = ab1.DefineDynamicModule("Module1"); + TypeBuilder type1 = mb1.DefineType("Type1", TypeAttributes.Public); + MethodBuilder method = type1.DefineMethod("TestMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(int), Type.EmptyTypes); + + ILGenerator ilGenerator = method.GetILGenerator(); + int expectedReturn = 5; + ilGenerator.Emit(OpCodes.Ldc_I4, expectedReturn); + ilGenerator.Emit(OpCodes.Ret); + type1.CreateType(); + ab1.Save(file.Path); + + PersistedAssemblyBuilder ab2 = new PersistedAssemblyBuilder(new AssemblyName("MyAssembly2"), typeof(object).Assembly); + ModuleBuilder mb2 = ab2.DefineDynamicModule("Module2"); + TypeBuilder type2 = mb2.DefineType("Type2", TypeAttributes.Public); + MethodBuilder method2 = type2.DefineMethod("TestMethod2", MethodAttributes.Public | MethodAttributes.Static, typeof(int), Type.EmptyTypes); + + ILGenerator ilGenerator2 = method2.GetILGenerator(); + ilGenerator2.Emit(OpCodes.Call, method); + ilGenerator2.Emit(OpCodes.Ret); + type2.CreateType(); + ab2.Save(file2.Path); + + TestAssemblyLoadContext tlc = new TestAssemblyLoadContext(); + tlc.LoadFromAssemblyPath(file.Path); + Type typeFromDisk = tlc.LoadFromAssemblyPath(file2.Path).GetType("Type2"); + MethodInfo methodFromDisk = typeFromDisk.GetMethod("TestMethod2")!; + Assert.Equal(expectedReturn, methodFromDisk.Invoke(null, null)); + tlc.Unload(); + } + } + + [Fact] + public void CrossReferenceGeneratedAssemblyMembers() + { + using (TempFile file = TempFile.Create()) + using (TempFile file2 = TempFile.Create()) + { + PersistedAssemblyBuilder ab1 = new PersistedAssemblyBuilder(new AssemblyName("MyAssembly1"), typeof(object).Assembly); + ModuleBuilder mb1 = ab1.DefineDynamicModule("Module1"); + TypeBuilder type1 = mb1.DefineType("Type1", TypeAttributes.Public); + MethodBuilder method = type1.DefineMethod("TestMethod", MethodAttributes.Public | MethodAttributes.Static, typeof(int), Type.EmptyTypes); + int expectedReturn = 5; + + PersistedAssemblyBuilder ab2 = new PersistedAssemblyBuilder(new AssemblyName("MyAssembly2"), typeof(object).Assembly); + ModuleBuilder mb2 = ab2.DefineDynamicModule("Module2"); + TypeBuilder type2 = mb2.DefineType("Type2", TypeAttributes.Public); + MethodBuilder method2 = type2.DefineMethod("TestMethod2", MethodAttributes.Public | MethodAttributes.Static, typeof(int), Type.EmptyTypes); + FieldBuilder field = type2.DefineField("Field2", typeof(int), FieldAttributes.Public | FieldAttributes.Static); + ILGenerator staticCtorIL = type2.DefineTypeInitializer().GetILGenerator(); + staticCtorIL.Emit(OpCodes.Ldc_I4, expectedReturn); + staticCtorIL.Emit(OpCodes.Stsfld, field); + staticCtorIL.Emit(OpCodes.Ret); + ILGenerator ilGenerator2 = method2.GetILGenerator(); + ilGenerator2.Emit(OpCodes.Call, method); + ilGenerator2.Emit(OpCodes.Ret); + type2.CreateType(); + + ILGenerator ilGenerator = method.GetILGenerator(); + ilGenerator.Emit(OpCodes.Ldsfld, field); + ilGenerator.Emit(OpCodes.Ret); + type1.CreateType(); + + ab1.Save(file.Path); + ab2.Save(file2.Path); + + TestAssemblyLoadContext tlc = new TestAssemblyLoadContext(); + tlc.LoadFromAssemblyPath(file.Path); + Type typeFromDisk = tlc.LoadFromAssemblyPath(file2.Path).GetType("Type2"); + MethodInfo methodFromDisk = typeFromDisk.GetMethod("TestMethod2")!; + Assert.Equal(expectedReturn, methodFromDisk.Invoke(null, null)); + tlc.Unload(); + } + } + + [Fact] + public void ReferenceGenericMembersInOtherGeneratedAssembly() + { + using (TempFile file = TempFile.Create()) + using (TempFile file2 = TempFile.Create()) + { + PersistedAssemblyBuilder ab = AssemblySaveTools.PopulateAssemblyBuilderAndTypeBuilder(out TypeBuilder type); + GenericTypeParameterBuilder[] typeParams = type.DefineGenericParameters(["T"]); + ConstructorBuilder ctor = type.DefineDefaultConstructor(MethodAttributes.PrivateScope | MethodAttributes.Public | + MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName); + FieldBuilder myField = type.DefineField("Field", typeParams[0], FieldAttributes.Public); + MethodBuilder genericMethod = type.DefineMethod("GM", MethodAttributes.Public | MethodAttributes.Static); + GenericTypeParameterBuilder[] methodParams = genericMethod.DefineGenericParameters("U"); + genericMethod.SetSignature(methodParams[0], null, null, new[] { methodParams[0] }, null, null); + + ILGenerator ilg = genericMethod.GetILGenerator(); + Type SampleOfU = type.MakeGenericType(methodParams[0]); + ConstructorInfo ctorOfU = TypeBuilder.GetConstructor(SampleOfU, ctor); + ilg.Emit(OpCodes.Newobj, ctorOfU); + ilg.Emit(OpCodes.Dup); + ilg.Emit(OpCodes.Ldarg_0); + FieldInfo FieldOfU = TypeBuilder.GetField(SampleOfU, myField); + ilg.Emit(OpCodes.Stfld, FieldOfU); + ilg.Emit(OpCodes.Dup); + ilg.Emit(OpCodes.Ldfld, FieldOfU); + ilg.Emit(OpCodes.Box, methodParams[0]); + MethodInfo writeLineObj = typeof(Console).GetMethod("WriteLine", [typeof(object)]); + ilg.EmitCall(OpCodes.Call, writeLineObj, null); + ilg.Emit(OpCodes.Ldfld, FieldOfU); + ilg.Emit(OpCodes.Ret); + type.CreateType(); + ab.Save(file.Path); + + PersistedAssemblyBuilder ab2 = new PersistedAssemblyBuilder(new AssemblyName("MyAssembly2"), typeof(object).Assembly); + TypeBuilder type2 = ab2.DefineDynamicModule("MyModule2").DefineType("Type2", TypeAttributes.Class | TypeAttributes.Public); + MethodBuilder method2 = type2.DefineMethod("Method2", MethodAttributes.Public | MethodAttributes.Static, typeof(string), Type.EmptyTypes); + ilg = method2.GetILGenerator(); + Type SampleOfInt = type.MakeGenericType(typeof(string)); + MethodInfo SampleOfIntGM = TypeBuilder.GetMethod(SampleOfInt, genericMethod); + MethodInfo GMOfString = SampleOfIntGM.MakeGenericMethod(typeof(string)); + ilg.Emit(OpCodes.Ldstr, "Hello, world!"); + ilg.EmitCall(OpCodes.Call, GMOfString, null); + ilg.Emit(OpCodes.Ret); + type2.CreateType(); + ab2.Save(file2.Path); + + TestAssemblyLoadContext tlc = new TestAssemblyLoadContext(); + tlc.LoadFromAssemblyPath(file.Path); + Type typeFromDisk = tlc.LoadFromAssemblyPath(file2.Path).GetType("Type2"); + MethodInfo methodFromDisk = typeFromDisk.GetMethod("Method2")!; + Assert.Equal("Hello, world!", methodFromDisk.Invoke(null, null)); + tlc.Unload(); + } + } } } From 9abc5de8ae1adb8eacec95f44bfaa8c61c8be489 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Sep 2024 16:15:00 -0700 Subject: [PATCH 09/34] add _requiresAlign8 to company and mangled name (#107701) Co-authored-by: yowl --- .../DependencyAnalysis/GCStaticEETypeNode.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GCStaticEETypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GCStaticEETypeNode.cs index 9e2c0d74220f6..b4130083ec8ec 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GCStaticEETypeNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GCStaticEETypeNode.cs @@ -44,6 +44,10 @@ protected override ObjectNodeSection GetDehydratedSection(NodeFactory factory) public void AppendMangledName(NameMangler nameMangler, Utf8StringBuilder sb) { sb.Append("__GCStaticEEType_"u8).Append(_gcMap.ToString()); + if (_requiresAlign8) + { + sb.Append("_align8"u8); + } } int ISymbolDefinitionNode.Offset @@ -107,7 +111,14 @@ protected override ObjectData GetDehydratableData(NodeFactory factory, bool relo public override int CompareToImpl(ISortableNode other, CompilerComparer comparer) { - return _gcMap.CompareTo(((GCStaticEETypeNode)other)._gcMap); + GCStaticEETypeNode otherGCStaticEETypeNode = (GCStaticEETypeNode)other; + int mapCompare = _gcMap.CompareTo(otherGCStaticEETypeNode._gcMap); + if (mapCompare == 0) + { + return _requiresAlign8.CompareTo(otherGCStaticEETypeNode._requiresAlign8); + } + + return mapCompare; } } } From 3104ebb55c39d3432b3adfcbce325d573471f161 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Sep 2024 16:19:01 -0700 Subject: [PATCH 10/34] Disable subset of the stack overflow tests on ARM (#107721) There is a problem with the variant of the stack overflow test that can overflow in a native function on ARM. The EHABI unwind info is not present for leaf functions and libunwind is unable to unwind from the failure location to the first managed frame. I've created an issue (#107184) for the underlying problem. This PR disables that test variant until the problem is fixed. Close #106742 Co-authored-by: Jan Vorlicek --- .../exceptions/stackoverflow/stackoverflowtester.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/tests/baseservices/exceptions/stackoverflow/stackoverflowtester.cs b/src/tests/baseservices/exceptions/stackoverflow/stackoverflowtester.cs index 99fcc753400d5..0264b65a39438 100644 --- a/src/tests/baseservices/exceptions/stackoverflow/stackoverflowtester.cs +++ b/src/tests/baseservices/exceptions/stackoverflow/stackoverflowtester.cs @@ -216,6 +216,12 @@ public static void TestStackOverflowLargeFrameSecondaryThread() [Fact] public static void TestStackOverflow3() { + if (RuntimeInformation.ProcessArchitecture == Architecture.Arm) + { + // Disabled on ARM due to https://github.com/dotnet/runtime/issues/107184 + return; + } + TestStackOverflow("stackoverflow3", "", out List lines); if (!lines[lines.Count - 1].EndsWith("at TestStackOverflow3.Program.Main()")) From 9bf644074a38cfb6c9e1750c46c00130924df1a6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Sep 2024 16:24:06 -0700 Subject: [PATCH 11/34] [release/9.0] Fix config source gen binding value types to null configuration values (#107670) * Fix config source gen binding value types to null configuration values * Address the feedback --------- Co-authored-by: Tarek Mahmoud Sayed --- .../gen/Emitter/CoreBindingHelpers.cs | 4 +- .../ConfigurationBinderTests.TestClasses.cs | 20 +++++ .../tests/Common/ConfigurationBinderTests.cs | 82 +++++++++++++++++++ .../Version1/Bind.generated.txt | 4 +- .../Version1/Bind_Instance.generated.txt | 4 +- .../Bind_Instance_BinderOptions.generated.txt | 4 +- .../Version1/Bind_Key_Instance.generated.txt | 4 +- .../Version1/Get.generated.txt | 8 +- .../Version1/Get_PrimitivesOnly.generated.txt | 6 +- .../Version1/Get_T.generated.txt | 6 +- .../Get_T_BinderOptions.generated.txt | 6 +- .../Version1/Get_TypeOf.generated.txt | 2 +- .../Get_TypeOf_BinderOptions.generated.txt | 2 +- .../Version1/BindConfiguration.generated.txt | 4 +- ...gurationWithConfigureActions.generated.txt | 4 +- .../Version1/Bind_T.generated.txt | 4 +- .../Bind_T_BinderOptions.generated.txt | 4 +- .../Version1/Configure_T.generated.txt | 6 +- .../Configure_T_BinderOptions.generated.txt | 6 +- .../Version1/Configure_T_name.generated.txt | 6 +- ...nfigure_T_name_BinderOptions.generated.txt | 6 +- .../net462/Version1/Collections.generated.txt | 6 +- ...DefaultConstructorParameters.generated.txt | 24 +++--- .../net462/Version1/Primitives.generated.txt | 48 +++++------ .../Version1/UnsupportedTypes.generated.txt | 4 +- .../Version1/Bind.generated.txt | 4 +- .../Version1/Bind_Instance.generated.txt | 4 +- .../Bind_Instance_BinderOptions.generated.txt | 4 +- .../Version1/Bind_Key_Instance.generated.txt | 4 +- .../Version1/Get.generated.txt | 8 +- .../Version1/Get_PrimitivesOnly.generated.txt | 6 +- .../Version1/Get_T.generated.txt | 6 +- .../Get_T_BinderOptions.generated.txt | 6 +- .../Version1/Get_TypeOf.generated.txt | 2 +- .../Get_TypeOf_BinderOptions.generated.txt | 2 +- .../Version1/BindConfiguration.generated.txt | 4 +- ...gurationWithConfigureActions.generated.txt | 4 +- .../Version1/Bind_T.generated.txt | 4 +- .../Bind_T_BinderOptions.generated.txt | 4 +- .../Version1/Configure_T.generated.txt | 6 +- .../Configure_T_BinderOptions.generated.txt | 6 +- .../Version1/Configure_T_name.generated.txt | 6 +- ...nfigure_T_name_BinderOptions.generated.txt | 6 +- .../Version1/Collections.generated.txt | 6 +- ...DefaultConstructorParameters.generated.txt | 24 +++--- .../Version1/Primitives.generated.txt | 58 ++++++------- .../Version1/UnsupportedTypes.generated.txt | 4 +- 47 files changed, 278 insertions(+), 174 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 10dcb779a928d..fabdebd67eb4b 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/CoreBindingHelpers.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/CoreBindingHelpers.cs @@ -1109,7 +1109,9 @@ private void EmitBindingLogic( } else { - EmitStartBlock($"if ({sectionValueExpr} is string {nonNull_StringValue_Identifier})"); + // In case of calling parsing methods, check the section value first for null or empty before calling parse. + string extraCondition = typeKind == StringParsableTypeKind.AssignFromSectionValue ? "" : $" && !string.IsNullOrEmpty({nonNull_StringValue_Identifier})"; + EmitStartBlock($"if ({sectionValueExpr} is string {nonNull_StringValue_Identifier}{extraCondition})"); writeOnSuccess?.Invoke(parsedValueExpr); 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 31278be112195..96be1fa6c4164 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 @@ -1111,5 +1111,25 @@ private IEnumerable> enumerate() IEnumerator IEnumerable.GetEnumerator() => enumerate().GetEnumerator(); } + public class ParsableValuesClass + { + public int? IntValue { get; set; } + public double? DoubleValue { get; set; } + public bool? BoolValue { get; set; } + public decimal? DecimalValue { get; set; } + public float? FloatValue { get; set; } + public long? LongValue { get; set; } + public short? ShortValue { get; set; } + public byte? ByteValue { get; set; } + public sbyte? SByteValue { get; set; } + public uint? UIntValue { get; set; } + public ushort? UShortValue { get; set; } + public ulong? ULongValue { get; set; } + public DateTime? DateTimeValue { get; set; } + public DateTimeOffset? DateTimeOffsetValue { get; set; } + public TimeSpan? TimeSpanValue { get; set; } + public Guid? GuidValue { get; set; } + public StringComparison? StringComparisonValue { 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 b1f4ffb264a92..ef822713f367d 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Common/ConfigurationBinderTests.cs @@ -1544,6 +1544,88 @@ public void CanBindOnParametersAndProperties_RecordWithArrayConstructorParameter Assert.Equal(new string[] { "a", "b", "c" }, options.Array); } + + public static IEnumerable Configuration_TestData() + { + yield return new object[] + { + new ConfigurationBuilder() + .AddJsonStream(new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(@"{ + ""IntValue"" : """", + ""DoubleValue"" : """", + ""BoolValue"" : """", + ""DecimalValue"" : """", + ""FloatValue"" : """", + ""LongValue"" : """", + ""ShortValue"" : """", + ""ByteValue"" : """", + ""SByteValue"" : """", + ""UIntValue"" : """", + ""UShortValue"" : """", + ""ULongValue"" : """", + ""DateTimeValue"" : """", + ""DateTimeOffsetValue"" : """", + ""TimeSpanValue"" : """", + ""GuidValue"" : """", + ""StringComparisonValue"" : """" + }" + ))).Build() + }; + + yield return new object[] + { + new ConfigurationBuilder().AddInMemoryCollection( + new Dictionary + { + { "IntValue", null }, + { "DoubleValue", null }, + { "BoolValue", null }, + { "DecimalValue", null }, + { "FloatValue", null }, + { "LongValue", null }, + { "ShortValue", null }, + { "ByteValue", null }, + { "SByteValue", null }, + { "UIntValue", null }, + { "UShortValue", null }, + { "ULongValue", null }, + { "DateTimeValue", null }, + { "DateTimeOffsetValue", null }, + { "TimeSpanValue", null }, + { "GuidValue", null }, + { "StringComparisonValue", null }, + }).Build() + }; + } + + /// + /// Test binding a value parsable types to null configuration values. + /// The test ensure the binding will succeed without exceptions and the value will be null (not set). + /// + [Theory] + [MemberData(nameof(Configuration_TestData))] + public void BindToKnownParsableTypesWithNullValueTest(IConfiguration configuration) + { + ParsableValuesClass instance = configuration.Get(); + Assert.Null(instance.IntValue); + Assert.Null(instance.DoubleValue); + Assert.Null(instance.BoolValue); + Assert.Null(instance.DecimalValue); + Assert.Null(instance.FloatValue); + Assert.Null(instance.LongValue); + Assert.Null(instance.ShortValue); + Assert.Null(instance.ByteValue); + Assert.Null(instance.SByteValue); + Assert.Null(instance.UIntValue); + Assert.Null(instance.UShortValue); + Assert.Null(instance.ULongValue); + Assert.Null(instance.DateTimeValue); + Assert.Null(instance.DateTimeOffsetValue); + Assert.Null(instance.TimeSpanValue); + Assert.Null(instance.GuidValue); + Assert.Null(instance.StringComparisonValue); + } + /// /// Test binding to recursive types using Dictionary or Collections. /// This ensure no stack overflow will occur during the compilation through the source gen or at runtime. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Bind.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Bind.generated.txt index eafca53839991..d969a2ce0a9d3 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Bind.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Bind.generated.txt @@ -96,7 +96,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -143,7 +143,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value1) + if (configuration["MyInt"] is string value1 && !string.IsNullOrEmpty(value1)) { instance.MyInt = ParseInt(value1, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Bind_Instance.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Bind_Instance.generated.txt index b8114b76f70dc..243c0c7524417 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Bind_Instance.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Bind_Instance.generated.txt @@ -60,7 +60,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -107,7 +107,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value1) + if (configuration["MyInt"] is string value1 && !string.IsNullOrEmpty(value1)) { instance.MyInt = ParseInt(value1, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Bind_Instance_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Bind_Instance_BinderOptions.generated.txt index 7eaabd7a89ab2..52b29ac28967b 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Bind_Instance_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Bind_Instance_BinderOptions.generated.txt @@ -60,7 +60,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -107,7 +107,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value1) + if (configuration["MyInt"] is string value1 && !string.IsNullOrEmpty(value1)) { instance.MyInt = ParseInt(value1, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Bind_Key_Instance.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Bind_Key_Instance.generated.txt index ed66e64fde8f9..aa3c6a9e94310 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Bind_Key_Instance.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Bind_Key_Instance.generated.txt @@ -60,7 +60,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -107,7 +107,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value1) + if (configuration["MyInt"] is string value1 && !string.IsNullOrEmpty(value1)) { instance.MyInt = ParseInt(value1, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Get.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Get.generated.txt index 5745fe8f16ace..68ddfa4c042c1 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Get.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Get.generated.txt @@ -89,7 +89,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -102,7 +102,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { temp2.Add(ParseInt(value, section.Path)); } @@ -141,7 +141,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value4) + if (configuration["MyInt"] is string value4 && !string.IsNullOrEmpty(value4)) { instance.MyInt = ParseInt(value4, configuration.GetSection("MyInt").Path); } @@ -191,7 +191,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { ValidateConfigurationKeys(typeof(global::Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); - if (configuration["MyInt"] is string value14) + if (configuration["MyInt"] is string value14 && !string.IsNullOrEmpty(value14)) { instance.MyInt = ParseInt(value14, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Get_PrimitivesOnly.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Get_PrimitivesOnly.generated.txt index 8ac6d07d29c65..97cdab82512c5 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Get_PrimitivesOnly.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Get_PrimitivesOnly.generated.txt @@ -71,7 +71,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { throw new InvalidOperationException(); } - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { return ParseInt(value, section.Path); } @@ -90,7 +90,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { throw new InvalidOperationException(); } - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { return ParseFloat(value, section.Path); } @@ -101,7 +101,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { throw new InvalidOperationException(); } - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { return ParseDouble(value, section.Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Get_T.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Get_T.generated.txt index a4bf3676be741..1c7b92598f41e 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Get_T.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Get_T.generated.txt @@ -70,7 +70,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -83,7 +83,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { temp1.Add(ParseInt(value, section.Path)); } @@ -122,7 +122,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value3) + if (configuration["MyInt"] is string value3 && !string.IsNullOrEmpty(value3)) { instance.MyInt = ParseInt(value3, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Get_T_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Get_T_BinderOptions.generated.txt index 0ea405142fe29..7598e23660007 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Get_T_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Get_T_BinderOptions.generated.txt @@ -70,7 +70,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -83,7 +83,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { temp1.Add(ParseInt(value, section.Path)); } @@ -122,7 +122,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value3) + if (configuration["MyInt"] is string value3 && !string.IsNullOrEmpty(value3)) { instance.MyInt = ParseInt(value3, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Get_TypeOf.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Get_TypeOf.generated.txt index 09c568050ea1e..589f4b4fb10d9 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Get_TypeOf.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Get_TypeOf.generated.txt @@ -70,7 +70,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { ValidateConfigurationKeys(typeof(global::Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); - if (configuration["MyInt"] is string value1) + if (configuration["MyInt"] is string value1 && !string.IsNullOrEmpty(value1)) { instance.MyInt = ParseInt(value1, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Get_TypeOf_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Get_TypeOf_BinderOptions.generated.txt index 3d3c4340e9719..53ee49e5ed1c6 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Get_TypeOf_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ConfigurationBinder/Version1/Get_TypeOf_BinderOptions.generated.txt @@ -70,7 +70,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { ValidateConfigurationKeys(typeof(global::Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); - if (configuration["MyInt"] is string value1) + if (configuration["MyInt"] is string value1 && !string.IsNullOrEmpty(value1)) { instance.MyInt = ParseInt(value1, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/OptionsBuilder/Version1/BindConfiguration.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/OptionsBuilder/Version1/BindConfiguration.generated.txt index a5fa9894a9e57..7981bfc8de6d5 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/OptionsBuilder/Version1/BindConfiguration.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/OptionsBuilder/Version1/BindConfiguration.generated.txt @@ -101,7 +101,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -125,7 +125,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value2) + if (configuration["MyInt"] is string value2 && !string.IsNullOrEmpty(value2)) { instance.MyInt = ParseInt(value2, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/OptionsBuilder/Version1/BindConfigurationWithConfigureActions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/OptionsBuilder/Version1/BindConfigurationWithConfigureActions.generated.txt index 8ed59c5e13746..7c89f54e22902 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/OptionsBuilder/Version1/BindConfigurationWithConfigureActions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/OptionsBuilder/Version1/BindConfigurationWithConfigureActions.generated.txt @@ -101,7 +101,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -125,7 +125,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value2) + if (configuration["MyInt"] is string value2 && !string.IsNullOrEmpty(value2)) { instance.MyInt = ParseInt(value2, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/OptionsBuilder/Version1/Bind_T.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/OptionsBuilder/Version1/Bind_T.generated.txt index a74b4934b12ab..d76fb22d50b1a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/OptionsBuilder/Version1/Bind_T.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/OptionsBuilder/Version1/Bind_T.generated.txt @@ -107,7 +107,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -131,7 +131,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value2) + if (configuration["MyInt"] is string value2 && !string.IsNullOrEmpty(value2)) { instance.MyInt = ParseInt(value2, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/OptionsBuilder/Version1/Bind_T_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/OptionsBuilder/Version1/Bind_T_BinderOptions.generated.txt index efafd0eb6a5b1..782feb787862f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/OptionsBuilder/Version1/Bind_T_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/OptionsBuilder/Version1/Bind_T_BinderOptions.generated.txt @@ -101,7 +101,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -125,7 +125,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value2) + if (configuration["MyInt"] is string value2 && !string.IsNullOrEmpty(value2)) { instance.MyInt = ParseInt(value2, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ServiceCollection/Version1/Configure_T.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ServiceCollection/Version1/Configure_T.generated.txt index b379e4993ea2e..a15b599220ada 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ServiceCollection/Version1/Configure_T.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ServiceCollection/Version1/Configure_T.generated.txt @@ -95,7 +95,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -106,7 +106,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { ValidateConfigurationKeys(typeof(global::Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); - if (configuration["MyInt"] is string value1) + if (configuration["MyInt"] is string value1 && !string.IsNullOrEmpty(value1)) { instance.MyInt = ParseInt(value1, configuration.GetSection("MyInt").Path); } @@ -158,7 +158,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value4) + if (configuration["MyInt"] is string value4 && !string.IsNullOrEmpty(value4)) { instance.MyInt = ParseInt(value4, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ServiceCollection/Version1/Configure_T_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ServiceCollection/Version1/Configure_T_BinderOptions.generated.txt index 8a52959bc613e..3e65d96e3f47b 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ServiceCollection/Version1/Configure_T_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ServiceCollection/Version1/Configure_T_BinderOptions.generated.txt @@ -95,7 +95,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -106,7 +106,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { ValidateConfigurationKeys(typeof(global::Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); - if (configuration["MyInt"] is string value1) + if (configuration["MyInt"] is string value1 && !string.IsNullOrEmpty(value1)) { instance.MyInt = ParseInt(value1, configuration.GetSection("MyInt").Path); } @@ -158,7 +158,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value4) + if (configuration["MyInt"] is string value4 && !string.IsNullOrEmpty(value4)) { instance.MyInt = ParseInt(value4, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ServiceCollection/Version1/Configure_T_name.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ServiceCollection/Version1/Configure_T_name.generated.txt index 2ab4a08cd8fb1..af7456240056c 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ServiceCollection/Version1/Configure_T_name.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ServiceCollection/Version1/Configure_T_name.generated.txt @@ -95,7 +95,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -106,7 +106,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { ValidateConfigurationKeys(typeof(global::Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); - if (configuration["MyInt"] is string value1) + if (configuration["MyInt"] is string value1 && !string.IsNullOrEmpty(value1)) { instance.MyInt = ParseInt(value1, configuration.GetSection("MyInt").Path); } @@ -158,7 +158,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value4) + if (configuration["MyInt"] is string value4 && !string.IsNullOrEmpty(value4)) { instance.MyInt = ParseInt(value4, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ServiceCollection/Version1/Configure_T_name_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ServiceCollection/Version1/Configure_T_name_BinderOptions.generated.txt index 4d87b2e4d2d1b..b5f3bd2069baa 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ServiceCollection/Version1/Configure_T_name_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/ServiceCollection/Version1/Configure_T_name_BinderOptions.generated.txt @@ -89,7 +89,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -100,7 +100,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { ValidateConfigurationKeys(typeof(global::Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); - if (configuration["MyInt"] is string value1) + if (configuration["MyInt"] is string value1 && !string.IsNullOrEmpty(value1)) { instance.MyInt = ParseInt(value1, configuration.GetSection("MyInt").Path); } @@ -152,7 +152,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value4) + if (configuration["MyInt"] is string value4 && !string.IsNullOrEmpty(value4)) { instance.MyInt = ParseInt(value4, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/Version1/Collections.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/Version1/Collections.generated.txt index b0f90ddf5b416..3bb04809ead38 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/Version1/Collections.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/Version1/Collections.generated.txt @@ -71,7 +71,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance[section.Key] = ParseInt(value, section.Path); } @@ -98,7 +98,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { temp.Add(ParseInt(value, section.Path)); } @@ -114,7 +114,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { temp[section.Key] = ParseInt(value, section.Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/Version1/DefaultConstructorParameters.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/Version1/DefaultConstructorParameters.generated.txt index dbcadc11d177a..bf84547cab061 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/Version1/DefaultConstructorParameters.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/Version1/DefaultConstructorParameters.generated.txt @@ -76,73 +76,73 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } int age = (int)(42); - if (configuration["Age"] is string value2) + if (configuration["Age"] is string value2 && !string.IsNullOrEmpty(value2)) { age = ParseInt(value2, configuration.GetSection("Age").Path); } float f = 42F; - if (configuration["F"] is string value3) + if (configuration["F"] is string value3 && !string.IsNullOrEmpty(value3)) { f = ParseFloat(value3, configuration.GetSection("F").Path); } double d = 3.1415899999999999D; - if (configuration["D"] is string value4) + if (configuration["D"] is string value4 && !string.IsNullOrEmpty(value4)) { d = ParseDouble(value4, configuration.GetSection("D").Path); } decimal m = 3.1415926535897932384626433M; - if (configuration["M"] is string value5) + if (configuration["M"] is string value5 && !string.IsNullOrEmpty(value5)) { m = ParseDecimal(value5, configuration.GetSection("M").Path); } global::System.StringComparison sc = (global::System.StringComparison)(4); - if (configuration["SC"] is string value6) + if (configuration["SC"] is string value6 && !string.IsNullOrEmpty(value6)) { sc = ParseEnum(value6, configuration.GetSection("SC").Path); } char c = 'q'; - if (configuration["C"] is string value7) + if (configuration["C"] is string value7 && !string.IsNullOrEmpty(value7)) { c = ParseChar(value7, configuration.GetSection("C").Path); } int? nage = (int?)(42); - if (configuration["NAge"] is string value8) + if (configuration["NAge"] is string value8 && !string.IsNullOrEmpty(value8)) { nage = ParseInt(value8, configuration.GetSection("NAge").Path); } float? nf = 42F; - if (configuration["NF"] is string value9) + if (configuration["NF"] is string value9 && !string.IsNullOrEmpty(value9)) { nf = ParseFloat(value9, configuration.GetSection("NF").Path); } double? nd = 3.1415899999999999D; - if (configuration["ND"] is string value10) + if (configuration["ND"] is string value10 && !string.IsNullOrEmpty(value10)) { nd = ParseDouble(value10, configuration.GetSection("ND").Path); } decimal? nm = 3.1415926535897932384626433M; - if (configuration["NM"] is string value11) + if (configuration["NM"] is string value11 && !string.IsNullOrEmpty(value11)) { nm = ParseDecimal(value11, configuration.GetSection("NM").Path); } global::System.StringComparison? nsc = (global::System.StringComparison?)(4); - if (configuration["NSC"] is string value12) + if (configuration["NSC"] is string value12 && !string.IsNullOrEmpty(value12)) { nsc = ParseEnum(value12, configuration.GetSection("NSC").Path); } char? nc = 'q'; - if (configuration["NC"] is string value13) + if (configuration["NC"] is string value13 && !string.IsNullOrEmpty(value13)) { nc = ParseChar(value13, configuration.GetSection("NC").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/Version1/Primitives.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/Version1/Primitives.generated.txt index 57e6403dc8268..862e062c05499 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/Version1/Primitives.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/Version1/Primitives.generated.txt @@ -60,7 +60,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { ValidateConfigurationKeys(typeof(global::Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - if (configuration["Prop0"] is string value0) + if (configuration["Prop0"] is string value0 && !string.IsNullOrEmpty(value0)) { instance.Prop0 = ParseBool(value0, configuration.GetSection("Prop0").Path); } @@ -69,7 +69,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop0 = instance.Prop0; } - if (configuration["Prop1"] is string value1) + if (configuration["Prop1"] is string value1 && !string.IsNullOrEmpty(value1)) { instance.Prop1 = ParseByte(value1, configuration.GetSection("Prop1").Path); } @@ -78,7 +78,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop1 = instance.Prop1; } - if (configuration["Prop2"] is string value2) + if (configuration["Prop2"] is string value2 && !string.IsNullOrEmpty(value2)) { instance.Prop2 = ParseSbyte(value2, configuration.GetSection("Prop2").Path); } @@ -87,7 +87,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop2 = instance.Prop2; } - if (configuration["Prop3"] is string value3) + if (configuration["Prop3"] is string value3 && !string.IsNullOrEmpty(value3)) { instance.Prop3 = ParseChar(value3, configuration.GetSection("Prop3").Path); } @@ -96,7 +96,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop3 = instance.Prop3; } - if (configuration["Prop4"] is string value4) + if (configuration["Prop4"] is string value4 && !string.IsNullOrEmpty(value4)) { instance.Prop4 = ParseDouble(value4, configuration.GetSection("Prop4").Path); } @@ -118,7 +118,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["Prop6"] is string value6) + if (configuration["Prop6"] is string value6 && !string.IsNullOrEmpty(value6)) { instance.Prop6 = ParseInt(value6, configuration.GetSection("Prop6").Path); } @@ -127,7 +127,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop6 = instance.Prop6; } - if (configuration["Prop8"] is string value7) + if (configuration["Prop8"] is string value7 && !string.IsNullOrEmpty(value7)) { instance.Prop8 = ParseShort(value7, configuration.GetSection("Prop8").Path); } @@ -136,7 +136,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop8 = instance.Prop8; } - if (configuration["Prop9"] is string value8) + if (configuration["Prop9"] is string value8 && !string.IsNullOrEmpty(value8)) { instance.Prop9 = ParseLong(value8, configuration.GetSection("Prop9").Path); } @@ -145,7 +145,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop9 = instance.Prop9; } - if (configuration["Prop10"] is string value9) + if (configuration["Prop10"] is string value9 && !string.IsNullOrEmpty(value9)) { instance.Prop10 = ParseFloat(value9, configuration.GetSection("Prop10").Path); } @@ -154,7 +154,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop10 = instance.Prop10; } - if (configuration["Prop13"] is string value10) + if (configuration["Prop13"] is string value10 && !string.IsNullOrEmpty(value10)) { instance.Prop13 = ParseUshort(value10, configuration.GetSection("Prop13").Path); } @@ -163,7 +163,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop13 = instance.Prop13; } - if (configuration["Prop14"] is string value11) + if (configuration["Prop14"] is string value11 && !string.IsNullOrEmpty(value11)) { instance.Prop14 = ParseUint(value11, configuration.GetSection("Prop14").Path); } @@ -172,7 +172,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop14 = instance.Prop14; } - if (configuration["Prop15"] is string value12) + if (configuration["Prop15"] is string value12 && !string.IsNullOrEmpty(value12)) { instance.Prop15 = ParseUlong(value12, configuration.GetSection("Prop15").Path); } @@ -194,7 +194,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["Prop17"] is string value14) + if (configuration["Prop17"] is string value14 && !string.IsNullOrEmpty(value14)) { instance.Prop17 = ParseSystemGlobalizationCultureInfo(value14, configuration.GetSection("Prop17").Path); } @@ -207,7 +207,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["Prop19"] is string value15) + if (configuration["Prop19"] is string value15 && !string.IsNullOrEmpty(value15)) { instance.Prop19 = ParseSystemDateTime(value15, configuration.GetSection("Prop19").Path); } @@ -216,7 +216,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop19 = instance.Prop19; } - if (configuration["Prop20"] is string value16) + if (configuration["Prop20"] is string value16 && !string.IsNullOrEmpty(value16)) { instance.Prop20 = ParseSystemDateTimeOffset(value16, configuration.GetSection("Prop20").Path); } @@ -225,7 +225,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop20 = instance.Prop20; } - if (configuration["Prop21"] is string value17) + if (configuration["Prop21"] is string value17 && !string.IsNullOrEmpty(value17)) { instance.Prop21 = ParseDecimal(value17, configuration.GetSection("Prop21").Path); } @@ -234,7 +234,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop21 = instance.Prop21; } - if (configuration["Prop23"] is string value18) + if (configuration["Prop23"] is string value18 && !string.IsNullOrEmpty(value18)) { instance.Prop23 = ParseSystemTimeSpan(value18, configuration.GetSection("Prop23").Path); } @@ -243,7 +243,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop23 = instance.Prop23; } - if (configuration["Prop24"] is string value19) + if (configuration["Prop24"] is string value19 && !string.IsNullOrEmpty(value19)) { instance.Prop24 = ParseSystemGuid(value19, configuration.GetSection("Prop24").Path); } @@ -252,7 +252,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop24 = instance.Prop24; } - if (configuration["Prop25"] is string value20) + if (configuration["Prop25"] is string value20 && !string.IsNullOrEmpty(value20)) { instance.Prop25 = ParseSystemUri(value20, configuration.GetSection("Prop25").Path); } @@ -265,7 +265,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["Prop26"] is string value21) + if (configuration["Prop26"] is string value21 && !string.IsNullOrEmpty(value21)) { instance.Prop26 = ParseSystemVersion(value21, configuration.GetSection("Prop26").Path); } @@ -278,7 +278,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["Prop27"] is string value22) + if (configuration["Prop27"] is string value22 && !string.IsNullOrEmpty(value22)) { instance.Prop27 = ParseEnum(value22, configuration.GetSection("Prop27").Path); } @@ -287,7 +287,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop27 = instance.Prop27; } - if (configuration["Prop28"] is string value23) + if (configuration["Prop28"] is string value23 && !string.IsNullOrEmpty(value23)) { instance.Prop28 = ParseByteArray(value23, configuration.GetSection("Prop28").Path); } @@ -300,7 +300,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["Prop29"] is string value24) + if (configuration["Prop29"] is string value24 && !string.IsNullOrEmpty(value24)) { instance.Prop29 = ParseInt(value24, configuration.GetSection("Prop29").Path); } @@ -309,7 +309,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop29 = instance.Prop29; } - if (configuration["Prop30"] is string value25) + if (configuration["Prop30"] is string value25 && !string.IsNullOrEmpty(value25)) { instance.Prop30 = ParseSystemDateTime(value25, configuration.GetSection("Prop30").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/Version1/UnsupportedTypes.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/Version1/UnsupportedTypes.generated.txt index 4cdd6685f6ac7..6b9ae8a88e90f 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/Version1/UnsupportedTypes.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/net462/Version1/UnsupportedTypes.generated.txt @@ -143,7 +143,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["Age"] is string value3) + if (configuration["Age"] is string value3 && !string.IsNullOrEmpty(value3)) { instance.Age = ParseInt(value3, configuration.GetSection("Age").Path); } @@ -192,7 +192,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static global::Record InitializeRecordAction(IConfiguration configuration, BinderOptions? binderOptions) { int x = (int)(10); - if (configuration["x"] is string value13) + if (configuration["x"] is string value13 && !string.IsNullOrEmpty(value13)) { x = ParseInt(value13, configuration.GetSection("x").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Bind.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Bind.generated.txt index 85ebf4c500e36..499cd068953bd 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Bind.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Bind.generated.txt @@ -87,7 +87,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -134,7 +134,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value1) + if (configuration["MyInt"] is string value1 && !string.IsNullOrEmpty(value1)) { instance.MyInt = ParseInt(value1, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Bind_Instance.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Bind_Instance.generated.txt index f090695e031bf..43edcd5055914 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Bind_Instance.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Bind_Instance.generated.txt @@ -57,7 +57,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -104,7 +104,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value1) + if (configuration["MyInt"] is string value1 && !string.IsNullOrEmpty(value1)) { instance.MyInt = ParseInt(value1, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Bind_Instance_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Bind_Instance_BinderOptions.generated.txt index fae095fdf9047..b6e930a7f3e3d 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Bind_Instance_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Bind_Instance_BinderOptions.generated.txt @@ -57,7 +57,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -104,7 +104,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value1) + if (configuration["MyInt"] is string value1 && !string.IsNullOrEmpty(value1)) { instance.MyInt = ParseInt(value1, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Bind_Key_Instance.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Bind_Key_Instance.generated.txt index ec1527b06b930..471dd1aeded6e 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Bind_Key_Instance.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Bind_Key_Instance.generated.txt @@ -57,7 +57,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -104,7 +104,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value1) + if (configuration["MyInt"] is string value1 && !string.IsNullOrEmpty(value1)) { instance.MyInt = ParseInt(value1, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Get.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Get.generated.txt index b1c4087f510f3..cf7bf6a8fbfe2 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Get.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Get.generated.txt @@ -86,7 +86,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -99,7 +99,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { temp2.Add(ParseInt(value, section.Path)); } @@ -138,7 +138,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value4) + if (configuration["MyInt"] is string value4 && !string.IsNullOrEmpty(value4)) { instance.MyInt = ParseInt(value4, configuration.GetSection("MyInt").Path); } @@ -188,7 +188,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { ValidateConfigurationKeys(typeof(global::Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); - if (configuration["MyInt"] is string value14) + if (configuration["MyInt"] is string value14 && !string.IsNullOrEmpty(value14)) { instance.MyInt = ParseInt(value14, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Get_PrimitivesOnly.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Get_PrimitivesOnly.generated.txt index 7ce53871d7d68..9b1bc5e1ea5c7 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Get_PrimitivesOnly.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Get_PrimitivesOnly.generated.txt @@ -68,7 +68,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { throw new InvalidOperationException(); } - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { return ParseInt(value, section.Path); } @@ -87,7 +87,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { throw new InvalidOperationException(); } - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { return ParseFloat(value, section.Path); } @@ -98,7 +98,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { throw new InvalidOperationException(); } - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { return ParseDouble(value, section.Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Get_T.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Get_T.generated.txt index 438b31ea5a373..a1fa448fd76f2 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Get_T.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Get_T.generated.txt @@ -67,7 +67,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -80,7 +80,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { temp1.Add(ParseInt(value, section.Path)); } @@ -119,7 +119,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value3) + if (configuration["MyInt"] is string value3 && !string.IsNullOrEmpty(value3)) { instance.MyInt = ParseInt(value3, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Get_T_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Get_T_BinderOptions.generated.txt index e3b4d79b987a4..8224f0967d14b 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Get_T_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Get_T_BinderOptions.generated.txt @@ -67,7 +67,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -80,7 +80,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { temp1.Add(ParseInt(value, section.Path)); } @@ -119,7 +119,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value3) + if (configuration["MyInt"] is string value3 && !string.IsNullOrEmpty(value3)) { instance.MyInt = ParseInt(value3, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Get_TypeOf.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Get_TypeOf.generated.txt index 096d659c11774..4ed9fffb98423 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Get_TypeOf.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Get_TypeOf.generated.txt @@ -67,7 +67,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { ValidateConfigurationKeys(typeof(global::Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); - if (configuration["MyInt"] is string value1) + if (configuration["MyInt"] is string value1 && !string.IsNullOrEmpty(value1)) { instance.MyInt = ParseInt(value1, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Get_TypeOf_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Get_TypeOf_BinderOptions.generated.txt index 2d338610619c8..5a576795bfdb9 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Get_TypeOf_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ConfigurationBinder/Version1/Get_TypeOf_BinderOptions.generated.txt @@ -67,7 +67,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { ValidateConfigurationKeys(typeof(global::Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); - if (configuration["MyInt"] is string value1) + if (configuration["MyInt"] is string value1 && !string.IsNullOrEmpty(value1)) { instance.MyInt = ParseInt(value1, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/OptionsBuilder/Version1/BindConfiguration.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/OptionsBuilder/Version1/BindConfiguration.generated.txt index 2f96ede4aa3fb..70ca8bf3f0546 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/OptionsBuilder/Version1/BindConfiguration.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/OptionsBuilder/Version1/BindConfiguration.generated.txt @@ -92,7 +92,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -116,7 +116,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value2) + if (configuration["MyInt"] is string value2 && !string.IsNullOrEmpty(value2)) { instance.MyInt = ParseInt(value2, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/OptionsBuilder/Version1/BindConfigurationWithConfigureActions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/OptionsBuilder/Version1/BindConfigurationWithConfigureActions.generated.txt index 96ede4c24d361..52d92bd33dffe 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/OptionsBuilder/Version1/BindConfigurationWithConfigureActions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/OptionsBuilder/Version1/BindConfigurationWithConfigureActions.generated.txt @@ -92,7 +92,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -116,7 +116,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value2) + if (configuration["MyInt"] is string value2 && !string.IsNullOrEmpty(value2)) { instance.MyInt = ParseInt(value2, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/OptionsBuilder/Version1/Bind_T.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/OptionsBuilder/Version1/Bind_T.generated.txt index 340cfa41f749c..8479f9c6672d5 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/OptionsBuilder/Version1/Bind_T.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/OptionsBuilder/Version1/Bind_T.generated.txt @@ -98,7 +98,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -122,7 +122,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value2) + if (configuration["MyInt"] is string value2 && !string.IsNullOrEmpty(value2)) { instance.MyInt = ParseInt(value2, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/OptionsBuilder/Version1/Bind_T_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/OptionsBuilder/Version1/Bind_T_BinderOptions.generated.txt index 640cb5b5afeed..6b7825d2ca8ab 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/OptionsBuilder/Version1/Bind_T_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/OptionsBuilder/Version1/Bind_T_BinderOptions.generated.txt @@ -92,7 +92,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -116,7 +116,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value2) + if (configuration["MyInt"] is string value2 && !string.IsNullOrEmpty(value2)) { instance.MyInt = ParseInt(value2, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ServiceCollection/Version1/Configure_T.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ServiceCollection/Version1/Configure_T.generated.txt index 3f926839b122f..2c322e75c16fe 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ServiceCollection/Version1/Configure_T.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ServiceCollection/Version1/Configure_T.generated.txt @@ -89,7 +89,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -100,7 +100,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { ValidateConfigurationKeys(typeof(global::Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); - if (configuration["MyInt"] is string value1) + if (configuration["MyInt"] is string value1 && !string.IsNullOrEmpty(value1)) { instance.MyInt = ParseInt(value1, configuration.GetSection("MyInt").Path); } @@ -152,7 +152,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value4) + if (configuration["MyInt"] is string value4 && !string.IsNullOrEmpty(value4)) { instance.MyInt = ParseInt(value4, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ServiceCollection/Version1/Configure_T_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ServiceCollection/Version1/Configure_T_BinderOptions.generated.txt index 0dd10a3677ff6..d9d27cdee4c77 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ServiceCollection/Version1/Configure_T_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ServiceCollection/Version1/Configure_T_BinderOptions.generated.txt @@ -89,7 +89,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -100,7 +100,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { ValidateConfigurationKeys(typeof(global::Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); - if (configuration["MyInt"] is string value1) + if (configuration["MyInt"] is string value1 && !string.IsNullOrEmpty(value1)) { instance.MyInt = ParseInt(value1, configuration.GetSection("MyInt").Path); } @@ -152,7 +152,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value4) + if (configuration["MyInt"] is string value4 && !string.IsNullOrEmpty(value4)) { instance.MyInt = ParseInt(value4, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ServiceCollection/Version1/Configure_T_name.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ServiceCollection/Version1/Configure_T_name.generated.txt index bdc65cf2f22fd..68019fb6069b3 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ServiceCollection/Version1/Configure_T_name.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ServiceCollection/Version1/Configure_T_name.generated.txt @@ -89,7 +89,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -100,7 +100,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { ValidateConfigurationKeys(typeof(global::Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); - if (configuration["MyInt"] is string value1) + if (configuration["MyInt"] is string value1 && !string.IsNullOrEmpty(value1)) { instance.MyInt = ParseInt(value1, configuration.GetSection("MyInt").Path); } @@ -152,7 +152,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value4) + if (configuration["MyInt"] is string value4 && !string.IsNullOrEmpty(value4)) { instance.MyInt = ParseInt(value4, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ServiceCollection/Version1/Configure_T_name_BinderOptions.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ServiceCollection/Version1/Configure_T_name_BinderOptions.generated.txt index 9b3ee20e9cd67..80ad0e0943f11 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ServiceCollection/Version1/Configure_T_name_BinderOptions.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/ServiceCollection/Version1/Configure_T_name_BinderOptions.generated.txt @@ -83,7 +83,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance.Add(ParseInt(value, section.Path)); } @@ -94,7 +94,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { ValidateConfigurationKeys(typeof(global::Program.MyClass2), s_configKeys_ProgramMyClass2, configuration, binderOptions); - if (configuration["MyInt"] is string value1) + if (configuration["MyInt"] is string value1 && !string.IsNullOrEmpty(value1)) { instance.MyInt = ParseInt(value1, configuration.GetSection("MyInt").Path); } @@ -146,7 +146,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["MyInt"] is string value4) + if (configuration["MyInt"] is string value4 && !string.IsNullOrEmpty(value4)) { instance.MyInt = ParseInt(value4, configuration.GetSection("MyInt").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/Version1/Collections.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/Version1/Collections.generated.txt index 8fed2d02c2075..2d0e1f3207ef2 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/Version1/Collections.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/Version1/Collections.generated.txt @@ -68,7 +68,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { instance[section.Key] = ParseInt(value, section.Path); } @@ -95,7 +95,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { temp.Add(ParseInt(value, section.Path)); } @@ -111,7 +111,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration foreach (IConfigurationSection section in configuration.GetChildren()) { - if (section.Value is string value) + if (section.Value is string value && !string.IsNullOrEmpty(value)) { temp[section.Key] = ParseInt(value, section.Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/Version1/DefaultConstructorParameters.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/Version1/DefaultConstructorParameters.generated.txt index 57fabba9d1faf..f726e2254264b 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/Version1/DefaultConstructorParameters.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/Version1/DefaultConstructorParameters.generated.txt @@ -73,73 +73,73 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } int age = (int)(42); - if (configuration["Age"] is string value2) + if (configuration["Age"] is string value2 && !string.IsNullOrEmpty(value2)) { age = ParseInt(value2, configuration.GetSection("Age").Path); } float f = 42F; - if (configuration["F"] is string value3) + if (configuration["F"] is string value3 && !string.IsNullOrEmpty(value3)) { f = ParseFloat(value3, configuration.GetSection("F").Path); } double d = 3.1415899999999999D; - if (configuration["D"] is string value4) + if (configuration["D"] is string value4 && !string.IsNullOrEmpty(value4)) { d = ParseDouble(value4, configuration.GetSection("D").Path); } decimal m = 3.1415926535897932384626433M; - if (configuration["M"] is string value5) + if (configuration["M"] is string value5 && !string.IsNullOrEmpty(value5)) { m = ParseDecimal(value5, configuration.GetSection("M").Path); } global::System.StringComparison sc = (global::System.StringComparison)(4); - if (configuration["SC"] is string value6) + if (configuration["SC"] is string value6 && !string.IsNullOrEmpty(value6)) { sc = ParseEnum(value6, configuration.GetSection("SC").Path); } char c = 'q'; - if (configuration["C"] is string value7) + if (configuration["C"] is string value7 && !string.IsNullOrEmpty(value7)) { c = ParseChar(value7, configuration.GetSection("C").Path); } int? nage = (int?)(42); - if (configuration["NAge"] is string value8) + if (configuration["NAge"] is string value8 && !string.IsNullOrEmpty(value8)) { nage = ParseInt(value8, configuration.GetSection("NAge").Path); } float? nf = 42F; - if (configuration["NF"] is string value9) + if (configuration["NF"] is string value9 && !string.IsNullOrEmpty(value9)) { nf = ParseFloat(value9, configuration.GetSection("NF").Path); } double? nd = 3.1415899999999999D; - if (configuration["ND"] is string value10) + if (configuration["ND"] is string value10 && !string.IsNullOrEmpty(value10)) { nd = ParseDouble(value10, configuration.GetSection("ND").Path); } decimal? nm = 3.1415926535897932384626433M; - if (configuration["NM"] is string value11) + if (configuration["NM"] is string value11 && !string.IsNullOrEmpty(value11)) { nm = ParseDecimal(value11, configuration.GetSection("NM").Path); } global::System.StringComparison? nsc = (global::System.StringComparison?)(4); - if (configuration["NSC"] is string value12) + if (configuration["NSC"] is string value12 && !string.IsNullOrEmpty(value12)) { nsc = ParseEnum(value12, configuration.GetSection("NSC").Path); } char? nc = 'q'; - if (configuration["NC"] is string value13) + if (configuration["NC"] is string value13 && !string.IsNullOrEmpty(value13)) { nc = ParseChar(value13, configuration.GetSection("NC").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/Version1/Primitives.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/Version1/Primitives.generated.txt index 7e442555da5e1..92787bd1909df 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/Version1/Primitives.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/Version1/Primitives.generated.txt @@ -57,7 +57,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration { ValidateConfigurationKeys(typeof(global::Program.MyClass), s_configKeys_ProgramMyClass, configuration, binderOptions); - if (configuration["Prop0"] is string value0) + if (configuration["Prop0"] is string value0 && !string.IsNullOrEmpty(value0)) { instance.Prop0 = ParseBool(value0, configuration.GetSection("Prop0").Path); } @@ -66,7 +66,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop0 = instance.Prop0; } - if (configuration["Prop1"] is string value1) + if (configuration["Prop1"] is string value1 && !string.IsNullOrEmpty(value1)) { instance.Prop1 = ParseByte(value1, configuration.GetSection("Prop1").Path); } @@ -75,7 +75,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop1 = instance.Prop1; } - if (configuration["Prop2"] is string value2) + if (configuration["Prop2"] is string value2 && !string.IsNullOrEmpty(value2)) { instance.Prop2 = ParseSbyte(value2, configuration.GetSection("Prop2").Path); } @@ -84,7 +84,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop2 = instance.Prop2; } - if (configuration["Prop3"] is string value3) + if (configuration["Prop3"] is string value3 && !string.IsNullOrEmpty(value3)) { instance.Prop3 = ParseChar(value3, configuration.GetSection("Prop3").Path); } @@ -93,7 +93,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop3 = instance.Prop3; } - if (configuration["Prop4"] is string value4) + if (configuration["Prop4"] is string value4 && !string.IsNullOrEmpty(value4)) { instance.Prop4 = ParseDouble(value4, configuration.GetSection("Prop4").Path); } @@ -115,7 +115,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["Prop6"] is string value6) + if (configuration["Prop6"] is string value6 && !string.IsNullOrEmpty(value6)) { instance.Prop6 = ParseInt(value6, configuration.GetSection("Prop6").Path); } @@ -124,7 +124,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop6 = instance.Prop6; } - if (configuration["Prop8"] is string value7) + if (configuration["Prop8"] is string value7 && !string.IsNullOrEmpty(value7)) { instance.Prop8 = ParseShort(value7, configuration.GetSection("Prop8").Path); } @@ -133,7 +133,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop8 = instance.Prop8; } - if (configuration["Prop9"] is string value8) + if (configuration["Prop9"] is string value8 && !string.IsNullOrEmpty(value8)) { instance.Prop9 = ParseLong(value8, configuration.GetSection("Prop9").Path); } @@ -142,7 +142,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop9 = instance.Prop9; } - if (configuration["Prop10"] is string value9) + if (configuration["Prop10"] is string value9 && !string.IsNullOrEmpty(value9)) { instance.Prop10 = ParseFloat(value9, configuration.GetSection("Prop10").Path); } @@ -151,7 +151,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop10 = instance.Prop10; } - if (configuration["Prop13"] is string value10) + if (configuration["Prop13"] is string value10 && !string.IsNullOrEmpty(value10)) { instance.Prop13 = ParseUshort(value10, configuration.GetSection("Prop13").Path); } @@ -160,7 +160,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop13 = instance.Prop13; } - if (configuration["Prop14"] is string value11) + if (configuration["Prop14"] is string value11 && !string.IsNullOrEmpty(value11)) { instance.Prop14 = ParseUint(value11, configuration.GetSection("Prop14").Path); } @@ -169,7 +169,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop14 = instance.Prop14; } - if (configuration["Prop15"] is string value12) + if (configuration["Prop15"] is string value12 && !string.IsNullOrEmpty(value12)) { instance.Prop15 = ParseUlong(value12, configuration.GetSection("Prop15").Path); } @@ -191,7 +191,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["Prop17"] is string value14) + if (configuration["Prop17"] is string value14 && !string.IsNullOrEmpty(value14)) { instance.Prop17 = ParseSystemGlobalizationCultureInfo(value14, configuration.GetSection("Prop17").Path); } @@ -204,7 +204,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["Prop19"] is string value15) + if (configuration["Prop19"] is string value15 && !string.IsNullOrEmpty(value15)) { instance.Prop19 = ParseSystemDateTime(value15, configuration.GetSection("Prop19").Path); } @@ -213,7 +213,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop19 = instance.Prop19; } - if (configuration["Prop20"] is string value16) + if (configuration["Prop20"] is string value16 && !string.IsNullOrEmpty(value16)) { instance.Prop20 = ParseSystemDateTimeOffset(value16, configuration.GetSection("Prop20").Path); } @@ -222,7 +222,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop20 = instance.Prop20; } - if (configuration["Prop21"] is string value17) + if (configuration["Prop21"] is string value17 && !string.IsNullOrEmpty(value17)) { instance.Prop21 = ParseDecimal(value17, configuration.GetSection("Prop21").Path); } @@ -231,7 +231,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop21 = instance.Prop21; } - if (configuration["Prop23"] is string value18) + if (configuration["Prop23"] is string value18 && !string.IsNullOrEmpty(value18)) { instance.Prop23 = ParseSystemTimeSpan(value18, configuration.GetSection("Prop23").Path); } @@ -240,7 +240,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop23 = instance.Prop23; } - if (configuration["Prop24"] is string value19) + if (configuration["Prop24"] is string value19 && !string.IsNullOrEmpty(value19)) { instance.Prop24 = ParseSystemGuid(value19, configuration.GetSection("Prop24").Path); } @@ -249,7 +249,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop24 = instance.Prop24; } - if (configuration["Prop25"] is string value20) + if (configuration["Prop25"] is string value20 && !string.IsNullOrEmpty(value20)) { instance.Prop25 = ParseSystemUri(value20, configuration.GetSection("Prop25").Path); } @@ -262,7 +262,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["Prop26"] is string value21) + if (configuration["Prop26"] is string value21 && !string.IsNullOrEmpty(value21)) { instance.Prop26 = ParseSystemVersion(value21, configuration.GetSection("Prop26").Path); } @@ -275,7 +275,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["Prop27"] is string value22) + if (configuration["Prop27"] is string value22 && !string.IsNullOrEmpty(value22)) { instance.Prop27 = ParseEnum(value22, configuration.GetSection("Prop27").Path); } @@ -284,7 +284,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop27 = instance.Prop27; } - if (configuration["Prop7"] is string value23) + if (configuration["Prop7"] is string value23 && !string.IsNullOrEmpty(value23)) { instance.Prop7 = ParseSystemInt128(value23, configuration.GetSection("Prop7").Path); } @@ -293,7 +293,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop7 = instance.Prop7; } - if (configuration["Prop11"] is string value24) + if (configuration["Prop11"] is string value24 && !string.IsNullOrEmpty(value24)) { instance.Prop11 = ParseSystemHalf(value24, configuration.GetSection("Prop11").Path); } @@ -302,7 +302,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop11 = instance.Prop11; } - if (configuration["Prop12"] is string value25) + if (configuration["Prop12"] is string value25 && !string.IsNullOrEmpty(value25)) { instance.Prop12 = ParseSystemUInt128(value25, configuration.GetSection("Prop12").Path); } @@ -311,7 +311,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop12 = instance.Prop12; } - if (configuration["Prop18"] is string value26) + if (configuration["Prop18"] is string value26 && !string.IsNullOrEmpty(value26)) { instance.Prop18 = ParseSystemDateOnly(value26, configuration.GetSection("Prop18").Path); } @@ -320,7 +320,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop18 = instance.Prop18; } - if (configuration["Prop22"] is string value27) + if (configuration["Prop22"] is string value27 && !string.IsNullOrEmpty(value27)) { instance.Prop22 = ParseSystemTimeOnly(value27, configuration.GetSection("Prop22").Path); } @@ -329,7 +329,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop22 = instance.Prop22; } - if (configuration["Prop28"] is string value28) + if (configuration["Prop28"] is string value28 && !string.IsNullOrEmpty(value28)) { instance.Prop28 = ParseByteArray(value28, configuration.GetSection("Prop28").Path); } @@ -342,7 +342,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["Prop29"] is string value29) + if (configuration["Prop29"] is string value29 && !string.IsNullOrEmpty(value29)) { instance.Prop29 = ParseInt(value29, configuration.GetSection("Prop29").Path); } @@ -351,7 +351,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration instance.Prop29 = instance.Prop29; } - if (configuration["Prop30"] is string value30) + if (configuration["Prop30"] is string value30 && !string.IsNullOrEmpty(value30)) { instance.Prop30 = ParseSystemDateTime(value30, configuration.GetSection("Prop30").Path); } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/Version1/UnsupportedTypes.generated.txt b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/Version1/UnsupportedTypes.generated.txt index 0b119b30f4eb1..119788b084218 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/Version1/UnsupportedTypes.generated.txt +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/Baselines/netcoreapp/Version1/UnsupportedTypes.generated.txt @@ -137,7 +137,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration } } - if (configuration["Age"] is string value3) + if (configuration["Age"] is string value3 && !string.IsNullOrEmpty(value3)) { instance.Age = ParseInt(value3, configuration.GetSection("Age").Path); } @@ -186,7 +186,7 @@ namespace Microsoft.Extensions.Configuration.Binder.SourceGeneration public static global::Record InitializeRecordAction(IConfiguration configuration, BinderOptions? binderOptions) { int x = (int)(10); - if (configuration["x"] is string value13) + if (configuration["x"] is string value13 && !string.IsNullOrEmpty(value13)) { x = ParseInt(value13, configuration.GetSection("x").Path); } From 73229ad78184da1ee76e60e937651e4b8827f31c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Sep 2024 16:29:46 -0700 Subject: [PATCH 12/34] [release/9.0] Fix config source gen binding with SslClientAuthenticationOptions (#107705) * Fix config source gen binding with SslClientAuthenticationOptions * Apply suggestions from code review Co-authored-by: Eric Erhardt --------- Co-authored-by: Tarek Mahmoud Sayed Co-authored-by: Tarek Mahmoud Sayed <10833894+tarekgh@users.noreply.github.com> Co-authored-by: Eric Erhardt --- .../gen/Emitter/CoreBindingHelpers.cs | 9 +++++ .../SourceGenerationTests/GeneratorTests.cs | 33 +++++++++++++++++++ 2 files changed, 42 insertions(+) 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 fabdebd67eb4b..685850bb16e2a 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/CoreBindingHelpers.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/CoreBindingHelpers.cs @@ -901,6 +901,15 @@ private bool EmitBindImplForMember( } case ComplexTypeSpec complexType: { + // Early detection of types we cannot bind to and skip it. + if (!_typeIndex.HasBindableMembers(complexType) && + !_typeIndex.GetEffectiveTypeSpec(complexType).IsValueType && + complexType is not CollectionSpec && + ((ObjectSpec)complexType).InstantiationStrategy == ObjectInstantiationStrategy.ParameterizedConstructor) + { + return false; + } + string sectionValidationCall = $"{MethodsToGen_CoreBindingHelper.AsConfigWithChildren}({sectionParseExpr})"; string sectionIdentifier = GetIncrementalIdentifier(Identifier.section); 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 f4f9c906a9354..1442c623f3fa0 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/SourceGenerationTests/GeneratorTests.cs @@ -257,6 +257,39 @@ async Task Test(bool expectOutput) } } + /// + /// We binding the type "SslClientAuthenticationOptions" which has a property "CipherSuitesPolicy" of type "CipherSuitesPolicy". We can't bind this type. + /// This test is to ensure not including the property "CipherSuitesPolicy" in the generated code caused a build break. + /// + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNetCore))] + public async Task IgnoredUnBindablePropertiesTest() + { + string source = """ + using System; + using System.Net.Security; + using Microsoft.Extensions.Configuration; + using System.Collections.Immutable; + using System.Text; + using System.Text.Json; + + public class Program + { + public static void Main() + { + ConfigurationBuilder configurationBuilder = new(); + IConfiguration config = configurationBuilder.Build(); + + var obj = config.Get(); + } + } + """; + + ConfigBindingGenRunResult result = await RunGeneratorAndUpdateCompilation(source, assemblyReferences: GetAssemblyRefsWithAdditional(typeof(ImmutableArray<>), typeof(Encoding), typeof(JsonSerializer), typeof(System.Net.Security.AuthenticatedStream))); + Assert.NotNull(result.GeneratedSource); + + Assert.DoesNotContain("CipherSuitesPolicy = ", result.GeneratedSource.Value.SourceText.ToString()); + } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNetCore))] [ActiveIssue("Work out why we aren't getting all the expected diagnostics.")] public async Task IssueDiagnosticsForAllOffendingCallsites() From 24cd94cbfb5de3e3c8b5e4cda26785a58b783d89 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 12 Sep 2024 09:23:15 -0700 Subject: [PATCH 13/34] [release/9.0] [browser] Fix processing of satellite assemblies from referenced assembly during publish (#107398) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix related asset computation for satellites from reference (not projectReference) where ResolvedFrom contains {RawFileName} * WBT * Don't remove files with DestinationSubDirectory from ResolvedFileToPublish because they can be resource assemblies from References * Feedback * Fix condition * We can't check for RawFileName, because ProjectReference satellites goes through the same path and are not discovered by nested publish * Comment about "{RawFileName}" * Explicitly set ResolveAssemblyReferencesFindRelatedSatellites=true for nested publish --------- Co-authored-by: Marek Fišera Co-authored-by: Larry Ewing Co-authored-by: Jeff Schwartz --- .../TestAppScenarios/SatelliteLoadingTests.cs | 41 +++++++++++++++++++ src/mono/wasm/build/WasmApp.Common.targets | 2 +- .../App/SatelliteAssembliesTest.cs | 12 ++---- .../App/WasmBasicTestApp.csproj | 1 + .../WasmBasicTestApp/Library/Json.cs | 3 ++ .../ResourceLibrary/ResourceAccessor.cs | 19 +++++++++ .../ResourceLibrary/ResourceLibrary.csproj | 7 ++++ .../{App => ResourceLibrary}/words.es-ES.resx | 0 .../{App => ResourceLibrary}/words.resx | 0 .../ComputeWasmBuildAssets.cs | 7 +++- 10 files changed, 81 insertions(+), 11 deletions(-) create mode 100644 src/mono/wasm/testassets/WasmBasicTestApp/ResourceLibrary/ResourceAccessor.cs create mode 100644 src/mono/wasm/testassets/WasmBasicTestApp/ResourceLibrary/ResourceLibrary.csproj rename src/mono/wasm/testassets/WasmBasicTestApp/{App => ResourceLibrary}/words.es-ES.resx (100%) rename src/mono/wasm/testassets/WasmBasicTestApp/{App => ResourceLibrary}/words.resx (100%) diff --git a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/SatelliteLoadingTests.cs b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/SatelliteLoadingTests.cs index 5e15cc53841ad..3acee24e88536 100644 --- a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/SatelliteLoadingTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/SatelliteLoadingTests.cs @@ -11,6 +11,7 @@ using Microsoft.Playwright; using Xunit.Abstractions; using Xunit; +using System.Xml.Linq; #nullable enable @@ -38,4 +39,44 @@ public async Task LoadSatelliteAssembly() m => Assert.Equal("es-ES with satellite: hola", m) ); } + + [Fact] + public async Task LoadSatelliteAssemblyFromReference() + { + CopyTestAsset("WasmBasicTestApp", "SatelliteLoadingTestsFromReference", "App"); + + // Replace ProjectReference with Reference + var appCsprojPath = Path.Combine(_projectDir!, "WasmBasicTestApp.csproj"); + var appCsproj = XDocument.Load(appCsprojPath); + + var projectReference = appCsproj.Descendants("ProjectReference").Where(pr => pr.Attribute("Include")?.Value?.Contains("ResourceLibrary") ?? false).Single(); + var itemGroup = projectReference.Parent!; + projectReference.Remove(); + + var reference = new XElement("Reference"); + reference.SetAttributeValue("Include", "..\\ResourceLibrary\\bin\\Release\\net9.0\\ResourceLibrary.dll"); + itemGroup.Add(reference); + + appCsproj.Save(appCsprojPath); + + // Build the library + var libraryCsprojPath = Path.GetFullPath(Path.Combine(_projectDir!, "..", "ResourceLibrary")); + new DotNetCommand(s_buildEnv, _testOutput) + .WithWorkingDirectory(libraryCsprojPath) + .WithEnvironmentVariable("NUGET_PACKAGES", _nugetPackagesDir) + .ExecuteWithCapturedOutput("build -c Release") + .EnsureSuccessful(); + + // Publish the app and assert + PublishProject("Release"); + + var result = await RunSdkStyleAppForPublish(new(Configuration: "Release", TestScenario: "SatelliteAssembliesTest")); + Assert.Collection( + result.TestOutput, + m => Assert.Equal("default: hello", m), + m => Assert.Equal("es-ES without satellite: hello", m), + m => Assert.Equal("default: hello", m), + m => Assert.Equal("es-ES with satellite: hola", m) + ); + } } diff --git a/src/mono/wasm/build/WasmApp.Common.targets b/src/mono/wasm/build/WasmApp.Common.targets index 2641a239ac4e5..cee4e3c1bea03 100644 --- a/src/mono/wasm/build/WasmApp.Common.targets +++ b/src/mono/wasm/build/WasmApp.Common.targets @@ -442,7 +442,7 @@ + Properties="_WasmInNestedPublish_UniqueProperty_XYZ=true;;WasmBuildingForNestedPublish=true;DeployOnBuild=;_IsPublishing=;_WasmIsPublishing=$(_IsPublishing);ResolveAssemblyReferencesFindRelatedSatellites=true"> diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/App/SatelliteAssembliesTest.cs b/src/mono/wasm/testassets/WasmBasicTestApp/App/SatelliteAssembliesTest.cs index b8dc5b0dbf884..23f3df8098cc5 100644 --- a/src/mono/wasm/testassets/WasmBasicTestApp/App/SatelliteAssembliesTest.cs +++ b/src/mono/wasm/testassets/WasmBasicTestApp/App/SatelliteAssembliesTest.cs @@ -2,25 +2,19 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; -using System.Globalization; -using System.Threading.Tasks; -using System.Resources; using System.Runtime.InteropServices.JavaScript; +using System.Threading.Tasks; public partial class SatelliteAssembliesTest { [JSExport] public static async Task Run() { - var rm = new ResourceManager("WasmBasicTestApp.words", typeof(Program).Assembly); - TestOutput.WriteLine("default: " + rm.GetString("hello", CultureInfo.CurrentCulture)); - TestOutput.WriteLine("es-ES without satellite: " + rm.GetString("hello", new CultureInfo("es-ES"))); + ResourceLibrary.ResourceAccessor.Read(TestOutput.WriteLine, false); await LoadSatelliteAssemblies(new[] { "es-ES" }); - rm = new ResourceManager("WasmBasicTestApp.words", typeof(Program).Assembly); - TestOutput.WriteLine("default: " + rm.GetString("hello", CultureInfo.CurrentCulture)); - TestOutput.WriteLine("es-ES with satellite: " + rm.GetString("hello", new CultureInfo("es-ES"))); + ResourceLibrary.ResourceAccessor.Read(TestOutput.WriteLine, true); } [JSImport("INTERNAL.loadSatelliteAssemblies")] diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/App/WasmBasicTestApp.csproj b/src/mono/wasm/testassets/WasmBasicTestApp/App/WasmBasicTestApp.csproj index f93102b467a45..e16a8c4948ca5 100644 --- a/src/mono/wasm/testassets/WasmBasicTestApp/App/WasmBasicTestApp.csproj +++ b/src/mono/wasm/testassets/WasmBasicTestApp/App/WasmBasicTestApp.csproj @@ -16,6 +16,7 @@ + diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/Library/Json.cs b/src/mono/wasm/testassets/WasmBasicTestApp/Library/Json.cs index cd496b96a3fc9..d2cffde92c9e4 100644 --- a/src/mono/wasm/testassets/WasmBasicTestApp/Library/Json.cs +++ b/src/mono/wasm/testassets/WasmBasicTestApp/Library/Json.cs @@ -1,3 +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; using System.Text.Json.Serialization; diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/ResourceLibrary/ResourceAccessor.cs b/src/mono/wasm/testassets/WasmBasicTestApp/ResourceLibrary/ResourceAccessor.cs new file mode 100644 index 0000000000000..27073846c66ae --- /dev/null +++ b/src/mono/wasm/testassets/WasmBasicTestApp/ResourceLibrary/ResourceAccessor.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; +using System.Globalization; +using System.Threading.Tasks; +using System.Resources; + +namespace ResourceLibrary; + +public static class ResourceAccessor +{ + public static void Read(Action testOuput, bool hasSatellites) + { + var rm = new ResourceManager("ResourceLibrary.words", typeof(ResourceAccessor).Assembly); + testOuput($"default: {rm.GetString("hello", CultureInfo.CurrentCulture)}"); + testOuput($"es-ES {(hasSatellites ? "with" : "without")} satellite: {rm.GetString("hello", new CultureInfo("es-ES"))}"); + } +} diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/ResourceLibrary/ResourceLibrary.csproj b/src/mono/wasm/testassets/WasmBasicTestApp/ResourceLibrary/ResourceLibrary.csproj new file mode 100644 index 0000000000000..3d5e0e2093c1a --- /dev/null +++ b/src/mono/wasm/testassets/WasmBasicTestApp/ResourceLibrary/ResourceLibrary.csproj @@ -0,0 +1,7 @@ + + + net9.0 + Library + true + + diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/App/words.es-ES.resx b/src/mono/wasm/testassets/WasmBasicTestApp/ResourceLibrary/words.es-ES.resx similarity index 100% rename from src/mono/wasm/testassets/WasmBasicTestApp/App/words.es-ES.resx rename to src/mono/wasm/testassets/WasmBasicTestApp/ResourceLibrary/words.es-ES.resx diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/App/words.resx b/src/mono/wasm/testassets/WasmBasicTestApp/ResourceLibrary/words.resx similarity index 100% rename from src/mono/wasm/testassets/WasmBasicTestApp/App/words.resx rename to src/mono/wasm/testassets/WasmBasicTestApp/ResourceLibrary/words.resx diff --git a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmBuildAssets.cs b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmBuildAssets.cs index e8daa16e60813..cb070606f49c0 100644 --- a/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmBuildAssets.cs +++ b/src/tasks/Microsoft.NET.Sdk.WebAssembly.Pack.Tasks/ComputeWasmBuildAssets.cs @@ -110,7 +110,12 @@ public override bool Execute() assetCandidate.SetMetadata("AssetTraitName", "Culture"); assetCandidate.SetMetadata("AssetTraitValue", inferredCulture); assetCandidate.SetMetadata("RelativePath", $"_framework/{inferredCulture}/{satelliteAssembly.GetMetadata("FileName")}{satelliteAssembly.GetMetadata("Extension")}"); - assetCandidate.SetMetadata("RelatedAsset", Path.GetFullPath(Path.Combine(OutputPath, "wwwroot", "_framework", Path.GetFileName(assetCandidate.GetMetadata("ResolvedFrom"))))); + + var resolvedFrom = assetCandidate.GetMetadata("ResolvedFrom"); + if (resolvedFrom == "{RawFileName}") // Satellite assembly found from `` element + resolvedFrom = candidate.GetMetadata("OriginalItemSpec"); + + assetCandidate.SetMetadata("RelatedAsset", Path.GetFullPath(Path.Combine(OutputPath, "wwwroot", "_framework", Path.GetFileName(resolvedFrom)))); assetCandidates.Add(assetCandidate); continue; From c13aac859f7fbbcc3154e9018121af01e747f4d5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 12 Sep 2024 09:24:42 -0700 Subject: [PATCH 14/34] Fix passing assemblies using relative path (#107548) Co-authored-by: Jeremi Kurdek Co-authored-by: Jeff Schwartz --- src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs b/src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs index 1814cba54eb18..34cc69f775283 100644 --- a/src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs +++ b/src/tasks/MonoTargetsTasks/ILStrip/ILStrip.cs @@ -127,13 +127,14 @@ private bool StripAssembly(ITaskItem assemblyItem) try { - if(!AssemblyStripper.AssemblyStripper.TryStripAssembly(assemblyFile, outputPath)) + if (!AssemblyStripper.AssemblyStripper.TryStripAssembly(assemblyFile, outputPath)) { Log.LogMessage(MessageImportance.Low, $"[ILStrip] Skipping {assemblyFile} because it is not a managed assembly."); } else { - _processedAssemblies.GetOrAdd(assemblyItem.ItemSpec, GetTrimmedAssemblyItem(assemblyItem, outputPath, assemblyFile)); + var fullPath = assemblyItem.GetMetadata("FullPath"); + _processedAssemblies.GetOrAdd(fullPath, GetTrimmedAssemblyItem(assemblyItem, outputPath, assemblyFile)); } } catch (Exception ex) From 0db82190f9ecbb33a8d113237dfc4bb365d47e0d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 12 Sep 2024 09:28:18 -0700 Subject: [PATCH 15/34] [release/9.0] Add missing `[RequiresDynamicCode]` attributes to System.Linq.Expressions API in ref assembly (#107638) * dotnet build /t:GenerateReferenceAssemblySource * Revert unnecessary changes * Revert API changes * build ... /p:ApiCompatGenerateSuppressionFile=true * Update link * Resolve AOT warning in DependencyInjection ExpressionResolverBuilder Calling Expression.Lambda without a delegate type isn't AOT compatible. Fix this by passing the delegate type. --------- Co-authored-by: Charles Stoner <10732005+cston@users.noreply.github.com> Co-authored-by: Eric Erhardt Co-authored-by: Jeff Schwartz --- .../Expressions/ExpressionResolverBuilder.cs | 1 + .../ref/System.Linq.Expressions.cs | 61 +++- .../src/CompatibilitySuppressions.xml | 306 ------------------ 3 files changed, 57 insertions(+), 311 deletions(-) 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 670c62ee2f69a..dd6db1467ee7e 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/Expressions/ExpressionResolverBuilder.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceLookup/Expressions/ExpressionResolverBuilder.cs @@ -32,6 +32,7 @@ internal sealed class ExpressionResolverBuilder : CallSiteVisitor), Expression.Call(ScopeParameter, ServiceLookupHelpers.CaptureDisposableMethodInfo, CaptureDisposableParameter), CaptureDisposableParameter); 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 015cfb079d360..5282c94bcf44a 100644 --- a/src/libraries/System.Linq.Expressions/ref/System.Linq.Expressions.cs +++ b/src/libraries/System.Linq.Expressions/ref/System.Linq.Expressions.cs @@ -6,6 +6,7 @@ namespace System.Dynamic { + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Creating a call site may require dynamic code generation.")] public abstract partial class BinaryOperationBinder : System.Dynamic.DynamicMetaObjectBinder { protected BinaryOperationBinder(System.Linq.Expressions.ExpressionType operation) { } @@ -35,6 +36,7 @@ public CallInfo(int argCount, params string[] argNames) { } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhen(true)] object? obj) { throw null; } public override int GetHashCode() { throw null; } } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Creating a call site may require dynamic code generation.")] public abstract partial class ConvertBinder : System.Dynamic.DynamicMetaObjectBinder { protected ConvertBinder(System.Type type, bool @explicit) { } @@ -45,6 +47,7 @@ protected ConvertBinder(System.Type type, bool @explicit) { } public System.Dynamic.DynamicMetaObject FallbackConvert(System.Dynamic.DynamicMetaObject target) { throw null; } public abstract System.Dynamic.DynamicMetaObject FallbackConvert(System.Dynamic.DynamicMetaObject target, System.Dynamic.DynamicMetaObject? errorSuggestion); } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Creating a call site may require dynamic code generation.")] public abstract partial class CreateInstanceBinder : System.Dynamic.DynamicMetaObjectBinder { protected CreateInstanceBinder(System.Dynamic.CallInfo callInfo) { } @@ -54,6 +57,7 @@ protected CreateInstanceBinder(System.Dynamic.CallInfo callInfo) { } public System.Dynamic.DynamicMetaObject FallbackCreateInstance(System.Dynamic.DynamicMetaObject target, System.Dynamic.DynamicMetaObject[] args) { throw null; } public abstract System.Dynamic.DynamicMetaObject FallbackCreateInstance(System.Dynamic.DynamicMetaObject target, System.Dynamic.DynamicMetaObject[] args, System.Dynamic.DynamicMetaObject? errorSuggestion); } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Creating a call site may require dynamic code generation.")] public abstract partial class DeleteIndexBinder : System.Dynamic.DynamicMetaObjectBinder { protected DeleteIndexBinder(System.Dynamic.CallInfo callInfo) { } @@ -63,6 +67,7 @@ protected DeleteIndexBinder(System.Dynamic.CallInfo callInfo) { } public System.Dynamic.DynamicMetaObject FallbackDeleteIndex(System.Dynamic.DynamicMetaObject target, System.Dynamic.DynamicMetaObject[] indexes) { throw null; } public abstract System.Dynamic.DynamicMetaObject FallbackDeleteIndex(System.Dynamic.DynamicMetaObject target, System.Dynamic.DynamicMetaObject[] indexes, System.Dynamic.DynamicMetaObject? errorSuggestion); } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Creating a call site may require dynamic code generation.")] public abstract partial class DeleteMemberBinder : System.Dynamic.DynamicMetaObjectBinder { protected DeleteMemberBinder(string name, bool ignoreCase) { } @@ -99,6 +104,7 @@ public DynamicMetaObject(System.Linq.Expressions.Expression expression, System.D public static System.Dynamic.DynamicMetaObject Create(object value, System.Linq.Expressions.Expression expression) { throw null; } public virtual System.Collections.Generic.IEnumerable GetDynamicMemberNames() { throw null; } } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Creating a call site may require dynamic code generation.")] public abstract partial class DynamicMetaObjectBinder : System.Runtime.CompilerServices.CallSiteBinder { protected DynamicMetaObjectBinder() { } @@ -109,6 +115,7 @@ protected DynamicMetaObjectBinder() { } public System.Dynamic.DynamicMetaObject Defer(params System.Dynamic.DynamicMetaObject[] args) { throw null; } public System.Linq.Expressions.Expression GetUpdateExpression(System.Type type) { throw null; } } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Creating a call site may require dynamic code generation.")] public partial class DynamicObject : System.Dynamic.IDynamicMetaObjectProvider { protected DynamicObject() { } @@ -149,6 +156,7 @@ event System.ComponentModel.PropertyChangedEventHandler? System.ComponentModel.I System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } System.Dynamic.DynamicMetaObject System.Dynamic.IDynamicMetaObjectProvider.GetMetaObject(System.Linq.Expressions.Expression parameter) { throw null; } } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Creating a call site may require dynamic code generation.")] public abstract partial class GetIndexBinder : System.Dynamic.DynamicMetaObjectBinder { protected GetIndexBinder(System.Dynamic.CallInfo callInfo) { } @@ -158,6 +166,7 @@ protected GetIndexBinder(System.Dynamic.CallInfo callInfo) { } public System.Dynamic.DynamicMetaObject FallbackGetIndex(System.Dynamic.DynamicMetaObject target, System.Dynamic.DynamicMetaObject[] indexes) { throw null; } public abstract System.Dynamic.DynamicMetaObject FallbackGetIndex(System.Dynamic.DynamicMetaObject target, System.Dynamic.DynamicMetaObject[] indexes, System.Dynamic.DynamicMetaObject? errorSuggestion); } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Creating a call site may require dynamic code generation.")] public abstract partial class GetMemberBinder : System.Dynamic.DynamicMetaObjectBinder { protected GetMemberBinder(string name, bool ignoreCase) { } @@ -176,6 +185,7 @@ public partial interface IInvokeOnGetBinder { bool InvokeOnGet { get; } } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Creating a call site may require dynamic code generation.")] public abstract partial class InvokeBinder : System.Dynamic.DynamicMetaObjectBinder { protected InvokeBinder(System.Dynamic.CallInfo callInfo) { } @@ -185,6 +195,7 @@ protected InvokeBinder(System.Dynamic.CallInfo callInfo) { } public System.Dynamic.DynamicMetaObject FallbackInvoke(System.Dynamic.DynamicMetaObject target, System.Dynamic.DynamicMetaObject[] args) { throw null; } public abstract System.Dynamic.DynamicMetaObject FallbackInvoke(System.Dynamic.DynamicMetaObject target, System.Dynamic.DynamicMetaObject[] args, System.Dynamic.DynamicMetaObject? errorSuggestion); } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Creating a call site may require dynamic code generation.")] public abstract partial class InvokeMemberBinder : System.Dynamic.DynamicMetaObjectBinder { protected InvokeMemberBinder(string name, bool ignoreCase, System.Dynamic.CallInfo callInfo) { } @@ -197,6 +208,7 @@ protected InvokeMemberBinder(string name, bool ignoreCase, System.Dynamic.CallIn public System.Dynamic.DynamicMetaObject FallbackInvokeMember(System.Dynamic.DynamicMetaObject target, System.Dynamic.DynamicMetaObject[] args) { throw null; } public abstract System.Dynamic.DynamicMetaObject FallbackInvokeMember(System.Dynamic.DynamicMetaObject target, System.Dynamic.DynamicMetaObject[] args, System.Dynamic.DynamicMetaObject? errorSuggestion); } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Creating a call site may require dynamic code generation.")] public abstract partial class SetIndexBinder : System.Dynamic.DynamicMetaObjectBinder { protected SetIndexBinder(System.Dynamic.CallInfo callInfo) { } @@ -206,6 +218,7 @@ protected SetIndexBinder(System.Dynamic.CallInfo callInfo) { } public System.Dynamic.DynamicMetaObject FallbackSetIndex(System.Dynamic.DynamicMetaObject target, System.Dynamic.DynamicMetaObject[] indexes, System.Dynamic.DynamicMetaObject value) { throw null; } public abstract System.Dynamic.DynamicMetaObject FallbackSetIndex(System.Dynamic.DynamicMetaObject target, System.Dynamic.DynamicMetaObject[] indexes, System.Dynamic.DynamicMetaObject value, System.Dynamic.DynamicMetaObject? errorSuggestion); } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Creating a call site may require dynamic code generation.")] public abstract partial class SetMemberBinder : System.Dynamic.DynamicMetaObjectBinder { protected SetMemberBinder(string name, bool ignoreCase) { } @@ -216,6 +229,7 @@ protected SetMemberBinder(string name, bool ignoreCase) { } public System.Dynamic.DynamicMetaObject FallbackSetMember(System.Dynamic.DynamicMetaObject target, System.Dynamic.DynamicMetaObject value) { throw null; } public abstract System.Dynamic.DynamicMetaObject FallbackSetMember(System.Dynamic.DynamicMetaObject target, System.Dynamic.DynamicMetaObject value, System.Dynamic.DynamicMetaObject? errorSuggestion); } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Creating a call site may require dynamic code generation.")] public abstract partial class UnaryOperationBinder : System.Dynamic.DynamicMetaObjectBinder { protected UnaryOperationBinder(System.Linq.Expressions.ExpressionType operation) { } @@ -337,12 +351,19 @@ internal DynamicExpression() { } int System.Linq.Expressions.IArgumentProvider.ArgumentCount { get { throw null; } } public override System.Type Type { get { throw null; } } protected internal override System.Linq.Expressions.Expression Accept(System.Linq.Expressions.ExpressionVisitor visitor) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static new System.Linq.Expressions.DynamicExpression Dynamic(System.Runtime.CompilerServices.CallSiteBinder binder, System.Type returnType, System.Collections.Generic.IEnumerable arguments) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static new System.Linq.Expressions.DynamicExpression Dynamic(System.Runtime.CompilerServices.CallSiteBinder binder, System.Type returnType, System.Linq.Expressions.Expression arg0) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static new System.Linq.Expressions.DynamicExpression Dynamic(System.Runtime.CompilerServices.CallSiteBinder binder, System.Type returnType, System.Linq.Expressions.Expression arg0, System.Linq.Expressions.Expression arg1) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static new System.Linq.Expressions.DynamicExpression Dynamic(System.Runtime.CompilerServices.CallSiteBinder binder, System.Type returnType, System.Linq.Expressions.Expression arg0, System.Linq.Expressions.Expression arg1, System.Linq.Expressions.Expression arg2) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static new System.Linq.Expressions.DynamicExpression Dynamic(System.Runtime.CompilerServices.CallSiteBinder binder, System.Type returnType, System.Linq.Expressions.Expression arg0, System.Linq.Expressions.Expression arg1, System.Linq.Expressions.Expression arg2, System.Linq.Expressions.Expression arg3) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static new System.Linq.Expressions.DynamicExpression Dynamic(System.Runtime.CompilerServices.CallSiteBinder binder, System.Type returnType, params System.Linq.Expressions.Expression[] arguments) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static new System.Linq.Expressions.DynamicExpression MakeDynamic(System.Type delegateType, System.Runtime.CompilerServices.CallSiteBinder binder, System.Collections.Generic.IEnumerable? arguments) { throw null; } public static new System.Linq.Expressions.DynamicExpression MakeDynamic(System.Type delegateType, System.Runtime.CompilerServices.CallSiteBinder binder, System.Linq.Expressions.Expression arg0) { throw null; } public static new System.Linq.Expressions.DynamicExpression MakeDynamic(System.Type delegateType, System.Runtime.CompilerServices.CallSiteBinder binder, System.Linq.Expressions.Expression arg0, System.Linq.Expressions.Expression arg1) { throw null; } @@ -426,6 +447,7 @@ protected Expression(System.Linq.Expressions.ExpressionType nodeType, System.Typ public static System.Linq.Expressions.MethodCallExpression Call(System.Linq.Expressions.Expression? instance, System.Reflection.MethodInfo method, System.Linq.Expressions.Expression arg0, System.Linq.Expressions.Expression arg1) { throw null; } public static System.Linq.Expressions.MethodCallExpression Call(System.Linq.Expressions.Expression? instance, System.Reflection.MethodInfo method, System.Linq.Expressions.Expression arg0, System.Linq.Expressions.Expression arg1, System.Linq.Expressions.Expression arg2) { throw null; } public static System.Linq.Expressions.MethodCallExpression Call(System.Linq.Expressions.Expression? instance, System.Reflection.MethodInfo method, params System.Linq.Expressions.Expression[]? arguments) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Calling a generic method requires dynamic code generation. This can be suppressed if the method is not generic.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Creating Expressions requires unreferenced code because the members being referenced by the Expression may be trimmed.")] public static System.Linq.Expressions.MethodCallExpression Call(System.Linq.Expressions.Expression instance, string methodName, System.Type[]? typeArguments, params System.Linq.Expressions.Expression[]? arguments) { throw null; } public static System.Linq.Expressions.MethodCallExpression Call(System.Reflection.MethodInfo method, System.Collections.Generic.IEnumerable? arguments) { throw null; } @@ -435,6 +457,7 @@ protected Expression(System.Linq.Expressions.ExpressionType nodeType, System.Typ public static System.Linq.Expressions.MethodCallExpression Call(System.Reflection.MethodInfo method, System.Linq.Expressions.Expression arg0, System.Linq.Expressions.Expression arg1, System.Linq.Expressions.Expression arg2, System.Linq.Expressions.Expression arg3) { throw null; } public static System.Linq.Expressions.MethodCallExpression Call(System.Reflection.MethodInfo method, System.Linq.Expressions.Expression arg0, System.Linq.Expressions.Expression arg1, System.Linq.Expressions.Expression arg2, System.Linq.Expressions.Expression arg3, System.Linq.Expressions.Expression arg4) { throw null; } public static System.Linq.Expressions.MethodCallExpression Call(System.Reflection.MethodInfo method, params System.Linq.Expressions.Expression[]? arguments) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Calling a generic method requires dynamic code generation. This can be suppressed if the method is not generic.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Calling a generic method cannot be statically analyzed. It's not possible to guarantee the availability of requirements of the generic method. This can be suppressed if the method is not generic.")] public static System.Linq.Expressions.MethodCallExpression Call([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicMethods | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] System.Type type, string methodName, System.Type[]? typeArguments, params System.Linq.Expressions.Expression[]? arguments) { throw null; } public static System.Linq.Expressions.CatchBlock Catch(System.Linq.Expressions.ParameterExpression variable, System.Linq.Expressions.Expression body) { throw null; } @@ -463,11 +486,17 @@ protected Expression(System.Linq.Expressions.ExpressionType nodeType, System.Typ public static System.Linq.Expressions.BinaryExpression DivideAssign(System.Linq.Expressions.Expression left, System.Linq.Expressions.Expression right) { throw null; } public static System.Linq.Expressions.BinaryExpression DivideAssign(System.Linq.Expressions.Expression left, System.Linq.Expressions.Expression right, System.Reflection.MethodInfo? method) { throw null; } public static System.Linq.Expressions.BinaryExpression DivideAssign(System.Linq.Expressions.Expression left, System.Linq.Expressions.Expression right, System.Reflection.MethodInfo? method, System.Linq.Expressions.LambdaExpression? conversion) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static System.Linq.Expressions.DynamicExpression Dynamic(System.Runtime.CompilerServices.CallSiteBinder binder, System.Type returnType, System.Collections.Generic.IEnumerable arguments) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static System.Linq.Expressions.DynamicExpression Dynamic(System.Runtime.CompilerServices.CallSiteBinder binder, System.Type returnType, System.Linq.Expressions.Expression arg0) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static System.Linq.Expressions.DynamicExpression Dynamic(System.Runtime.CompilerServices.CallSiteBinder binder, System.Type returnType, System.Linq.Expressions.Expression arg0, System.Linq.Expressions.Expression arg1) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static System.Linq.Expressions.DynamicExpression Dynamic(System.Runtime.CompilerServices.CallSiteBinder binder, System.Type returnType, System.Linq.Expressions.Expression arg0, System.Linq.Expressions.Expression arg1, System.Linq.Expressions.Expression arg2) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static System.Linq.Expressions.DynamicExpression Dynamic(System.Runtime.CompilerServices.CallSiteBinder binder, System.Type returnType, System.Linq.Expressions.Expression arg0, System.Linq.Expressions.Expression arg1, System.Linq.Expressions.Expression arg2, System.Linq.Expressions.Expression arg3) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static System.Linq.Expressions.DynamicExpression Dynamic(System.Runtime.CompilerServices.CallSiteBinder binder, System.Type returnType, params System.Linq.Expressions.Expression[] arguments) { throw null; } public static System.Linq.Expressions.ElementInit ElementInit(System.Reflection.MethodInfo addMethod, System.Collections.Generic.IEnumerable arguments) { throw null; } public static System.Linq.Expressions.ElementInit ElementInit(System.Reflection.MethodInfo addMethod, params System.Linq.Expressions.Expression[] arguments) { throw null; } @@ -483,8 +512,11 @@ protected Expression(System.Linq.Expressions.ExpressionType nodeType, System.Typ [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Creating Expressions requires unreferenced code because the members being referenced by the Expression may be trimmed.")] public static System.Linq.Expressions.MemberExpression Field(System.Linq.Expressions.Expression expression, string fieldName) { throw null; } public static System.Linq.Expressions.MemberExpression Field(System.Linq.Expressions.Expression? expression, [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields)] System.Type type, string fieldName) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static System.Type GetActionType(params System.Type[]? typeArgs) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static System.Type GetDelegateType(params System.Type[] typeArgs) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static System.Type GetFuncType(params System.Type[]? typeArgs) { throw null; } public static System.Linq.Expressions.GotoExpression Goto(System.Linq.Expressions.LabelTarget target) { throw null; } public static System.Linq.Expressions.GotoExpression Goto(System.Linq.Expressions.LabelTarget target, System.Linq.Expressions.Expression? value) { throw null; } @@ -510,11 +542,17 @@ protected Expression(System.Linq.Expressions.ExpressionType nodeType, System.Typ public static System.Linq.Expressions.LabelTarget Label(string? name) { throw null; } public static System.Linq.Expressions.LabelTarget Label(System.Type type) { throw null; } public static System.Linq.Expressions.LabelTarget Label(System.Type type, string? name) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static System.Linq.Expressions.LambdaExpression Lambda(System.Linq.Expressions.Expression body, bool tailCall, System.Collections.Generic.IEnumerable? parameters) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static System.Linq.Expressions.LambdaExpression Lambda(System.Linq.Expressions.Expression body, bool tailCall, params System.Linq.Expressions.ParameterExpression[]? parameters) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static System.Linq.Expressions.LambdaExpression Lambda(System.Linq.Expressions.Expression body, System.Collections.Generic.IEnumerable? parameters) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static System.Linq.Expressions.LambdaExpression Lambda(System.Linq.Expressions.Expression body, params System.Linq.Expressions.ParameterExpression[]? parameters) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static System.Linq.Expressions.LambdaExpression Lambda(System.Linq.Expressions.Expression body, string? name, bool tailCall, System.Collections.Generic.IEnumerable? parameters) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static System.Linq.Expressions.LambdaExpression Lambda(System.Linq.Expressions.Expression body, string? name, System.Collections.Generic.IEnumerable? parameters) { throw null; } public static System.Linq.Expressions.LambdaExpression Lambda(System.Type delegateType, System.Linq.Expressions.Expression body, bool tailCall, System.Collections.Generic.IEnumerable? parameters) { throw null; } public static System.Linq.Expressions.LambdaExpression Lambda(System.Type delegateType, System.Linq.Expressions.Expression body, bool tailCall, params System.Linq.Expressions.ParameterExpression[]? parameters) { throw null; } @@ -544,13 +582,17 @@ protected Expression(System.Linq.Expressions.ExpressionType nodeType, System.Typ [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The Property metadata or other accessor may be trimmed.")] public static System.Linq.Expressions.MemberListBinding ListBind(System.Reflection.MethodInfo propertyAccessor, params System.Linq.Expressions.ElementInit[] initializers) { throw null; } public static System.Linq.Expressions.ListInitExpression ListInit(System.Linq.Expressions.NewExpression newExpression, System.Collections.Generic.IEnumerable initializers) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Calling a generic method requires dynamic code generation. This can be suppressed if the method is not generic.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Creating Expressions requires unreferenced code because the members being referenced by the Expression may be trimmed.")] public static System.Linq.Expressions.ListInitExpression ListInit(System.Linq.Expressions.NewExpression newExpression, System.Collections.Generic.IEnumerable initializers) { throw null; } public static System.Linq.Expressions.ListInitExpression ListInit(System.Linq.Expressions.NewExpression newExpression, params System.Linq.Expressions.ElementInit[] initializers) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Calling a generic method requires dynamic code generation. This can be suppressed if the method is not generic.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Creating Expressions requires unreferenced code because the members being referenced by the Expression may be trimmed.")] public static System.Linq.Expressions.ListInitExpression ListInit(System.Linq.Expressions.NewExpression newExpression, params System.Linq.Expressions.Expression[] initializers) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Calling a generic method requires dynamic code generation. This can be suppressed if the method is not generic.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Creating Expressions requires unreferenced code because the members being referenced by the Expression may be trimmed.")] public static System.Linq.Expressions.ListInitExpression ListInit(System.Linq.Expressions.NewExpression newExpression, System.Reflection.MethodInfo? addMethod, System.Collections.Generic.IEnumerable initializers) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Calling a generic method requires dynamic code generation. This can be suppressed if the method is not generic.")] [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Creating Expressions requires unreferenced code because the members being referenced by the Expression may be trimmed.")] public static System.Linq.Expressions.ListInitExpression ListInit(System.Linq.Expressions.NewExpression newExpression, System.Reflection.MethodInfo? addMethod, params System.Linq.Expressions.Expression[] initializers) { throw null; } public static System.Linq.Expressions.LoopExpression Loop(System.Linq.Expressions.Expression body) { throw null; } @@ -560,11 +602,17 @@ protected Expression(System.Linq.Expressions.ExpressionType nodeType, System.Typ public static System.Linq.Expressions.BinaryExpression MakeBinary(System.Linq.Expressions.ExpressionType binaryType, System.Linq.Expressions.Expression left, System.Linq.Expressions.Expression right, bool liftToNull, System.Reflection.MethodInfo? method) { throw null; } public static System.Linq.Expressions.BinaryExpression MakeBinary(System.Linq.Expressions.ExpressionType binaryType, System.Linq.Expressions.Expression left, System.Linq.Expressions.Expression right, bool liftToNull, System.Reflection.MethodInfo? method, System.Linq.Expressions.LambdaExpression? conversion) { throw null; } public static System.Linq.Expressions.CatchBlock MakeCatchBlock(System.Type type, System.Linq.Expressions.ParameterExpression? variable, System.Linq.Expressions.Expression body, System.Linq.Expressions.Expression? filter) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static System.Linq.Expressions.DynamicExpression MakeDynamic(System.Type delegateType, System.Runtime.CompilerServices.CallSiteBinder binder, System.Collections.Generic.IEnumerable? arguments) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static System.Linq.Expressions.DynamicExpression MakeDynamic(System.Type delegateType, System.Runtime.CompilerServices.CallSiteBinder binder, System.Linq.Expressions.Expression arg0) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static System.Linq.Expressions.DynamicExpression MakeDynamic(System.Type delegateType, System.Runtime.CompilerServices.CallSiteBinder binder, System.Linq.Expressions.Expression arg0, System.Linq.Expressions.Expression arg1) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static System.Linq.Expressions.DynamicExpression MakeDynamic(System.Type delegateType, System.Runtime.CompilerServices.CallSiteBinder binder, System.Linq.Expressions.Expression arg0, System.Linq.Expressions.Expression arg1, System.Linq.Expressions.Expression arg2) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static System.Linq.Expressions.DynamicExpression MakeDynamic(System.Type delegateType, System.Runtime.CompilerServices.CallSiteBinder binder, System.Linq.Expressions.Expression arg0, System.Linq.Expressions.Expression arg1, System.Linq.Expressions.Expression arg2, System.Linq.Expressions.Expression arg3) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static System.Linq.Expressions.DynamicExpression MakeDynamic(System.Type delegateType, System.Runtime.CompilerServices.CallSiteBinder binder, params System.Linq.Expressions.Expression[]? arguments) { throw null; } public static System.Linq.Expressions.GotoExpression MakeGoto(System.Linq.Expressions.GotoExpressionKind kind, System.Linq.Expressions.LabelTarget target, System.Linq.Expressions.Expression? value, System.Type type) { throw null; } public static System.Linq.Expressions.IndexExpression MakeIndex(System.Linq.Expressions.Expression instance, System.Reflection.PropertyInfo? indexer, System.Collections.Generic.IEnumerable? arguments) { throw null; } @@ -607,13 +655,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.")] + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("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.")] + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("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.")] + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("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.")] + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("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; } @@ -703,7 +751,9 @@ protected Expression(System.Linq.Expressions.ExpressionType nodeType, System.Typ public static System.Linq.Expressions.TryExpression TryCatchFinally(System.Linq.Expressions.Expression body, System.Linq.Expressions.Expression? @finally, params System.Linq.Expressions.CatchBlock[]? handlers) { throw null; } public static System.Linq.Expressions.TryExpression TryFault(System.Linq.Expressions.Expression body, System.Linq.Expressions.Expression? fault) { throw null; } public static System.Linq.Expressions.TryExpression TryFinally(System.Linq.Expressions.Expression body, System.Linq.Expressions.Expression? @finally) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static bool TryGetActionType(System.Type[] typeArgs, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Type? actionType) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Delegate creation requires dynamic code generation.")] public static bool TryGetFuncType(System.Type[] typeArgs, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Type? funcType) { throw null; } public static System.Linq.Expressions.UnaryExpression TypeAs(System.Linq.Expressions.Expression expression, System.Type type) { throw null; } public static System.Linq.Expressions.TypeBinaryExpression TypeEqual(System.Linq.Expressions.Expression expression, System.Type type) { throw null; } @@ -1032,7 +1082,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.")] + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Creating arrays at runtime requires dynamic code generation.")] public partial class NewArrayExpression : System.Linq.Expressions.Expression { internal NewArrayExpression() { } @@ -1162,6 +1212,7 @@ public partial class CallSite : System.Runtime.CompilerServices.CallSite wher internal CallSite() { } public T Target; public T Update { get { throw null; } } + [System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute("Creating arrays at runtime requires dynamic code generation.")] public static System.Runtime.CompilerServices.CallSite Create(System.Runtime.CompilerServices.CallSiteBinder binder) { throw null; } } public abstract partial class DebugInfoGenerator diff --git a/src/libraries/System.Linq.Expressions/src/CompatibilitySuppressions.xml b/src/libraries/System.Linq.Expressions/src/CompatibilitySuppressions.xml index 2524d0e9645e5..d43c6bf4e772b 100644 --- a/src/libraries/System.Linq.Expressions/src/CompatibilitySuppressions.xml +++ b/src/libraries/System.Linq.Expressions/src/CompatibilitySuppressions.xml @@ -97,312 +97,6 @@ ref/net9.0/System.Linq.Expressions.dll lib/net9.0/System.Linq.Expressions.dll - - CP0016 - M:System.Linq.Expressions.DynamicExpression.Dynamic(System.Runtime.CompilerServices.CallSiteBinder,System.Type,System.Collections.Generic.IEnumerable{System.Linq.Expressions.Expression}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.DynamicExpression.Dynamic(System.Runtime.CompilerServices.CallSiteBinder,System.Type,System.Linq.Expressions.Expression,System.Linq.Expressions.Expression,System.Linq.Expressions.Expression,System.Linq.Expressions.Expression):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.DynamicExpression.Dynamic(System.Runtime.CompilerServices.CallSiteBinder,System.Type,System.Linq.Expressions.Expression,System.Linq.Expressions.Expression,System.Linq.Expressions.Expression):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.DynamicExpression.Dynamic(System.Runtime.CompilerServices.CallSiteBinder,System.Type,System.Linq.Expressions.Expression,System.Linq.Expressions.Expression):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.DynamicExpression.Dynamic(System.Runtime.CompilerServices.CallSiteBinder,System.Type,System.Linq.Expressions.Expression):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.DynamicExpression.Dynamic(System.Runtime.CompilerServices.CallSiteBinder,System.Type,System.Linq.Expressions.Expression[]):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.DynamicExpression.MakeDynamic(System.Type,System.Runtime.CompilerServices.CallSiteBinder,System.Collections.Generic.IEnumerable{System.Linq.Expressions.Expression}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.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/net9.0/System.Linq.Expressions.dll - lib/net9.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/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.Expression.Dynamic(System.Runtime.CompilerServices.CallSiteBinder,System.Type,System.Collections.Generic.IEnumerable{System.Linq.Expressions.Expression}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.Expression.Dynamic(System.Runtime.CompilerServices.CallSiteBinder,System.Type,System.Linq.Expressions.Expression,System.Linq.Expressions.Expression,System.Linq.Expressions.Expression,System.Linq.Expressions.Expression):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.Expression.Dynamic(System.Runtime.CompilerServices.CallSiteBinder,System.Type,System.Linq.Expressions.Expression,System.Linq.Expressions.Expression,System.Linq.Expressions.Expression):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.Expression.Dynamic(System.Runtime.CompilerServices.CallSiteBinder,System.Type,System.Linq.Expressions.Expression,System.Linq.Expressions.Expression):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.Expression.Dynamic(System.Runtime.CompilerServices.CallSiteBinder,System.Type,System.Linq.Expressions.Expression):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.Expression.Dynamic(System.Runtime.CompilerServices.CallSiteBinder,System.Type,System.Linq.Expressions.Expression[]):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.Expression.GetActionType(System.Type[]):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.Expression.GetDelegateType(System.Type[]):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.Expression.GetFuncType(System.Type[]):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.Expression.Lambda(System.Linq.Expressions.Expression,System.Boolean,System.Collections.Generic.IEnumerable{System.Linq.Expressions.ParameterExpression}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.Expression.Lambda(System.Linq.Expressions.Expression,System.Boolean,System.Linq.Expressions.ParameterExpression[]):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.Expression.Lambda(System.Linq.Expressions.Expression,System.Collections.Generic.IEnumerable{System.Linq.Expressions.ParameterExpression}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.Expression.Lambda(System.Linq.Expressions.Expression,System.Linq.Expressions.ParameterExpression[]):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.Expression.Lambda(System.Linq.Expressions.Expression,System.String,System.Boolean,System.Collections.Generic.IEnumerable{System.Linq.Expressions.ParameterExpression}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.Expression.Lambda(System.Linq.Expressions.Expression,System.String,System.Collections.Generic.IEnumerable{System.Linq.Expressions.ParameterExpression}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.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/net9.0/System.Linq.Expressions.dll - lib/net9.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/net9.0/System.Linq.Expressions.dll - lib/net9.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/net9.0/System.Linq.Expressions.dll - lib/net9.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/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.Expression.MakeDynamic(System.Type,System.Runtime.CompilerServices.CallSiteBinder,System.Collections.Generic.IEnumerable{System.Linq.Expressions.Expression}):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.Expression.MakeDynamic(System.Type,System.Runtime.CompilerServices.CallSiteBinder,System.Linq.Expressions.Expression,System.Linq.Expressions.Expression,System.Linq.Expressions.Expression,System.Linq.Expressions.Expression):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.Expression.MakeDynamic(System.Type,System.Runtime.CompilerServices.CallSiteBinder,System.Linq.Expressions.Expression,System.Linq.Expressions.Expression,System.Linq.Expressions.Expression):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.Expression.MakeDynamic(System.Type,System.Runtime.CompilerServices.CallSiteBinder,System.Linq.Expressions.Expression,System.Linq.Expressions.Expression):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.Expression.MakeDynamic(System.Type,System.Runtime.CompilerServices.CallSiteBinder,System.Linq.Expressions.Expression):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.Expression.MakeDynamic(System.Type,System.Runtime.CompilerServices.CallSiteBinder,System.Linq.Expressions.Expression[]):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.Expression.TryGetActionType(System.Type[],System.Type@):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Linq.Expressions.Expression.TryGetFuncType(System.Type[],System.Type@):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - M:System.Runtime.CompilerServices.CallSite`1.Create(System.Runtime.CompilerServices.CallSiteBinder):[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - T:System.Dynamic.BinaryOperationBinder:[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - T:System.Dynamic.ConvertBinder:[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - T:System.Dynamic.CreateInstanceBinder:[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - T:System.Dynamic.DeleteIndexBinder:[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - T:System.Dynamic.DeleteMemberBinder:[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - T:System.Dynamic.DynamicMetaObjectBinder:[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - T:System.Dynamic.DynamicObject:[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - T:System.Dynamic.GetIndexBinder:[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - T:System.Dynamic.GetMemberBinder:[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - T:System.Dynamic.InvokeBinder:[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - T:System.Dynamic.InvokeMemberBinder:[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - T:System.Dynamic.SetIndexBinder:[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - T:System.Dynamic.SetMemberBinder:[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - - - CP0016 - T:System.Dynamic.UnaryOperationBinder:[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute] - ref/net9.0/System.Linq.Expressions.dll - lib/net9.0/System.Linq.Expressions.dll - CP0020 M:System.Linq.Expressions.DynamicExpressionVisitor.#ctor From 165f846974711c2691b0f05085cd85a134a0209a Mon Sep 17 00:00:00 2001 From: Aman Khalid Date: Thu, 12 Sep 2024 16:29:12 +0000 Subject: [PATCH 16/34] Backport #107207 (#107722) Co-authored-by: SwapnilGaikwad Co-authored-by: Jeff Schwartz --- src/coreclr/jit/hwintrinsic.h | 9 ++ src/coreclr/jit/hwintrinsiclistarm64sve.h | 18 +-- src/coreclr/jit/lowerarmarch.cpp | 5 +- .../GenerateHWIntrinsicTests_Arm.cs | 63 ++++++++- .../_SveMinimalUnaryOpTestTemplate.template | 129 ++++++++++++++++++ .../JitBlue/Runtime_106868/Runtime_106868.cs | 57 ++++++++ .../Runtime_106868/Runtime_106868.csproj | 9 ++ .../JitBlue/Runtime_106871/Runtime_106871.cs | 41 ++++++ .../Runtime_106871/Runtime_106871.csproj | 9 ++ .../JitBlue/Runtime_106872/Runtime_106872.cs | 46 +++++++ .../Runtime_106872/Runtime_106872.csproj | 9 ++ 11 files changed, 383 insertions(+), 12 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.csproj create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.csproj create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.csproj diff --git a/src/coreclr/jit/hwintrinsic.h b/src/coreclr/jit/hwintrinsic.h index 8ee5b656e9d20..597f56a363d1f 100644 --- a/src/coreclr/jit/hwintrinsic.h +++ b/src/coreclr/jit/hwintrinsic.h @@ -250,6 +250,9 @@ enum HWIntrinsicFlag : unsigned int // (HW_Flag_BaseTypeFrom{First, Second}Arg must also be set to denote the position of the ValueTuple) HW_Flag_BaseTypeFromValueTupleArg = 0x10000000, + // The intrinsic is a reduce operation. + HW_Flag_ReduceOperation = 0x20000000, + #endif // TARGET_XARCH // The intrinsic is a FusedMultiplyAdd intrinsic @@ -1011,6 +1014,12 @@ struct HWIntrinsicInfo return (flags & HW_Flag_BaseTypeFromValueTupleArg) != 0; } + static bool IsReduceOperation(NamedIntrinsic id) + { + const HWIntrinsicFlag flags = lookupFlags(id); + return (flags & HW_Flag_ReduceOperation) != 0; + } + static NamedIntrinsic GetScalarInputVariant(NamedIntrinsic id) { assert(HasScalarInputVariant(id)); diff --git a/src/coreclr/jit/hwintrinsiclistarm64sve.h b/src/coreclr/jit/hwintrinsiclistarm64sve.h index b8898288f72fb..73eb98f27cc22 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64sve.h +++ b/src/coreclr/jit/hwintrinsiclistarm64sve.h @@ -23,12 +23,12 @@ HARDWARE_INTRINSIC(Sve, AbsoluteCompareLessThan, HARDWARE_INTRINSIC(Sve, AbsoluteCompareLessThanOrEqual, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_facle, INS_sve_facle}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ReturnsPerElementMask|HW_Flag_ZeroingMaskedOperation) HARDWARE_INTRINSIC(Sve, AbsoluteDifference, -1, -1, {INS_sve_sabd, INS_sve_uabd, INS_sve_sabd, INS_sve_uabd, INS_sve_sabd, INS_sve_uabd, INS_sve_sabd, INS_sve_uabd, INS_sve_fabd, INS_sve_fabd}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, Add, -1, -1, {INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_fadd, INS_sve_fadd}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) -HARDWARE_INTRINSIC(Sve, AddAcross, -1, 1, {INS_sve_saddv, INS_sve_uaddv, INS_sve_saddv, INS_sve_uaddv, INS_sve_saddv, INS_sve_uaddv, INS_sve_uaddv, INS_sve_uaddv, INS_sve_faddv, INS_sve_faddv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, AddAcross, -1, 1, {INS_sve_saddv, INS_sve_uaddv, INS_sve_saddv, INS_sve_uaddv, INS_sve_saddv, INS_sve_uaddv, INS_sve_uaddv, INS_sve_uaddv, INS_sve_faddv, INS_sve_faddv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ReduceOperation) HARDWARE_INTRINSIC(Sve, AddRotateComplex, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fcadd, INS_sve_fcadd}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand) HARDWARE_INTRINSIC(Sve, AddSaturate, -1, 2, {INS_sve_sqadd, INS_sve_uqadd, INS_sve_sqadd, INS_sve_uqadd, INS_sve_sqadd, INS_sve_uqadd, INS_sve_sqadd, INS_sve_uqadd, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) -HARDWARE_INTRINSIC(Sve, AddSequentialAcross, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fadda, INS_sve_fadda}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve, AddSequentialAcross, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fadda, INS_sve_fadda}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_ReduceOperation) HARDWARE_INTRINSIC(Sve, And, -1, -1, {INS_sve_and, INS_sve_and, INS_sve_and, INS_sve_and, INS_sve_and, INS_sve_and, INS_sve_and, INS_sve_and, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) -HARDWARE_INTRINSIC(Sve, AndAcross, -1, -1, {INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, AndAcross, -1, -1, {INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ReduceOperation) HARDWARE_INTRINSIC(Sve, BitwiseClear, -1, -1, {INS_sve_bic, INS_sve_bic, INS_sve_bic, INS_sve_bic, INS_sve_bic, INS_sve_bic, INS_sve_bic, INS_sve_bic, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, BooleanNot, -1, -1, {INS_sve_cnot, INS_sve_cnot, INS_sve_cnot, INS_sve_cnot, INS_sve_cnot, INS_sve_cnot, INS_sve_cnot, INS_sve_cnot, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, Compact, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_compact, INS_sve_compact, INS_sve_compact, INS_sve_compact, INS_sve_compact, INS_sve_compact}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) @@ -208,13 +208,13 @@ HARDWARE_INTRINSIC(Sve, LoadVectorUInt32ZeroExtendFirstFaulting, HARDWARE_INTRINSIC(Sve, LoadVectorUInt32ZeroExtendToInt64, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1w, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) HARDWARE_INTRINSIC(Sve, LoadVectorUInt32ZeroExtendToUInt64, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1w, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) HARDWARE_INTRINSIC(Sve, Max, -1, -1, {INS_sve_smax, INS_sve_umax, INS_sve_smax, INS_sve_umax, INS_sve_smax, INS_sve_umax, INS_sve_smax, INS_sve_umax, INS_sve_fmax, INS_sve_fmax}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) -HARDWARE_INTRINSIC(Sve, MaxAcross, -1, -1, {INS_sve_smaxv, INS_sve_umaxv, INS_sve_smaxv, INS_sve_umaxv, INS_sve_smaxv, INS_sve_umaxv, INS_sve_smaxv, INS_sve_umaxv, INS_sve_fmaxv, INS_sve_fmaxv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, MaxAcross, -1, -1, {INS_sve_smaxv, INS_sve_umaxv, INS_sve_smaxv, INS_sve_umaxv, INS_sve_smaxv, INS_sve_umaxv, INS_sve_smaxv, INS_sve_umaxv, INS_sve_fmaxv, INS_sve_fmaxv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ReduceOperation) HARDWARE_INTRINSIC(Sve, MaxNumber, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fmaxnm, INS_sve_fmaxnm}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) -HARDWARE_INTRINSIC(Sve, MaxNumberAcross, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fmaxnmv, INS_sve_fmaxnmv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, MaxNumberAcross, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fmaxnmv, INS_sve_fmaxnmv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ReduceOperation) HARDWARE_INTRINSIC(Sve, Min, -1, -1, {INS_sve_smin, INS_sve_umin, INS_sve_smin, INS_sve_umin, INS_sve_smin, INS_sve_umin, INS_sve_smin, INS_sve_umin, INS_sve_fmin, INS_sve_fmin}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) -HARDWARE_INTRINSIC(Sve, MinAcross, -1, -1, {INS_sve_sminv, INS_sve_uminv, INS_sve_sminv, INS_sve_uminv, INS_sve_sminv, INS_sve_uminv, INS_sve_sminv, INS_sve_uminv, INS_sve_fminv, INS_sve_fminv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, MinAcross, -1, -1, {INS_sve_sminv, INS_sve_uminv, INS_sve_sminv, INS_sve_uminv, INS_sve_sminv, INS_sve_uminv, INS_sve_sminv, INS_sve_uminv, INS_sve_fminv, INS_sve_fminv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ReduceOperation) HARDWARE_INTRINSIC(Sve, MinNumber, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fminnm, INS_sve_fminnm}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) -HARDWARE_INTRINSIC(Sve, MinNumberAcross, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fminnmv, INS_sve_fminnmv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, MinNumberAcross, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fminnmv, INS_sve_fminnmv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ReduceOperation) HARDWARE_INTRINSIC(Sve, Multiply, -1, 2, {INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_fmul, INS_sve_fmul}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, MultiplyAdd, -1, -1, {INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation|HW_Flag_FmaIntrinsic|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve, MultiplyAddRotateComplex, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fcmla, INS_sve_fcmla}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand) @@ -225,7 +225,7 @@ HARDWARE_INTRINSIC(Sve, MultiplySubtract, HARDWARE_INTRINSIC(Sve, Negate, -1, -1, {INS_sve_neg, INS_invalid, INS_sve_neg, INS_invalid, INS_sve_neg, INS_invalid, INS_sve_neg, INS_invalid, INS_sve_fneg, INS_sve_fneg}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, Not, -1, -1, {INS_sve_not, INS_sve_not, INS_sve_not, INS_sve_not, INS_sve_not, INS_sve_not, INS_sve_not, INS_sve_not, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation) HARDWARE_INTRINSIC(Sve, Or, -1, -1, {INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) -HARDWARE_INTRINSIC(Sve, OrAcross, -1, -1, {INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, OrAcross, -1, -1, {INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ReduceOperation) HARDWARE_INTRINSIC(Sve, PopCount, -1, -1, {INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, PrefetchBytes, -1, 3, {INS_invalid, INS_sve_prfb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Special, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_BaseTypeFromFirstArg|HW_Flag_HasImmediateOperand|HW_Flag_HasEnumOperand|HW_Flag_SpecialSideEffect_Other) HARDWARE_INTRINSIC(Sve, PrefetchInt16, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_sve_prfh, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Special, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_BaseTypeFromFirstArg|HW_Flag_HasImmediateOperand|HW_Flag_HasEnumOperand|HW_Flag_SpecialSideEffect_Other) @@ -293,7 +293,7 @@ HARDWARE_INTRINSIC(Sve, UnzipEven, HARDWARE_INTRINSIC(Sve, UnzipOdd, -1, 2, {INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve, VectorTableLookup, -1, 2, {INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl}, HW_Category_SIMD, HW_Flag_Scalable) HARDWARE_INTRINSIC(Sve, Xor, -1, -1, {INS_sve_eor, INS_sve_eor, INS_sve_eor, INS_sve_eor, INS_sve_eor, INS_sve_eor, INS_sve_eor, INS_sve_eor, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) -HARDWARE_INTRINSIC(Sve, XorAcross, -1, -1, {INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, XorAcross, -1, -1, {INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ReduceOperation) HARDWARE_INTRINSIC(Sve, ZeroExtend16, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_uxth, INS_invalid, INS_sve_uxth, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, ZeroExtend32, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_uxtw, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, ZeroExtend8, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_sve_uxtb, INS_invalid, INS_sve_uxtb, INS_invalid, INS_sve_uxtb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp index 56cfa8f6ed1d7..7625dbabbd111 100644 --- a/src/coreclr/jit/lowerarmarch.cpp +++ b/src/coreclr/jit/lowerarmarch.cpp @@ -4056,9 +4056,10 @@ GenTree* Lowering::LowerHWIntrinsicCndSel(GenTreeHWIntrinsic* cndSelNode) NamedIntrinsic nestedOp2Id = nestedOp2->AsHWIntrinsic()->GetHWIntrinsicId(); // If the nested op uses Pg/Z, then inactive lanes will result in zeros, so can only transform if - // op3 is all zeros. + // op3 is all zeros. Such a Csel operation is absorbed into the instruction when emitted. Skip this optimisation + // when the nestedOp is a reduce operation. - if (nestedOp1->IsMaskAllBitsSet() && + if (nestedOp1->IsMaskAllBitsSet() && !HWIntrinsicInfo::IsReduceOperation(nestedOp2Id) && (!HWIntrinsicInfo::IsZeroingMaskedOperation(nestedOp2Id) || op3->IsVectorZero())) { GenTree* nestedOp2 = nestedCndSel->Op(2); diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index 632e2a73064e9..523c6822e4838 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -220,6 +220,67 @@ } }"; +const string VecReduceUnOpTest_VectorValidationLogicForCndSel = @" + { + var hasFailed = (mask[0] != 0 ? {ValidateReduceOpResult}: (falseVal[0] != result[0])); + + if (hasFailed) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + var iterResult = (mask[i] != 0) ? 0 : falseVal[i]; + if (mask[i] != 0) + { + // Pick the trueValue + if (iterResult != result[i]) + { + succeeded = false; + break; + } + } + else + { + // For false, the values are merged with destination, and we do not know + // those contents would be, so skip verification for them. + } + } + } + }"; + +const string VecReduceUnOpTest_VectorValidationLogicForCndSel_FalseValue = @" + { + var hasFailed = (mask[0] != 0) ? (trueVal[0] != result[0]): {ValidateReduceOpResult}; + if (hasFailed) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + var iterResult = (mask[i] != 0) ? trueVal[i] : 0; + if (mask[i] != 0) + { + // Pick the trueValue + if (iterResult != result[i]) + { + succeeded = false; + break; + } + } + else + { + // For false, the values are merged with destination, and we do not know + // those contents would be, so skip verification for them. + } + } + } + }"; + const string VecReduceOpTest_ValidationLogic = @"if ({ValidateReduceOpResult}) { succeeded = false; @@ -293,7 +354,7 @@ ("_SveImmTernOpFirstArgTestTemplate.template", "SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), ("_SveScalarTernOpTestTemplate.template", "SveScalarTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleScalarOpTest_ValidationLogic }), ("_SveImm2UnaryOpTestTemplate.template", "SveVecImm2UnOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), - ("_SveMinimalUnaryOpTestTemplate.template", "SveVecReduceUnOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = VecReduceOpTest_ValidationLogic }), + ("_SveMinimalUnaryOpTestTemplate.template", "SveVecReduceUnOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = VecReduceOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = VecReduceUnOpTest_VectorValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = VecReduceUnOpTest_VectorValidationLogicForCndSel_FalseValue }), ("_SveMasklessUnaryOpTestTemplate.template", "SveMasklessSimpleVecOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), ("_SveVecAndScalarOpTest.template", "SveVecAndScalarOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_VectorValidationLogic }), ("_SveMasklessBinaryOpTestTemplate.template", "SveMasklessVecBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveMinimalUnaryOpTestTemplate.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveMinimalUnaryOpTestTemplate.template index 782f77de3520e..5de4a13faa6ad 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveMinimalUnaryOpTestTemplate.template +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveMinimalUnaryOpTestTemplate.template @@ -50,6 +50,12 @@ namespace JIT.HardwareIntrinsics.Arm // Validates passing an instance member of a struct works test.RunStructFldScenario(); + + // Validates executing the test inside conditional, with op3 as falseValue + test.ConditionalSelect_FalseOp(); + + // Validates executing the test inside conditional, with op3 as zero + test.ConditionalSelect_ZeroOp(); } else { @@ -139,9 +145,12 @@ namespace JIT.HardwareIntrinsics.Arm private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); + private static {RetBaseType}[] _maskData = new {RetBaseType}[RetElementCount]; private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; + private {RetVectorType}<{RetBaseType}> _mask; private {Op1VectorType}<{Op1BaseType}> _fld1; + private {RetVectorType}<{RetBaseType}> _falseFld; private DataTable _dataTable; @@ -149,8 +158,12 @@ namespace JIT.HardwareIntrinsics.Arm { Succeeded = true; + for (var i = 0; i < RetElementCount; i++) { _maskData[i] = ({RetBaseType})(TestLibrary.Generator.Get{RetBaseType}() % 2); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetVectorType}<{RetBaseType}>, byte>(ref _mask), ref Unsafe.As<{RetBaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetVectorType}<{RetBaseType}>, byte>(ref _falseFld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } _dataTable = new DataTable(_data1, new {RetBaseType}[RetElementCount], LargestVectorSize); @@ -239,6 +252,66 @@ namespace JIT.HardwareIntrinsics.Arm test.RunStructFldScenario(this); } + public void ConditionalSelect_FalseOp() + { + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_mask - operation in trueValue"); + ConditionalSelectScenario_TrueValue(_mask, _fld1, _falseFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_zero - operation in trueValue"); + ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}>.Zero, _fld1, _falseFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_all - operation in trueValue"); + ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}>.AllBitsSet, _fld1, _falseFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_mask - operation in falseValue"); + ConditionalSelectScenario_FalseValue(_mask, _fld1, _falseFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_zero - operation in falseValue"); + ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}>.Zero, _fld1, _falseFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_all - operation in falseValue"); + ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}>.AllBitsSet, _fld1, _falseFld); + } + + public void ConditionalSelect_ZeroOp() + { + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_mask - operation in trueValue"); + ConditionalSelectScenario_TrueValue(_mask, _fld1, {RetVectorType}<{RetBaseType}>.Zero); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero - operation in trueValue"); + ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}>.Zero, _fld1, {RetVectorType}<{RetBaseType}>.Zero); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all - operation in trueValue"); + ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}>.AllBitsSet, _fld1, {RetVectorType}<{RetBaseType}>.Zero); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_mask - operation in falseValue"); + ConditionalSelectScenario_FalseValue(_mask, _fld1, {RetVectorType}<{RetBaseType}>.Zero); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero - operation in falseValue"); + ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}>.Zero, _fld1, {RetVectorType}<{RetBaseType}>.Zero); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all - operation in falseValue"); + ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}>.AllBitsSet, _fld1, {RetVectorType}<{RetBaseType}>.Zero); + } + + [method: MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {RetVectorType}<{RetBaseType}> falseOp) + { + var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1), falseOp); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateConditionalSelectResult_TrueValue(mask, op1, falseOp, _dataTable.outArrayPtr); + } + + [method: MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {RetVectorType}<{RetBaseType}> trueOp) + { + var result = Sve.ConditionalSelect(mask, trueOp, {Isa}.{Method}(op1)); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateConditionalSelectResult_FalseValue(mask, op1, trueOp, _dataTable.outArrayPtr); + } + public void RunUnsupportedScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); @@ -260,6 +333,62 @@ namespace JIT.HardwareIntrinsics.Arm } } + private void ValidateConditionalSelectResult_TrueValue({RetVectorType}<{RetBaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> leftOp, {RetVectorType}<{RetBaseType}> falseOp, void* output, [CallerMemberName] string method = "") + { + {RetBaseType}[] mask = new {RetBaseType}[RetElementCount]; + {Op1BaseType}[] firstOp = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] falseVal = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] result = new {RetBaseType}[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref mask[0]), maskOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref firstOp[0]), leftOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref falseVal[0]), falseOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref result[0]), ref Unsafe.AsRef(output), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + bool succeeded = true; + {TemplateValidationLogicForCndSel} + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(Sve)}.{nameof({Isa}.{Method})}<{RetBaseType}>({RetVectorType}<{RetBaseType}>, {RetVectorType}<{RetBaseType}>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" mask: ({string.Join(", ", mask)})"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" falseOp: ({string.Join(", ", falseVal)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + + private void ValidateConditionalSelectResult_FalseValue({RetVectorType}<{RetBaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> leftOp, {RetVectorType}<{RetBaseType}> trueOp, void* output, [CallerMemberName] string method = "") + { + {RetBaseType}[] mask = new {RetBaseType}[RetElementCount]; + {Op1BaseType}[] firstOp = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] trueVal = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] result = new {RetBaseType}[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref mask[0]), maskOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref firstOp[0]), leftOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref trueVal[0]), trueOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref result[0]), ref Unsafe.AsRef(output), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + bool succeeded = true; + {TemplateValidationLogicForCndSel_FalseValue} + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(Sve)}.{nameof({Isa}.{Method})}<{RetBaseType}>({RetVectorType}<{RetBaseType}>, {RetVectorType}<{RetBaseType}>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" mask: ({string.Join(", ", mask)})"); + TestLibrary.TestFramework.LogInformation($"firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" trueOp: ({string.Join(", ", trueVal)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, void* result, [CallerMemberName] string method = "") { {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.cs b/src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.cs new file mode 100644 index 0000000000000..0134bab599463 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.cs @@ -0,0 +1,57 @@ +// 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; + +// Generated by Fuzzlyn v2.3 on 2024-08-23 10:17:54 +// Run on Arm64 Windows +// Seed: 14752078066107523191-vectort,vector64,vector128,armsve +// Reduced from 52.7 KiB to 0.7 KiB in 00:00:54 +// Hits JIT assert in Release: +// Assertion failed '!"Got unexpected instruction format after MOVPRFX"' in 'Program:Main(Fuzzlyn.ExecutionServer.IRuntime)' during 'Emit code' (IL size 54; hash 0xade6b36b; FullOpts) +// +// File: C:\dev\dotnet\runtime2\src\coreclr\jit\emitarm64sve.cpp Line: 18623 +// + +using System; +using System.Numerics; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; + +public struct S2 +{ + public Vector F2; +} + +public class Runtime_106868 +{ + public static S2 s_1; + + public static int M4() + { + Vector vr17 = default(Vector); + var vr11 = Vector.Create(0); + var vr8 = Sve.SubtractSaturate(vr17, vr11); + return 1; + } + + [Fact] + public static void TestEntryPoint() + { + if (Sve.IsSupported) + { + var vr12 = Vector.Create(0); + var vr13 = Vector.Create(0); + var vr14 = M4(); + var vr15 = Vector128.CreateScalar(vr14).AsVector(); + var vr16 = Sve.AndAcross(vr13); + s_1.F2 = Sve.ConditionalSelect(vr12, vr16, vr15); + Consume(s_1.F2); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void Consume(Vector v) + { + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.csproj new file mode 100644 index 0000000000000..1352ebe3277bc --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.csproj @@ -0,0 +1,9 @@ + + + True + $(NoWarn),SYSLIB5003 + + + + + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.cs b/src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.cs new file mode 100644 index 0000000000000..c69558571a31d --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.cs @@ -0,0 +1,41 @@ +// 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; + +// Generated by Fuzzlyn v2.3 on 2024-08-23 10:47:43 +// Run on Arm64 Windows +// Seed: 6363239363759785984-vectort,vector64,vector128,armsve +// Reduced from 29.6 KiB to 0.8 KiB in 00:00:27 +// Debug: Prints 0 line(s) +// Release: Prints 1 line(s) +using System; +using System.Numerics; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; + +public class Runtime_106871 +{ + [Fact] + public static void TestEntryPoint() + { + if (Sve.IsSupported) + { + var vr11 = (byte)1; + var vr12 = Vector128.CreateScalar(vr11).AsVector(); + var vr13 = Vector.Create(1); + var vr14 = Vector.Create(1); + var vr15 = (byte)Sve.ConditionalExtractAfterLastActiveElement(vr13, 0, vr14); + var vr16 = Vector128.CreateScalar(vr15).AsVector(); + var vr17 = Vector.Create(0); + var vr18 = (byte)1; + var vr19 = Vector128.CreateScalar(vr18).AsVector(); + var vr20 = Sve.MinAcross(vr19); + var vr21 = Sve.ConditionalSelect(vr16, vr20, vr17); + if (Sve.TestFirstTrue(vr12, vr21)) + { + System.Console.WriteLine(0); + } + } + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.csproj new file mode 100644 index 0000000000000..1352ebe3277bc --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.csproj @@ -0,0 +1,9 @@ + + + True + $(NoWarn),SYSLIB5003 + + + + + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.cs b/src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.cs new file mode 100644 index 0000000000000..16de557d30335 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.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.Runtime.CompilerServices; +using Xunit; + +// Generated by Fuzzlyn v2.3 on 2024-08-23 10:51:00 +// Run on Arm64 Windows +// Seed: 11139641262794602128-vectort,vector64,vector128,armsve +// Reduced from 38.6 KiB to 0.6 KiB in 00:00:32 +// Hits JIT assert in Release: +// Assertion failed 'intrin.op3->IsVectorZero()' in 'Program:Main(Fuzzlyn.ExecutionServer.IRuntime)' during 'Generate code' (IL size 100; hash 0xade6b36b; FullOpts) +// +// File: C:\dev\dotnet\runtime2\src\coreclr\jit\hwintrinsiccodegenarm64.cpp Line: 755 +// +using System; +using System.Numerics; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; + +public class C2 +{ + public Vector F3; +} + +public class Runtime_106872 +{ + public static C2[] s_1 = { new C2() }; + + [Fact] + public static void TestEntryPoint() + { + if (Sve.IsSupported) + { + var vr4 = Vector128.CreateScalar(728.8837854670671d).AsVector(); + var vr5 = Vector128.CreateScalar(1103.750484880559d).AsVector(); + var vr6 = Vector128.CreateScalar(-1881.6772519539704d).AsVector(); + var vr7 = s_1[0].F3; + s_1[0].F3 = Sve.ConditionalSelect(vr4, Sve.AddSequentialAcross(vr6, vr7), vr5); + } + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void Consume(Vector v) + { + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.csproj new file mode 100644 index 0000000000000..1352ebe3277bc --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.csproj @@ -0,0 +1,9 @@ + + + True + $(NoWarn),SYSLIB5003 + + + + + From 593af2b03bf3198a229258173ef5d315db669350 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 12 Sep 2024 14:07:26 -0600 Subject: [PATCH 17/34] Revert "don't define HAS_CUSTOM_BLOCKS on mono (#106764)" (#107675) This reverts commit 7266021f0e16011c38686618b73f0eb8e37f1644. Co-authored-by: Matous Kozak --- .../System.Private.CoreLib/src/System/SpanHelpers.ByteMemOps.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.ByteMemOps.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.ByteMemOps.cs index f4a97d15689cb..c4831969ccb0c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.ByteMemOps.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.ByteMemOps.cs @@ -1,7 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if !MONO && (TARGET_AMD64 || TARGET_ARM64 || (TARGET_32BIT && !TARGET_ARM) || TARGET_LOONGARCH64) +#if TARGET_AMD64 || TARGET_ARM64 || (TARGET_32BIT && !TARGET_ARM) || TARGET_LOONGARCH64 // JIT is guaranteed to unroll blocks up to 64 bytes in size #define HAS_CUSTOM_BLOCKS #endif From c04c2b7223f2c61c30df3a94dc3a080ecc35c6ae Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 12 Sep 2024 14:08:37 -0600 Subject: [PATCH 18/34] [release/9.0] [Tar] Fill in the file size even if the file is empty. (#107633) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Tar] Fill in the file size even if the file is empty. This matches standard behavior. * fix tests, set size only when datastream is not null * Add unit tests for size header of an empty file * Scope disposables Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> * Update test to verify entry can be read after confirming the sequence is correct. Add test to verify that entries created with the malformed size field are still readable after the bug fix. --------- Co-authored-by: Szymon Sobik Co-authored-by: Carlos Sánchez López <1175054+carlossanlop@users.noreply.github.com> --- .../src/System/Formats/Tar/TarHeader.Write.cs | 2 +- .../tests/TarWriter/TarWriter.Tests.cs | 69 +++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.Write.cs b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.Write.cs index 81d90e1d7be21..fcc5d22cde60e 100644 --- a/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.Write.cs +++ b/src/libraries/System.Formats.Tar/src/System/Formats/Tar/TarHeader.Write.cs @@ -629,7 +629,7 @@ private int WriteCommonFields(Span buffer, TarEntryType actualEntryType) checksum += FormatNumeric(_gid, buffer.Slice(FieldLocations.Gid, FieldLengths.Gid)); } - if (_size > 0) + if (_dataStream != null && _size >= 0) { checksum += FormatNumeric(_size, buffer.Slice(FieldLocations.Size, FieldLengths.Size)); } diff --git a/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.Tests.cs b/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.Tests.cs index b46816844b44c..26b768bfe33b8 100644 --- a/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.Tests.cs +++ b/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.Tests.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.IO; +using System.Linq; using Xunit; namespace System.Formats.Tar.Tests @@ -144,6 +145,74 @@ public void Verify_Checksum_SymbolicLink_LongLink(TarEntryFormat format) => public void Verify_Checksum_SymbolicLink_LongLink_LongPath(TarEntryFormat format) => Verify_Checksum_Internal(format, TarEntryType.SymbolicLink, longPath: true, longLink: true); + [Fact] + public void Verify_Size_RegularFile_Empty() + { + using MemoryStream archiveStream = new(); + string entryName = "entry.txt"; + using (TarWriter archive = new(archiveStream, TarEntryFormat.V7, leaveOpen: true)) + { + V7TarEntry e = new(TarEntryType.V7RegularFile, entryName) + { + DataStream = new MemoryStream(0) + }; + archive.WriteEntry(e); + } + + int sizeLocation = 100 + // Name + 8 + // Mode + 8 + // Uid + 8; // Gid + int sizeLength = 12; + + archiveStream.Position = 0; + byte[] actual = archiveStream.GetBuffer()[sizeLocation..(sizeLocation + sizeLength)]; + + byte[] expected = [0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0]; + AssertExtensions.SequenceEqual(expected, actual); + + archiveStream.Position = 0; + using TarReader reader = new(archiveStream); + + TarEntry? actualEntry = reader.GetNextEntry(); + Assert.NotNull(actualEntry); + Assert.Equal(0, actualEntry.Length); + Assert.Null(actualEntry.DataStream); // No stream created when size field's value is 0 + } + + [Fact] + public void Verify_Compatibility_RegularFile_EmptyFile_NoSizeStored() + { + using MemoryStream archiveStream = new(); + string entryName = "entry.txt"; + using (TarWriter archive = new(archiveStream, TarEntryFormat.V7, leaveOpen: true)) + { + V7TarEntry e = new(TarEntryType.V7RegularFile, entryName) + { + DataStream = new MemoryStream(0) + }; + archive.WriteEntry(e); + } + + int sizeLocation = 100 + // Name + 8 + // Mode + 8 + // Uid + 8; // Gid + + // Fill the size field with 12 zeros as we used to before the bug fix + byte[] replacement = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + archiveStream.Seek(sizeLocation, SeekOrigin.Begin); + archiveStream.Write(replacement); + + archiveStream.Position = 0; + using TarReader reader = new(archiveStream); + + TarEntry? actualEntry = reader.GetNextEntry(); // Should succeed to read the entry with a malformed size field value + Assert.NotNull(actualEntry); + Assert.Equal(0, actualEntry.Length); // Should succeed to detect the size field's value as zero + Assert.Null(actualEntry.DataStream); // No stream created when size field's value is 0 + } + private void Verify_Checksum_Internal(TarEntryFormat format, TarEntryType entryType, bool longPath, bool longLink) { using MemoryStream archive = new MemoryStream(); From a1e101980ae150d67bdb39254e01813ec80f97b0 Mon Sep 17 00:00:00 2001 From: Aman Khalid Date: Thu, 12 Sep 2024 20:09:24 +0000 Subject: [PATCH 19/34] Backport #107601 (#107725) Co-authored-by: SwapnilGaikwad --- .../GenerateHWIntrinsicTests_Arm.cs | 38 +++++-------------- 1 file changed, 10 insertions(+), 28 deletions(-) diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index 523c6822e4838..264531af67e39 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -222,7 +222,7 @@ const string VecReduceUnOpTest_VectorValidationLogicForCndSel = @" { - var hasFailed = (mask[0] != 0 ? {ValidateReduceOpResult}: (falseVal[0] != result[0])); + var hasFailed = (mask[0] != 0) ? ({ValidateReduceOpResult}): (falseVal[0] != result[0]); if (hasFailed) { @@ -232,20 +232,11 @@ { for (var i = 1; i < RetElementCount; i++) { - var iterResult = (mask[i] != 0) ? 0 : falseVal[i]; - if (mask[i] != 0) + hasFailed = (mask[i] != 0) ? ({ValidateRemainingResults}) : (falseVal[i] != result[i]); + if (hasFailed) { - // Pick the trueValue - if (iterResult != result[i]) - { - succeeded = false; - break; - } - } - else - { - // For false, the values are merged with destination, and we do not know - // those contents would be, so skip verification for them. + succeeded = false; + break; } } } @@ -253,7 +244,7 @@ const string VecReduceUnOpTest_VectorValidationLogicForCndSel_FalseValue = @" { - var hasFailed = (mask[0] != 0) ? (trueVal[0] != result[0]): {ValidateReduceOpResult}; + var hasFailed = (mask[0] != 0) ? (trueVal[0] != result[0]): ({ValidateReduceOpResult}); if (hasFailed) { succeeded = false; @@ -262,20 +253,11 @@ { for (var i = 1; i < RetElementCount; i++) { - var iterResult = (mask[i] != 0) ? trueVal[i] : 0; - if (mask[i] != 0) + hasFailed = (mask[i] != 0) ? (trueVal[i] != result[i]) : ({ValidateRemainingResults}); + if (hasFailed) { - // Pick the trueValue - if (iterResult != result[i]) - { - succeeded = false; - break; - } - } - else - { - // For false, the values are merged with destination, and we do not know - // those contents would be, so skip verification for them. + succeeded = false; + break; } } } From e9633ab878a381e4b5714d05b47383ce1094e6e9 Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Thu, 12 Sep 2024 22:11:31 +0200 Subject: [PATCH 20/34] [release/9.0] TypeName fuzzer and bug fixes (#107533) * AssemblyNameInfo fuzzer (#107195) * add initial AssemblyNameInfo Fuzzer * fix the first bug that it has discovered * Fix sbyte overflow in TypeName parsing (#107261) * Add TypeNameFuzzer (#107206) Co-authored-by: Miha Zupan Co-authored-by: Adam Sitnik * [TypeName] Nested types should respect MaxNode count (#106334) * Improve AssemblyNameInfo Fuzzer (#107257) --------- Co-authored-by: Buyaa Namnan Co-authored-by: Miha Zupan --- .../libraries/fuzzing/deploy-to-onefuzz.yml | 16 ++ .../Dictionaries/assemblynameinfo.dict | 16 ++ .../DotnetFuzzing/Dictionaries/typename.dict | 26 ++ .../Fuzzers/AssemblyNameInfoFuzzer.cs | 80 ++++++ .../DotnetFuzzing/Fuzzers/TypeNameFuzzer.cs | 65 +++++ .../src/System/Reflection/TypeNameResolver.cs | 3 - .../Reflection/Metadata/AssemblyNameInfo.cs | 2 +- .../System/Reflection/Metadata/TypeName.cs | 24 +- .../Reflection/Metadata/TypeNameParser.cs | 32 ++- .../Metadata/TypeNameParserHelpers.cs | 27 +- .../Metadata/TypeNameParserOptions.cs | 2 - .../tests/Metadata/AssemblyNameInfoTests.cs | 7 + .../Metadata/TypeNameParserHelpersTests.cs | 5 +- .../tests/Metadata/TypeNameTests.cs | 262 +++++++++++++----- 14 files changed, 460 insertions(+), 107 deletions(-) create mode 100644 src/libraries/Fuzzing/DotnetFuzzing/Dictionaries/assemblynameinfo.dict create mode 100644 src/libraries/Fuzzing/DotnetFuzzing/Dictionaries/typename.dict create mode 100644 src/libraries/Fuzzing/DotnetFuzzing/Fuzzers/AssemblyNameInfoFuzzer.cs create mode 100644 src/libraries/Fuzzing/DotnetFuzzing/Fuzzers/TypeNameFuzzer.cs diff --git a/eng/pipelines/libraries/fuzzing/deploy-to-onefuzz.yml b/eng/pipelines/libraries/fuzzing/deploy-to-onefuzz.yml index 276cc50f97de3..18c5ad2b5e832 100644 --- a/eng/pipelines/libraries/fuzzing/deploy-to-onefuzz.yml +++ b/eng/pipelines/libraries/fuzzing/deploy-to-onefuzz.yml @@ -65,6 +65,14 @@ extends: # displayName: Send to OneFuzz # ONEFUZZ_TASK_WORKAROUND_START + - task: onefuzz-task@0 + inputs: + onefuzzOSes: 'Windows' + env: + onefuzzDropDirectory: $(fuzzerProject)/deployment/AssemblyNameInfoFuzzer + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + displayName: Send AssemblyNameInfoFuzzer to OneFuzz + - task: onefuzz-task@0 inputs: onefuzzOSes: 'Windows' @@ -113,6 +121,14 @@ extends: SYSTEM_ACCESSTOKEN: $(System.AccessToken) displayName: Send TextEncodingFuzzer to OneFuzz + - task: onefuzz-task@0 + inputs: + onefuzzOSes: 'Windows' + env: + onefuzzDropDirectory: $(fuzzerProject)/deployment/TypeNameFuzzer + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + displayName: Send TypeNameFuzzer to OneFuzz + - task: onefuzz-task@0 inputs: onefuzzOSes: 'Windows' diff --git a/src/libraries/Fuzzing/DotnetFuzzing/Dictionaries/assemblynameinfo.dict b/src/libraries/Fuzzing/DotnetFuzzing/Dictionaries/assemblynameinfo.dict new file mode 100644 index 0000000000000..f15a4c6c72173 --- /dev/null +++ b/src/libraries/Fuzzing/DotnetFuzzing/Dictionaries/assemblynameinfo.dict @@ -0,0 +1,16 @@ +"MyAssemblyName, Version=1.0.0.0, PublicKeyToken=b77a5c561934e089" +"System.IO.Pipelines.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001004b86c4cb78549b34bab61a3b1800e23bfeb5b3ec390074041536a7e3cbd97f5f04cf0f857155a8928eaa29ebfd11cfbbad3ba70efea7bda3226c6a8d370a4cd303f714486b6ebc225985a638471e6ef571cc92a4613c00b8fa65d61ccee0cbe5f36330c9a01f4183559f1bef24cc2917c6d913e3a541333a1d05d9bed22b38cb" +"System.IO.Pipelines.Tests, PublicKey=null" +"Abc, ProcessorArchitecture=X86" +"Abc, ProcessorArchitecture=Amd64" +"Abc, ProcessorArchitecture=Arm" +"Abc, ProcessorArchitecture=MSIL" +"Abc, ContentType=WindowsRuntime" +"Abc, Retargetable=Yes" +"Esc\\[aped" +"MyAssemblyName, Version=1.0.0.0, PublicKeyToken=b77a5c561934e089", "MyAssemblyName, Version=1.0.0.0, PublicKeyToken=b77a5c561934e089" +"MyAssemblyName, Version=1.0.0.0, PublicKey=00000000000000000400000000000000", "MyAssemblyName, Version=1.0.0.0, PublicKeyToken=b77a5c561934e089" +"TerraFX.Interop.Windows, PublicKey=002400000c800000940000000602000000240000525341310004000001000100897039f5ff762b25b9ba982c3f5836c34e299279c33df505bf806a07bccdf0e1216e661943f557b954cb18422ed522a5b3174b85385052677f39c4ce19f30a1ddbaa507054bc5943461651f396afc612cd80419c5ee2b5277571ff65f51d14ba99e4e4196de0f393e89850a465f019dbdc365ed5e81bbafe1370f54efd254ba8, TerraFX.Interop.Windows, PublicKeyToken=35b01b53313a6f7e" +"aaaa, language=en-en" +"aaaa, foo=bar, foo=baz" +"aa/name " \ No newline at end of file diff --git a/src/libraries/Fuzzing/DotnetFuzzing/Dictionaries/typename.dict b/src/libraries/Fuzzing/DotnetFuzzing/Dictionaries/typename.dict new file mode 100644 index 0000000000000..1380ac70af0ec --- /dev/null +++ b/src/libraries/Fuzzing/DotnetFuzzing/Dictionaries/typename.dict @@ -0,0 +1,26 @@ +" " +"0" +"," +"[*[" +" System.Int32 " +"System.Int32&&" +"System.Int32[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]" +"System.Int32[*******************************]" +"System.Int32[][][][][][][][][][][][][][][][][][][][]" +".NoNamespace" +"Namespace.Ko\xC5\x9B\xC4\x87" +"Declaring+Nested" +"Declaring+Deep+Deeper+Nested" +"Declaring+Deep+Deeper+Nested, Lib" +"MyNamespace.MyType+NestedType" +"Pointer*******" +"Generic`1[[A]]" +"Generic`2[[A],[B]]" +"Generic`3[[A],[B],[C]]" +"Generic`3[A,B,C]" +"Generic`2[[System.Int32, mscorlib, Version=4.0.0, Culture=neutral, PublicKeyToken=b77a5c561934],[System.Boolean, mscorlib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]" +"Generic`3[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089], System.Boolean, [System.Byte, other, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089]]" +"TypeNameWith\\TheEscapingCharacter" +"TypeNameWith[[]]NestedSquareBrackets" +"TypeNameWith\\[]+*&,AllSpecialCharacters" +"System.Reflection.Metadata.Tests.TypeNameTests+NestedGeneric_0`1+NestedGeneric_1`2+NestedGeneric_2`3+NestedNonGeneric_3[[System.Int32, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.String, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Boolean, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Int16, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Byte, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.SByte, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Reflection.Metadata.Tests, Version=9.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" \ No newline at end of file diff --git a/src/libraries/Fuzzing/DotnetFuzzing/Fuzzers/AssemblyNameInfoFuzzer.cs b/src/libraries/Fuzzing/DotnetFuzzing/Fuzzers/AssemblyNameInfoFuzzer.cs new file mode 100644 index 0000000000000..9ce1bd255c7b6 --- /dev/null +++ b/src/libraries/Fuzzing/DotnetFuzzing/Fuzzers/AssemblyNameInfoFuzzer.cs @@ -0,0 +1,80 @@ +// 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.Reflection.Metadata; +using System.Runtime.InteropServices; +using System.Text; + +namespace DotnetFuzzing.Fuzzers +{ + internal sealed class AssemblyNameInfoFuzzer : IFuzzer + { + public string[] TargetAssemblies => ["System.Reflection.Metadata"]; + + public string[] TargetCoreLibPrefixes => []; + + public string Dictionary => "assemblynameinfo.dict"; + + public void FuzzTarget(ReadOnlySpan bytes) + { + Span chars = new char[Encoding.UTF8.GetCharCount(bytes)]; + Encoding.UTF8.GetChars(bytes, chars); + + using PooledBoundedMemory inputPoisonedBefore = PooledBoundedMemory.Rent(chars, PoisonPagePlacement.Before); + using PooledBoundedMemory inputPoisonedAfter = PooledBoundedMemory.Rent(chars, PoisonPagePlacement.After); + + Test(inputPoisonedBefore); + Test(inputPoisonedAfter); + } + + private static void Test(PooledBoundedMemory inputPoisoned) + { + if (AssemblyNameInfo.TryParse(inputPoisoned.Span, out AssemblyNameInfo? fromTryParse)) + { + AssemblyNameInfo fromParse = AssemblyNameInfo.Parse(inputPoisoned.Span); + + Assert.Equal(fromTryParse.Name, fromParse.Name); + Assert.Equal(fromTryParse.FullName, fromParse.FullName); + Assert.Equal(fromTryParse.CultureName, fromParse.CultureName); + Assert.Equal(fromTryParse.Flags, fromParse.Flags); + Assert.Equal(fromTryParse.Version, fromParse.Version); + Assert.SequenceEqual(fromTryParse.PublicKeyOrToken.AsSpan(), fromParse.PublicKeyOrToken.AsSpan()); + + Assert.Equal(fromTryParse.ToAssemblyName().Name, fromParse.ToAssemblyName().Name); + Assert.Equal(fromTryParse.ToAssemblyName().Version, fromParse.ToAssemblyName().Version); + Assert.Equal(fromTryParse.ToAssemblyName().ContentType, fromParse.ToAssemblyName().ContentType); + Assert.Equal(fromTryParse.ToAssemblyName().CultureName, fromParse.ToAssemblyName().CultureName); + + Assert.Equal(fromTryParse.Name, fromParse.ToAssemblyName().Name); + Assert.Equal(fromTryParse.CultureName, fromParse.ToAssemblyName().CultureName); + Assert.Equal(fromTryParse.Version, fromParse.ToAssemblyName().Version); + + // AssemblyNameInfo.FullName can be different than AssemblyName.FullName: + // AssemblyNameInfo includes public key, AssemblyName only its Token. + + try + { + Assert.Equal(fromTryParse.ToAssemblyName().FullName, fromParse.ToAssemblyName().FullName); + } + catch (System.Security.SecurityException) + { + // AssemblyName.FullName performs public key validation, AssemblyNameInfo does not (on purpose). + } + } + else + { + try + { + _ = AssemblyNameInfo.Parse(inputPoisoned.Span); + } + catch (ArgumentException) + { + return; + } + + throw new Exception("Parsing was supposed to fail!"); + } + } + } +} diff --git a/src/libraries/Fuzzing/DotnetFuzzing/Fuzzers/TypeNameFuzzer.cs b/src/libraries/Fuzzing/DotnetFuzzing/Fuzzers/TypeNameFuzzer.cs new file mode 100644 index 0000000000000..f8b3e96083707 --- /dev/null +++ b/src/libraries/Fuzzing/DotnetFuzzing/Fuzzers/TypeNameFuzzer.cs @@ -0,0 +1,65 @@ +// 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.Reflection.Metadata; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.Marshalling; +using System.Text; + +namespace DotnetFuzzing.Fuzzers +{ + internal sealed class TypeNameFuzzer : IFuzzer + { + public string[] TargetAssemblies { get; } = ["System.Reflection.Metadata"]; + public string[] TargetCoreLibPrefixes => []; + public string Dictionary => "typename.dict"; + + public void FuzzTarget(ReadOnlySpan bytes) + { + Span charSpan = new char[Encoding.UTF8.GetCharCount(bytes)]; + Encoding.UTF8.GetChars(bytes, charSpan); + using var poisonAfter = PooledBoundedMemory.Rent(charSpan, PoisonPagePlacement.After); + using var poisonBefore = PooledBoundedMemory.Rent(charSpan, PoisonPagePlacement.Before); + + Test(poisonAfter.Span); + Test(poisonBefore.Span); + } + + private static void Test(Span testSpan) + { + if (TypeName.TryParse(testSpan, out TypeName? result1)) + { + TypeName result2 = TypeName.Parse(testSpan); + Assert.Equal(result1.Name, result2.Name); + Assert.Equal(result1.FullName, result2.FullName); + Assert.Equal(result1.AssemblyQualifiedName, result2.AssemblyQualifiedName); + Assert.Equal(result1.IsSimple, result2.IsSimple); + Assert.Equal(result1.IsNested, result2.IsNested); + Assert.Equal(result1.IsArray, result2.IsArray); + Assert.Equal(result1.GetNodeCount(), result2.GetNodeCount()); + if (result1.AssemblyName != null) + { + Assert.Equal(result1.AssemblyName.Name, result2.AssemblyName!.Name); + Assert.Equal(result1.AssemblyName.FullName, result2.AssemblyName.FullName); + Assert.Equal(result1.AssemblyName.CultureName, result2.AssemblyName.CultureName); + Assert.Equal(result1.AssemblyName.Version?.ToString(), result2.AssemblyName.Version?.ToString()); + } + else + { + Assert.Equal(result1.AssemblyName, result2.AssemblyName); + } + } + else + { + try + { + TypeName.Parse(testSpan); + Assert.Equal(true, false); // should never succeed + } + catch (ArgumentException) { } + catch (InvalidOperationException) { } + } + } + } +} diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/TypeNameResolver.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/TypeNameResolver.cs index 9e36505b390ea..04ab8e7ee0859 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/TypeNameResolver.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/TypeNameResolver.cs @@ -4,7 +4,6 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Reflection.Metadata; -using System.Text; namespace System.Reflection.Metadata { @@ -12,8 +11,6 @@ internal struct TypeNameParseOptions { public TypeNameParseOptions() { } #pragma warning disable CA1822 // Mark members as static - // CoreLib does not enforce any limits - public bool IsMaxDepthExceeded(int _) => false; public int MaxNodes { get diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/AssemblyNameInfo.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/AssemblyNameInfo.cs index ddc61cd36449c..bd1febff03659 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/AssemblyNameInfo.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/AssemblyNameInfo.cs @@ -193,7 +193,7 @@ public static AssemblyNameInfo Parse(ReadOnlySpan assemblyName) public static bool TryParse(ReadOnlySpan assemblyName, [NotNullWhen(true)] out AssemblyNameInfo? result) { AssemblyNameParser.AssemblyNameParts parts = default; - if (AssemblyNameParser.TryParse(assemblyName, ref parts)) + if (!assemblyName.IsEmpty && AssemblyNameParser.TryParse(assemblyName, ref parts)) { result = new(parts); return true; diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeName.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeName.cs index 8920e5a31c39f..22ae86f08e6b5 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeName.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeName.cs @@ -301,24 +301,28 @@ public string Name /// public int GetNodeCount() { + // This method uses checked arithmetic to avoid silent overflows. + // It's impossible to parse a TypeName with NodeCount > int.MaxValue + // (TypeNameParseOptions.MaxNodes is an int), but it's possible + // to create such names with the Make* APIs. int result = 1; - if (IsNested) + if (IsArray || IsPointer || IsByRef) { - result += DeclaringType.GetNodeCount(); + result = checked(result + GetElementType().GetNodeCount()); } else if (IsConstructedGenericType) { - result++; - } - else if (IsArray || IsPointer || IsByRef) - { - result += GetElementType().GetNodeCount(); - } + result = checked(result + GetGenericTypeDefinition().GetNodeCount()); - foreach (TypeName genericArgument in GetGenericArguments()) + foreach (TypeName genericArgument in GetGenericArguments()) + { + result = checked(result + genericArgument.GetNodeCount()); + } + } + else if (IsNested) { - result += genericArgument.GetNodeCount(); + result = checked(result + DeclaringType.GetNodeCount()); } return result; diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeNameParser.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeNameParser.cs index 5a5bbe04a0c18..97294c8014f2b 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeNameParser.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeNameParser.cs @@ -49,7 +49,7 @@ private TypeNameParser(ReadOnlySpan name, bool throwOnError, TypeNameParse { if (throwOnError) { - if (parser._parseOptions.IsMaxDepthExceeded(recursiveDepth)) + if (IsMaxDepthExceeded(parser._parseOptions, recursiveDepth)) { ThrowInvalidOperation_MaxNodesExceeded(parser._parseOptions.MaxNodes); } @@ -61,19 +61,21 @@ private TypeNameParser(ReadOnlySpan name, bool throwOnError, TypeNameParse return null; } + Debug.Assert(parsedName.GetNodeCount() == recursiveDepth, $"Node count mismatch for '{typeName.ToString()}'"); + return parsedName; } // this method should return null instead of throwing, so the caller can get errorIndex and include it in error msg private TypeName? ParseNextTypeName(bool allowFullyQualifiedName, ref int recursiveDepth) { - if (!TryDive(ref recursiveDepth)) + if (!TryDive(_parseOptions, ref recursiveDepth)) { return null; } List? nestedNameLengths = null; - if (!TryGetTypeNameInfo(ref _inputString, ref nestedNameLengths, out int fullTypeNameLength)) + if (!TryGetTypeNameInfo(_parseOptions, ref _inputString, ref nestedNameLengths, ref recursiveDepth, out int fullTypeNameLength)) { return null; } @@ -147,6 +149,16 @@ private TypeNameParser(ReadOnlySpan name, bool throwOnError, TypeNameParse { _inputString = capturedBeforeProcessing; } + else + { + // Every constructed generic type needs the generic type definition. + if (!TryDive(_parseOptions, ref recursiveDepth)) + { + return null; + } + // If that generic type is a nested type, we don't increase the recursiveDepth any further, + // as generic type definition uses exactly the same declaring type as the constructed generic type. + } int previousDecorator = default; // capture the current state so we can reprocess it again once we know the AssemblyName @@ -154,7 +166,7 @@ private TypeNameParser(ReadOnlySpan name, bool throwOnError, TypeNameParse // iterate over the decorators to ensure there are no illegal combinations while (TryParseNextDecorator(ref _inputString, out int parsedDecorator)) { - if (!TryDive(ref recursiveDepth)) + if (!TryDive(_parseOptions, ref recursiveDepth)) { return null; } @@ -194,7 +206,7 @@ private TypeNameParser(ReadOnlySpan name, bool throwOnError, TypeNameParse { while (TryParseNextDecorator(ref capturedBeforeProcessing, out int parsedModifier)) { - result = new(fullName: null, assemblyName, elementOrGenericType: result, rankOrModifier: (sbyte)parsedModifier); + result = new(fullName: null, assemblyName, elementOrGenericType: result, rankOrModifier: parsedModifier); } } @@ -245,15 +257,5 @@ private bool TryParseAssemblyName(ref AssemblyNameInfo? assemblyName) return declaringType; } - - private bool TryDive(ref int depth) - { - if (_parseOptions.IsMaxDepthExceeded(depth)) - { - return false; - } - depth++; - return true; - } } } diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeNameParserHelpers.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeNameParserHelpers.cs index ef0a9e702a1a2..93859262eed99 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeNameParserHelpers.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeNameParserHelpers.cs @@ -11,9 +11,9 @@ namespace System.Reflection.Metadata { internal static class TypeNameParserHelpers { - internal const sbyte SZArray = -1; - internal const sbyte Pointer = -2; - internal const sbyte ByRef = -3; + internal const int SZArray = -1; + internal const int Pointer = -2; + internal const int ByRef = -3; private const char EscapeCharacter = '\\'; #if NET8_0_OR_GREATER private static readonly SearchValues s_endOfFullTypeNameDelimitersSearchValues = SearchValues.Create("[]&*,+\\"); @@ -220,7 +220,8 @@ internal static bool IsBeginningOfGenericArgs(ref ReadOnlySpan span, out b return false; } - internal static bool TryGetTypeNameInfo(ref ReadOnlySpan input, ref List? nestedNameLengths, out int totalLength) + internal static bool TryGetTypeNameInfo(TypeNameParseOptions options, ref ReadOnlySpan input, + ref List? nestedNameLengths, ref int recursiveDepth, out int totalLength) { bool isNestedType; totalLength = 0; @@ -248,6 +249,11 @@ internal static bool TryGetTypeNameInfo(ref ReadOnlySpan input, ref List false; // CoreLib does not enforce any limits +#else + => depth > options.MaxNodes; +#endif + + internal static bool TryDive(TypeNameParseOptions options, ref int depth) + { + depth++; + return !IsMaxDepthExceeded(options, depth); + } + #if SYSTEM_REFLECTION_METADATA [DoesNotReturn] internal static void ThrowInvalidOperation_NotSimpleName(string fullName) diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeNameParserOptions.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeNameParserOptions.cs index 551876e73147c..b7420c40aa9ea 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeNameParserOptions.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeNameParserOptions.cs @@ -27,7 +27,5 @@ public int MaxNodes _maxNodes = value; } } - - internal bool IsMaxDepthExceeded(int depth) => depth >= _maxNodes; } } diff --git a/src/libraries/System.Reflection.Metadata/tests/Metadata/AssemblyNameInfoTests.cs b/src/libraries/System.Reflection.Metadata/tests/Metadata/AssemblyNameInfoTests.cs index 89127889c407c..c766e6bd4d559 100644 --- a/src/libraries/System.Reflection.Metadata/tests/Metadata/AssemblyNameInfoTests.cs +++ b/src/libraries/System.Reflection.Metadata/tests/Metadata/AssemblyNameInfoTests.cs @@ -98,6 +98,13 @@ public void RetargetableIsPropagated() public void EscapedSquareBracketIsNotAllowedInTheName() => Assert.False(AssemblyNameInfo.TryParse("Esc\\[aped".AsSpan(), out _)); + [Fact] + public void EmptyInputIsInvalid() + { + Assert.False(AssemblyNameInfo.TryParse("".AsSpan(), out _)); + Assert.Throws(() => AssemblyNameInfo.Parse("".AsSpan())); + } + static void Roundtrip(AssemblyName source) { AssemblyNameInfo parsed = AssemblyNameInfo.Parse(source.FullName.AsSpan()); diff --git a/src/libraries/System.Reflection.Metadata/tests/Metadata/TypeNameParserHelpersTests.cs b/src/libraries/System.Reflection.Metadata/tests/Metadata/TypeNameParserHelpersTests.cs index b9d23a2be1524..01ec45b50cc3e 100644 --- a/src/libraries/System.Reflection.Metadata/tests/Metadata/TypeNameParserHelpersTests.cs +++ b/src/libraries/System.Reflection.Metadata/tests/Metadata/TypeNameParserHelpersTests.cs @@ -122,7 +122,9 @@ public void TryGetTypeNameInfoGetsAllTheInfo(string input, bool expectedResult, { List? nestedNameLengths = null; ReadOnlySpan span = input.AsSpan(); - bool result = TypeNameParserHelpers.TryGetTypeNameInfo(ref span, ref nestedNameLengths, out int totalLength); + TypeNameParseOptions options = new(); + int recursiveDepth = 0; + bool result = TypeNameParserHelpers.TryGetTypeNameInfo(options, ref span, ref nestedNameLengths, ref recursiveDepth, out int totalLength); Assert.Equal(expectedResult, result); @@ -130,6 +132,7 @@ public void TryGetTypeNameInfoGetsAllTheInfo(string input, bool expectedResult, { Assert.Equal(expectedNestedNameLengths, nestedNameLengths?.ToArray()); Assert.Equal(expectedTotalLength, totalLength); + Assert.Equal(expectedNestedNameLengths?.Length ?? 0, recursiveDepth); } } diff --git a/src/libraries/System.Reflection.Metadata/tests/Metadata/TypeNameTests.cs b/src/libraries/System.Reflection.Metadata/tests/Metadata/TypeNameTests.cs index 1fbc9f4e011d1..dcf46d54d2d95 100644 --- a/src/libraries/System.Reflection.Metadata/tests/Metadata/TypeNameTests.cs +++ b/src/libraries/System.Reflection.Metadata/tests/Metadata/TypeNameTests.cs @@ -121,119 +121,207 @@ static void Verify(Type type, AssemblyName expectedAssemblyName, TypeName parsed } } - [Theory] - [InlineData(10, "*")] // pointer to pointer - [InlineData(10, "[]")] // array of arrays - [InlineData(100, "*")] - [InlineData(100, "[]")] - public void MaxNodesIsRespected_TooManyDecorators(int maxDepth, string decorator) + private static void EnsureMaxNodesIsRespected(string typeName, int expectedNodeCount, Action validate) { - TypeNameParseOptions options = new() + // Specified MaxNodes is equal the actual node count + TypeNameParseOptions equal = new() + { + MaxNodes = expectedNodeCount + }; + + TypeName parsed = TypeName.Parse(typeName.AsSpan(), equal); + Assert.Equal(expectedNodeCount, parsed.GetNodeCount()); + validate(parsed); + Assert.True(TypeName.TryParse(typeName.AsSpan(), out parsed, equal)); + Assert.Equal(expectedNodeCount, parsed.GetNodeCount()); + validate(parsed); + + // Specified MaxNodes is less than the actual node count + TypeNameParseOptions less = new() { - MaxNodes = maxDepth + MaxNodes = expectedNodeCount - 1 }; - string notTooMany = $"System.Int32{string.Join("", Enumerable.Repeat(decorator, maxDepth - 1))}"; - string tooMany = $"System.Int32{string.Join("", Enumerable.Repeat(decorator, maxDepth))}"; + Assert.Throws(() => TypeName.Parse(typeName.AsSpan(), less)); + Assert.False(TypeName.TryParse(typeName.AsSpan(), out _, less)); + + // Specified MaxNodes is more than the actual node count + TypeNameParseOptions more = new() + { + MaxNodes = expectedNodeCount + 1 + }; - Assert.Throws(() => TypeName.Parse(tooMany.AsSpan(), options)); - Assert.False(TypeName.TryParse(tooMany.AsSpan(), out _, options)); + parsed = TypeName.Parse(typeName.AsSpan(), more); + Assert.Equal(expectedNodeCount, parsed.GetNodeCount()); + validate(parsed); + Assert.True(TypeName.TryParse(typeName.AsSpan(), out parsed, more)); + Assert.Equal(expectedNodeCount, parsed.GetNodeCount()); + validate(parsed); + } - TypeName parsed = TypeName.Parse(notTooMany.AsSpan(), options); - ValidateElementType(maxDepth, parsed, decorator); + [Theory] + [InlineData("*", 10)] // pointer to pointer + [InlineData("[]", 10)] // array of arrays + [InlineData("*", 100)] + [InlineData("[]", 100)] + public void MaxNodesIsRespected_Decorators(string decorator, int decoratorsCount) + { + string name = $"System.Int32{string.Join("", Enumerable.Repeat(decorator, decoratorsCount))}"; - Assert.True(TypeName.TryParse(notTooMany.AsSpan(), out parsed, options)); - ValidateElementType(maxDepth, parsed, decorator); + // Expected node count: + // - +1 for the simple type name (System.Int32) + // - +1 for every decorator + int expectedNodeCount = 1 + decoratorsCount; - static void ValidateElementType(int maxDepth, TypeName parsed, string decorator) + EnsureMaxNodesIsRespected(name, expectedNodeCount, parsed => { - for (int i = 0; i < maxDepth - 1; i++) + for (int i = 0; i < decoratorsCount; i++) { + Assert.Equal(expectedNodeCount - i, parsed.GetNodeCount()); + Assert.Equal(decorator == "*", parsed.IsPointer); Assert.Equal(decorator == "[]", parsed.IsSZArray); Assert.False(parsed.IsConstructedGenericType); + Assert.False(parsed.IsSimple); parsed = parsed.GetElementType(); } - } + }); } [Theory] [InlineData(10)] [InlineData(100)] - public void MaxNodesIsRespected_TooDeepGenerics(int maxDepth) + public void MaxNodesIsRespected_GenericsOfGenerics(int depth) { - TypeNameParseOptions options = new() - { - MaxNodes = maxDepth - }; - - string tooDeep = GetName(maxDepth); - string notTooDeep = GetName(maxDepth - 1); - - Assert.Throws(() => TypeName.Parse(tooDeep.AsSpan(), options)); - Assert.False(TypeName.TryParse(tooDeep.AsSpan(), out _, options)); - - TypeName parsed = TypeName.Parse(notTooDeep.AsSpan(), options); - Validate(maxDepth, parsed); - - Assert.True(TypeName.TryParse(notTooDeep.AsSpan(), out parsed, options)); - Validate(maxDepth, parsed); - - static string GetName(int depth) + // MakeGenericType is not used here, as it crashes for larger depths + string coreLibName = typeof(object).Assembly.FullName; + string name = typeof(int).AssemblyQualifiedName!; + for (int i = 0; i < depth; i++) { - // MakeGenericType is not used here, as it crashes for larger depths - string coreLibName = typeof(object).Assembly.FullName; - string fullName = typeof(int).AssemblyQualifiedName!; - for (int i = 0; i < depth; i++) - { - fullName = $"System.Collections.Generic.List`1[[{fullName}]], {coreLibName}"; - } - return fullName; + name = $"System.Collections.Generic.List`1[[{name}]], {coreLibName}"; } - static void Validate(int maxDepth, TypeName parsed) + // Expected node count: + // - +1 for the simple type name (System.Int32) + // - +2 * depth (+1 for the generic type definition and +1 for the constructed generic type) + int expectedNodeCount = 1 + 2 * depth; + + EnsureMaxNodesIsRespected(name, expectedNodeCount, parsed => { - for (int i = 0; i < maxDepth - 1; i++) + for (int i = 0; i < depth - 1; i++) { Assert.True(parsed.IsConstructedGenericType); parsed = parsed.GetGenericArguments()[0]; } - } + }); } [Theory] [InlineData(10)] [InlineData(100)] - public void MaxNodesIsRespected_TooManyGenericArguments(int maxDepth) + public void MaxNodesIsRespected_FlatGenericArguments(int genericArgsCount) { - TypeNameParseOptions options = new() + string name = $"Some.GenericType`{genericArgsCount}[{string.Join(",", Enumerable.Repeat("System.Int32", genericArgsCount))}]"; + + // Expected node count: + // - +1 for the constructed generic type itself + // - +1 * genericArgsCount (all arguments are simple) + // - +1 for generic type definition + int expectedNodeCount = 1 + genericArgsCount + 1; + + EnsureMaxNodesIsRespected(name, expectedNodeCount, parsed => { - MaxNodes = maxDepth - }; + Assert.True(parsed.IsConstructedGenericType); + ImmutableArray genericArgs = parsed.GetGenericArguments(); + Assert.Equal(genericArgsCount, genericArgs.Length); + Assert.All(genericArgs, arg => Assert.False(arg.IsConstructedGenericType)); + Assert.All(genericArgs, arg => Assert.Equal(1, arg.GetNodeCount())); + Assert.Equal(1, parsed.GetGenericTypeDefinition().GetNodeCount()); + Assert.Equal(expectedNodeCount, parsed.GetNodeCount()); + }); + } - string tooMany = GetName(maxDepth); - string notTooMany = GetName(maxDepth - 1); + [Theory] + [InlineData(10)] + [InlineData(100)] + public void MaxNodesIsRespected_NestedNames(int nestingDepth) + { + string name = $"Namespace.NotNestedType+{string.Join("+", Enumerable.Repeat("NestedType", nestingDepth))}"; - Assert.Throws(() => TypeName.Parse(tooMany.AsSpan(), options)); - Assert.False(TypeName.TryParse(tooMany.AsSpan(), out _, options)); + // Expected node count: + // - +1 for the nested type name itself + // - +1 * nestingDepth + int expectedNodeCount = 1 + nestingDepth; - TypeName parsed = TypeName.Parse(notTooMany.AsSpan(), options); - Validate(parsed, maxDepth); + EnsureMaxNodesIsRespected(name, expectedNodeCount, parsed => + { + Assert.True(parsed.IsNested); + Assert.Equal(expectedNodeCount, parsed.GetNodeCount()); - Assert.True(TypeName.TryParse(notTooMany.AsSpan(), out parsed, options)); - Validate(parsed, maxDepth); + int depth = nestingDepth; + while (parsed.IsNested) + { + parsed = parsed.DeclaringType; + Assert.Equal(depth, parsed.GetNodeCount()); + depth--; + } - static string GetName(int depth) - => $"Some.GenericType`{depth}[{string.Join(",", Enumerable.Repeat("System.Int32", depth))}]"; + Assert.False(parsed.IsNested); + Assert.Equal(1, parsed.GetNodeCount()); + Assert.Equal(0, depth); + }); + } - static void Validate(TypeName parsed, int maxDepth) + [Theory] + [InlineData("System.Int32*", 2)] // a pointer to a simple type + [InlineData("System.Int32[]*", 3)] // a pointer to an array of a simple type + [InlineData("System.Declaring+Nested", 2)] // a nested and declaring types + [InlineData("System.Declaring+Nested*", 3)] // a pointer to a nested type, which has the declaring type + // "Namespace.Declaring+NestedGeneric`2[A, B]" requires 5 TypeName instances: + // - constructed generic type: Namespace.Declaring+NestedGeneric`2[A, B] (+1) + // - declaring type: Namespace.Declaring (+1) + // - generic type definition: Namespace.Declaring+NestedGeneric`2 (+1) + // - declaring type is the same as of the constructed generic type (+0) + // - generic arguments: + // - generic arguments: + // - simple: A (+1) + // - simple: B (+1) + [InlineData("Namespace.Declaring+NestedGeneric`2[A, B]", 5)] + // A pointer to the above + [InlineData("Namespace.Declaring+NestedGeneric`2[A, B]*", 6)] + // A pointer to the array of the above + [InlineData("Namespace.Declaring+NestedGeneric`2[A, B][,]*", 7)] + // "Namespace.Declaring+NestedGeneric`1[AnotherGeneric`1[A]]" requires 6 TypeName instances: + // - constructed generic type: Namespace.Declaring+NestedGeneric`1[AnotherGeneric`1[A]] (+1) + // - declaring type: Namespace.Declaring (+1) + // - generic type definition: Namespace.Declaring+NestedGeneric`1 (+1) + // - declaring type is the same as of the constructed generic type (+0) + // - generic arguments: + // - constructed generic type: AnotherGeneric`1[A] (+1) + // - generic type definition: AnotherGeneric`1 (+1) + // - generic arguments: + // - simple: A (+1) + [InlineData("Namespace.Declaring+NestedGeneric`1[AnotherGeneric`1[A]]", 6)] + public void MaxNodesIsRespected(string typeName, int expectedNodeCount) + { + TypeNameParseOptions tooMany = new() { - Assert.True(parsed.IsConstructedGenericType); - ImmutableArray genericArgs = parsed.GetGenericArguments(); - Assert.Equal(maxDepth - 1, genericArgs.Length); - Assert.All(genericArgs, arg => Assert.False(arg.IsConstructedGenericType)); - } + MaxNodes = expectedNodeCount - 1 + }; + TypeNameParseOptions notTooMany = new() + { + MaxNodes = expectedNodeCount + }; + + Assert.Throws(() => TypeName.Parse(typeName.AsSpan(), tooMany)); + Assert.False(TypeName.TryParse(typeName.AsSpan(), out _, tooMany)); + + TypeName parsed = TypeName.Parse(typeName.AsSpan(), notTooMany); + Assert.Equal(expectedNodeCount, parsed.GetNodeCount()); + + Assert.True(TypeName.TryParse(typeName.AsSpan(), out parsed, notTooMany)); + Assert.Equal(expectedNodeCount, parsed.GetNodeCount()); } public static IEnumerable GenericArgumentsAreSupported_Arguments() @@ -471,10 +559,10 @@ public static IEnumerable GetAdditionalConstructedTypeData() [InlineData(typeof(int[,][]), 3)] [InlineData(typeof(Nullable<>), 1)] // open generic type treated as elemental [InlineData(typeof(NestedNonGeneric_0), 2)] // declaring and nested - [InlineData(typeof(NestedGeneric_0), 3)] // declaring, nested and generic arg + [InlineData(typeof(NestedGeneric_0), 4)] // declaring, nested, generic arg and generic type definition [InlineData(typeof(NestedNonGeneric_0.NestedNonGeneric_1), 3)] // declaring, nested 0 and nested 1 // TypeNameTests+NestedGeneric_0`1+NestedGeneric_1`2[[Int32],[String],[Boolean]] (simplified for brevity) - [InlineData(typeof(NestedGeneric_0.NestedGeneric_1), 6)] // declaring, nested 0 and nested 1 and 3 generic args + [InlineData(typeof(NestedGeneric_0.NestedGeneric_1), 7)] // declaring, nested 0 and nested 1 and 3 generic args and generic type definition [MemberData(nameof(GetAdditionalConstructedTypeData))] public void GetNodeCountReturnsExpectedValue(Type type, int expected) { @@ -493,6 +581,26 @@ public void GetNodeCountReturnsExpectedValue(Type type, int expected) } } + [OuterLoop("It takes a lot of time")] + [Fact] + public void GetNodeCountThrowsForInt32Overflow() + { + TypeName genericType = TypeName.Parse("Generic".AsSpan()); + TypeName genericArg = TypeName.Parse("Arg".AsSpan()); + // Don't allocate Array.MaxLength array as it may make this test flaky (frequent OOMs). + ImmutableArray.Builder genericArgs = ImmutableArray.CreateBuilder(initialCapacity: (int)Math.Sqrt(int.MaxValue)); + for (int i = 0; i < genericArgs.Capacity; ++i) + { + genericArgs.Add(genericArg); + } + TypeName constructedGenericType = genericType.MakeGenericTypeName(genericArgs.MoveToImmutable()); + // Just repeat the same reference to a large closed generic type multiple times. + // It's going to give us large node count without allocating too much. + TypeName largeNodeCount = genericType.MakeGenericTypeName(Enumerable.Repeat(constructedGenericType, (int)Math.Sqrt(int.MaxValue)).ToImmutableArray()); + + Assert.Throws(() => largeNodeCount.GetNodeCount()); + } + [Fact] public void MakeGenericTypeName() { @@ -705,6 +813,18 @@ public void TheNumberAfterBacktickDoesNotEnforceGenericArgCount(string input, st Assert.Equal("bool", parsed.GetGenericArguments()[1].Name); } + [Fact] + public void ArrayRank_SByteOverflow() + { + const string Input = "WeDontEnforceAnyMaxArrayRank[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]"; + + TypeName typeName = TypeName.Parse(Input.AsSpan()); + + Assert.Equal(Input, typeName.FullName); + Assert.True(typeName.IsArray); + Assert.Equal(128, typeName.GetArrayRank()); + } + [Theory] [InlineData(typeof(int))] [InlineData(typeof(int?))] From 496a16cf11eb60a73f96fc8a8273c8cf449f8c26 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 12 Sep 2024 14:12:18 -0600 Subject: [PATCH 21/34] Fix heap corruption issue in PriorityQueue.Remove (#107603) Co-authored-by: Eirik Tsarpalis --- .../Collections/Generic/PriorityQueue.cs | 20 +++++++++++--- .../PriorityQueue/PriorityQueue.Tests.cs | 27 +++++++++++++++++++ 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Collections/src/System/Collections/Generic/PriorityQueue.cs b/src/libraries/System.Collections/src/System/Collections/Generic/PriorityQueue.cs index 5047b76433738..c4d66bf14fd53 100644 --- a/src/libraries/System.Collections/src/System/Collections/Generic/PriorityQueue.cs +++ b/src/libraries/System.Collections/src/System/Collections/Generic/PriorityQueue.cs @@ -532,16 +532,30 @@ public bool Remove( if (index < newSize) { // We're removing an element from the middle of the heap. - // Pop the last element in the collection and sift downward from the removed index. + // Pop the last element in the collection and sift from the removed index. (TElement Element, TPriority Priority) lastNode = nodes[newSize]; if (_comparer == null) { - MoveDownDefaultComparer(lastNode, index); + if (Comparer.Default.Compare(lastNode.Priority, priority) < 0) + { + MoveUpDefaultComparer(lastNode, index); + } + else + { + MoveDownDefaultComparer(lastNode, index); + } } else { - MoveDownCustomComparer(lastNode, index); + if (_comparer.Compare(lastNode.Priority, priority) < 0) + { + MoveUpCustomComparer(lastNode, index); + } + else + { + MoveDownCustomComparer(lastNode, index); + } } } diff --git a/src/libraries/System.Collections/tests/Generic/PriorityQueue/PriorityQueue.Tests.cs b/src/libraries/System.Collections/tests/Generic/PriorityQueue/PriorityQueue.Tests.cs index 03419ab9f6af2..e5bd24a5dbf53 100644 --- a/src/libraries/System.Collections/tests/Generic/PriorityQueue/PriorityQueue.Tests.cs +++ b/src/libraries/System.Collections/tests/Generic/PriorityQueue/PriorityQueue.Tests.cs @@ -266,6 +266,33 @@ public void PriorityQueue_EmptyCollection_Remove_ShouldReturnFalse() Assert.Null(removedPriority); } + [Fact] + public void PriorityQueue_LargeCollection_Remove_ShouldPreserveHeapInvariant() + { + // Regression test for https://github.com/dotnet/runtime/issues/107292 + + PriorityQueue queue = new(); + for (int i = 19; i >= 0; i--) + { + queue.Enqueue(i, i); + } + + queue.Remove(10, out int _, out int _); + + List sortedValues = queue.UnorderedItems + .OrderBy(e => e.Priority) + .Select(e => e.Element) + .ToList(); + + List dequeuedValues = new(); + while (queue.Count > 0) + { + dequeuedValues.Add(queue.Dequeue()); + } + + Assert.Equal(sortedValues, dequeuedValues); + } + #region EnsureCapacity, TrimExcess [Fact] From 3dfee09bb15297ae5dc3fd1208ca3337cefd75c2 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 12 Sep 2024 14:15:48 -0600 Subject: [PATCH 22/34] Update dependencies from https://github.com/dotnet/arcade build 20240909.6 (#107611) Microsoft.SourceBuild.Intermediate.arcade , 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.XliffTasks , Microsoft.DotNet.XUnitAssert , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 9.0.0-beta.24453.1 -> To Version 9.0.0-beta.24459.6 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 84 ++++++++++++++++++++--------------------- eng/Versions.props | 32 ++++++++-------- global.json | 6 +-- 3 files changed, 61 insertions(+), 61 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 95b4b96b8dbb4..12d3d733dc872 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -88,87 +88,87 @@ - + https://github.com/dotnet/arcade - dd332f2d4e21daa8b79f84251ab156af9a0b11b2 + 65260b148c869ada772a5843863c54737cd2361e - + https://github.com/dotnet/arcade - dd332f2d4e21daa8b79f84251ab156af9a0b11b2 + 65260b148c869ada772a5843863c54737cd2361e - + https://github.com/dotnet/arcade - dd332f2d4e21daa8b79f84251ab156af9a0b11b2 + 65260b148c869ada772a5843863c54737cd2361e - + https://github.com/dotnet/arcade - dd332f2d4e21daa8b79f84251ab156af9a0b11b2 + 65260b148c869ada772a5843863c54737cd2361e - + https://github.com/dotnet/arcade - dd332f2d4e21daa8b79f84251ab156af9a0b11b2 + 65260b148c869ada772a5843863c54737cd2361e - + https://github.com/dotnet/arcade - dd332f2d4e21daa8b79f84251ab156af9a0b11b2 + 65260b148c869ada772a5843863c54737cd2361e - + https://github.com/dotnet/arcade - dd332f2d4e21daa8b79f84251ab156af9a0b11b2 + 65260b148c869ada772a5843863c54737cd2361e - + https://github.com/dotnet/arcade - dd332f2d4e21daa8b79f84251ab156af9a0b11b2 + 65260b148c869ada772a5843863c54737cd2361e - + https://github.com/dotnet/arcade - dd332f2d4e21daa8b79f84251ab156af9a0b11b2 + 65260b148c869ada772a5843863c54737cd2361e - + https://github.com/dotnet/arcade - dd332f2d4e21daa8b79f84251ab156af9a0b11b2 + 65260b148c869ada772a5843863c54737cd2361e - + https://github.com/dotnet/arcade - dd332f2d4e21daa8b79f84251ab156af9a0b11b2 + 65260b148c869ada772a5843863c54737cd2361e - + https://github.com/dotnet/arcade - dd332f2d4e21daa8b79f84251ab156af9a0b11b2 + 65260b148c869ada772a5843863c54737cd2361e - + https://github.com/dotnet/arcade - dd332f2d4e21daa8b79f84251ab156af9a0b11b2 + 65260b148c869ada772a5843863c54737cd2361e - + https://github.com/dotnet/arcade - dd332f2d4e21daa8b79f84251ab156af9a0b11b2 + 65260b148c869ada772a5843863c54737cd2361e - + https://github.com/dotnet/arcade - dd332f2d4e21daa8b79f84251ab156af9a0b11b2 + 65260b148c869ada772a5843863c54737cd2361e - + https://github.com/dotnet/arcade - dd332f2d4e21daa8b79f84251ab156af9a0b11b2 + 65260b148c869ada772a5843863c54737cd2361e - + https://github.com/dotnet/arcade - dd332f2d4e21daa8b79f84251ab156af9a0b11b2 + 65260b148c869ada772a5843863c54737cd2361e - + https://github.com/dotnet/arcade - dd332f2d4e21daa8b79f84251ab156af9a0b11b2 + 65260b148c869ada772a5843863c54737cd2361e - + https://github.com/dotnet/arcade - dd332f2d4e21daa8b79f84251ab156af9a0b11b2 + 65260b148c869ada772a5843863c54737cd2361e - + https://github.com/dotnet/arcade - dd332f2d4e21daa8b79f84251ab156af9a0b11b2 + 65260b148c869ada772a5843863c54737cd2361e https://github.com/dotnet/runtime-assets @@ -328,9 +328,9 @@ https://github.com/dotnet/xharness 9794254fa909ff5adc46326e9b54009793f61dcd - + https://github.com/dotnet/arcade - dd332f2d4e21daa8b79f84251ab156af9a0b11b2 + 65260b148c869ada772a5843863c54737cd2361e https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/eng/Versions.props b/eng/Versions.props index c4b9e2e2747eb..07bcc1757a107 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -83,22 +83,22 @@ 9.0.100-rc.1.24409.1 - 9.0.0-beta.24453.1 - 9.0.0-beta.24453.1 - 9.0.0-beta.24453.1 - 9.0.0-beta.24453.1 - 2.9.0-beta.24453.1 - 9.0.0-beta.24453.1 - 2.9.0-beta.24453.1 - 9.0.0-beta.24453.1 - 9.0.0-beta.24453.1 - 9.0.0-beta.24453.1 - 9.0.0-beta.24453.1 - 9.0.0-beta.24453.1 - 9.0.0-beta.24453.1 - 9.0.0-beta.24453.1 - 9.0.0-beta.24453.1 - 9.0.0-beta.24453.1 + 9.0.0-beta.24459.6 + 9.0.0-beta.24459.6 + 9.0.0-beta.24459.6 + 9.0.0-beta.24459.6 + 2.9.0-beta.24459.6 + 9.0.0-beta.24459.6 + 2.9.0-beta.24459.6 + 9.0.0-beta.24459.6 + 9.0.0-beta.24459.6 + 9.0.0-beta.24459.6 + 9.0.0-beta.24459.6 + 9.0.0-beta.24459.6 + 9.0.0-beta.24459.6 + 9.0.0-beta.24459.6 + 9.0.0-beta.24459.6 + 9.0.0-beta.24459.6 1.4.0 diff --git a/global.json b/global.json index e8b6c544ced98..08435128e0833 100644 --- a/global.json +++ b/global.json @@ -8,9 +8,9 @@ "dotnet": "9.0.100-preview.7.24407.12" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24453.1", - "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24453.1", - "Microsoft.DotNet.SharedFramework.Sdk": "9.0.0-beta.24453.1", + "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24459.6", + "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24459.6", + "Microsoft.DotNet.SharedFramework.Sdk": "9.0.0-beta.24459.6", "Microsoft.Build.NoTargets": "3.7.0", "Microsoft.Build.Traversal": "3.4.0", "Microsoft.NET.Sdk.IL": "9.0.0-rc.1.24410.5" From db5dcbf3f3ec5a2213bfee2bb1f574c2dd2df1b9 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 12 Sep 2024 14:16:40 -0600 Subject: [PATCH 23/34] Update dependencies from https://github.com/dotnet/source-build-externals build 20240909.2 (#107607) Microsoft.SourceBuild.Intermediate.source-build-externals From Version 9.0.0-alpha.1.24452.1 -> To Version 9.0.0-alpha.1.24459.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 12d3d733dc872..1d015ff53eea0 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -81,9 +81,9 @@ - + https://github.com/dotnet/source-build-externals - eab3dc5eabdf8bcd9bbdf917741aab335c74373d + 71b0a48963717f08dc2d3d26527a2587316170fc From a1f25d8b1fa9ffb3ffc0b2ccad7791e64c80258f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 12 Sep 2024 13:21:11 -0700 Subject: [PATCH 24/34] [release/9.0] [DiagnosticSource] Add version event to EventSources used for out-of-proc monitoring (#107748) * Add a version event to DS event sources. * Tweaks. * Code review. * Code review, bug fixes, and tests. * Fix GenerateFileFromTemplate and make it work with incremental build * Test fixes and code review. * Apply suggestions from code review --------- Co-authored-by: Mikel Blanchard Co-authored-by: Eric StJohn Co-authored-by: Tarek Mahmoud Sayed <10833894+tarekgh@users.noreply.github.com> --- ...System.Diagnostics.DiagnosticSource.csproj | 23 ++++++++++++ .../DiagnosticSourceEventSource.cs | 17 +++++++++ .../Diagnostics/Metrics/MetricsEventSource.cs | 17 +++++++++ .../src/ThisAssembly.cs.in | 11 ++++++ .../DiagnosticSourceEventSourceBridgeTests.cs | 37 +++++++++++++++++++ .../tests/MetricEventSourceTests.cs | 35 +++++++++++++++++- 6 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 src/libraries/System.Diagnostics.DiagnosticSource/src/ThisAssembly.cs.in 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 3db1dbd5a06ef..2316c532efb58 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj @@ -89,6 +89,10 @@ System.Diagnostics.DiagnosticSource + + + + @@ -154,4 +158,23 @@ System.Diagnostics.DiagnosticSource + + + + + + + + + + + + + diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs index 065e81ccdac09..673671b3ad52c 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs @@ -349,12 +349,29 @@ public void ActivityStart(string SourceName, string ActivityName, IEnumerable> Arguments) => WriteEvent(12, SourceName, ActivityName, Arguments); + /// + /// Used to send version information. + /// + [Event(13, Keywords = Keywords.Messages)] + public void Version(int Major, int Minor, int Patch) + { + WriteEvent(13, Major, Minor, Patch); + } + /// /// Called when the EventSource gets a command from a EventListener or ETW. /// [NonEvent] protected override void OnEventCommand(EventCommandEventArgs command) { + if (command.Command == EventCommand.Enable) + { + Version( + ThisAssembly.AssemblyFileVersion.Major, + ThisAssembly.AssemblyFileVersion.Minor, + ThisAssembly.AssemblyFileVersion.Build); + } + // On every command (which the debugger can force by turning on this EventSource with ETW) // call a function that the debugger can hook to do an arbitrary func evaluation. BreakPointWithDebuggerFuncEval(); 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 70b74e9613f06..295e1eecf9e81 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 @@ -277,12 +277,29 @@ public void MultipleSessionsConfiguredIncorrectlyError(string clientId, string e WriteEvent(17, clientId, expectedMaxHistograms, actualMaxHistograms, expectedMaxTimeSeries, actualMaxTimeSeries, expectedRefreshInterval, actualRefreshInterval); } + /// + /// Used to send version information. + /// + [Event(18, Keywords = Keywords.Messages)] + public void Version(int Major, int Minor, int Patch) + { + WriteEvent(18, Major, Minor, Patch); + } + /// /// Called when the EventSource gets a command from a EventListener or ETW. /// [NonEvent] protected override void OnEventCommand(EventCommandEventArgs command) { + if (command.Command == EventCommand.Enable) + { + Version( + ThisAssembly.AssemblyFileVersion.Major, + ThisAssembly.AssemblyFileVersion.Minor, + ThisAssembly.AssemblyFileVersion.Build); + } + lock (this) { Handler.OnEventCommand(command); diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/ThisAssembly.cs.in b/src/libraries/System.Diagnostics.DiagnosticSource/src/ThisAssembly.cs.in new file mode 100644 index 0000000000000..788ab480acad2 --- /dev/null +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/ThisAssembly.cs.in @@ -0,0 +1,11 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Diagnostics; + +internal static class ThisAssembly +{ + private const string BuildAssemblyFileVersion = "${AssemblyFileVersion}"; + + public static Version AssemblyFileVersion { get; } = new(BuildAssemblyFileVersion); +} diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/DiagnosticSourceEventSourceBridgeTests.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/DiagnosticSourceEventSourceBridgeTests.cs index 136e33807a48f..311d9732ba3d5 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/DiagnosticSourceEventSourceBridgeTests.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/DiagnosticSourceEventSourceBridgeTests.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics.Tracing; +using System.Reflection; using System.Text; using System.Threading; using Microsoft.DotNet.RemoteExecutor; @@ -959,6 +960,42 @@ public void TestMessages() }).Dispose(); } + // Tests that version event from DiagnosticSourceEventSource is fired. + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public void TestVersion() + { + RemoteExecutor.Invoke(static () => + { + Activity a = new Activity("test"); // we need this to ensure DiagnosticSourceEventSource.Logger creation. + + using (var eventSourceListener = new TestDiagnosticSourceEventListener()) + { + Assert.Equal(0, eventSourceListener.EventCount); + + Version? version = null; + + eventSourceListener.OtherEventWritten += delegate (EventWrittenEventArgs evnt) + { + if (evnt.EventName == "Version") + { + version = new( + (int)evnt.Payload[0], + (int)evnt.Payload[1], + (int)evnt.Payload[2]); + } + }; + + eventSourceListener.Enable(""); + Assert.Equal(0, eventSourceListener.EventCount); + + Assert.NotNull(version); + Assert.Equal( + new Version(typeof(Activity).Assembly.GetCustomAttribute()?.Version ?? "0.0.0").ToString(3), + version.ToString()); + } + }).Dispose(); + } + /// /// Tests the feature to send the messages as EventSource Activities. /// diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricEventSourceTests.cs b/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricEventSourceTests.cs index 46ace10f70861..15bdf85ea2513 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricEventSourceTests.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricEventSourceTests.cs @@ -46,6 +46,35 @@ public void GetInstanceMethodIsReflectable() Assert.True(o is EventSource, "Expected object returned from MetricsEventSource.GetInstance() to be assignable to EventSource"); } + // Tests that version event from MetricsEventSource is fired. + [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] + public void TestVersion() + { + RemoteExecutor.Invoke(static () => + { + using var meter = new Meter("test"); // we need this to ensure MetricsEventSource.Logger creation. + + using (var eventSourceListener = new MetricsEventListener(NullTestOutputHelper.Instance, EventKeywords.All, 60)) + { + var versionEvents = eventSourceListener.Events.Where(e => e.EventName == "Version"); + + Assert.Single(versionEvents); + + var versionEvent = versionEvents.First(); + + var version = new Version( + (int)versionEvent.Payload[0], + (int)versionEvent.Payload[1], + (int)versionEvent.Payload[2]); + + Assert.NotNull(version); + Assert.Equal( + new Version(typeof(Meter).Assembly.GetCustomAttribute()?.Version ?? "0.0.0").ToString(3), + version.ToString()); + } + }).Dispose(); + } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))] [OuterLoop("Slow and has lots of console spew")] public void MultipleListeners_DifferentCounters() @@ -2102,7 +2131,11 @@ public override void Dispose() protected override void OnEventWritten(EventWrittenEventArgs eventData) { string sessionId = eventData.Payload[0].ToString(); - if (eventData.EventName != "MultipleSessionsNotSupportedError" && eventData.EventName != "MultipleSessionsConfiguredIncorrectlyError" && sessionId != "" && sessionId != _sessionId) + if (eventData.EventName != "MultipleSessionsNotSupportedError" + && eventData.EventName != "MultipleSessionsConfiguredIncorrectlyError" + && eventData.EventName != "Version" + && sessionId != "" + && sessionId != _sessionId) { return; } From bef9c4abf047ec25fd864112d3a8e6071b4aa59b Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Thu, 12 Sep 2024 13:23:03 -0700 Subject: [PATCH 25/34] [release/9.0] Backport some PACKAGE.md files (#107724) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Provide System.Composition package readme (#106443) * Provide System.Composition package readme * Fix empty lines * Provide System.Composition.AttributedModel package readme (#106781) * Provide System.Composition.AttributedModel package readme * Improve after feedback * Set correct PackageDescription * Provide System.Composition.Convention package readme (#106782) * Provide System.Composition.Convention package readme * Improve after feedback * Provide System.Composition.Hosting package readme (#106783) * Provide System.Composition.Hosting package readme * Improve after feedback * Provide System.Composition.Runtime package readme (#106784) * Provide System.Composition.Runtime package readme * Improve after feedback * Provide System.Composition.TypedParts package readme (#106785) * Provide System.Composition.TypedParts package readme * Improve after feedback * Provide System.CodeDom package readme (#107372) * Provide System.CodeDom package readme * Add remark about Roslyn/.NET Compiler SDK * Update src/libraries/System.CodeDom/src/PACKAGE.md --------- Co-authored-by: Buyaa Namnan --------- Co-authored-by: Michaël Hompus --- src/libraries/System.CodeDom/src/PACKAGE.md | 127 ++++++++++++++++ .../System.CodeDom/src/System.CodeDom.csproj | 10 +- .../src/PACKAGE.md | 140 ++++++++++++++++++ .../System.Composition.AttributedModel.csproj | 9 +- .../src/PACKAGE.md | 97 ++++++++++++ .../src/System.Composition.Convention.csproj | 11 +- .../System.Composition.Hosting/src/PACKAGE.md | 80 ++++++++++ .../src/System.Composition.Hosting.csproj | 7 +- .../System.Composition.Runtime/src/PACKAGE.md | 87 +++++++++++ .../src/System.Composition.Runtime.csproj | 7 +- .../src/PACKAGE.md | 88 +++++++++++ .../src/System.Composition.TypedParts.csproj | 8 +- .../System.Composition/src/PACKAGE.md | 77 ++++++++++ .../src/System.Composition.csproj | 13 +- 14 files changed, 703 insertions(+), 58 deletions(-) create mode 100644 src/libraries/System.CodeDom/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 diff --git a/src/libraries/System.CodeDom/src/PACKAGE.md b/src/libraries/System.CodeDom/src/PACKAGE.md new file mode 100644 index 0000000000000..2785a3e5888a3 --- /dev/null +++ b/src/libraries/System.CodeDom/src/PACKAGE.md @@ -0,0 +1,127 @@ +## About + + + +Provides functionality for dynamically generating and compiling source code using the Code Document Object Model (CodeDOM). + +It allows developers to represent code in a language-agnostic format and then generate code in multiple languages, such as C# and VB.NET. +The primary use cases include creating dynamic code generation tools, runtime code generation, and facilitating code analysis or transformation. + +For a new modern development consider using the [.NET Compiler Platform SDK](https://learn.microsoft.com/dotnet/csharp/roslyn-sdk/), in particular [Roslyn source generators](https://learn.microsoft.com/dotnet/csharp/roslyn-sdk/source-generators-overview#get-started-with-source-generators). + +## Key Features + + + +* Write code using a common object model that can be translated into multiple programming languages. +* Generate and compile code at runtime based on the CodeDOM. + +## How to Use + + + +Generating and compiling C# code: + +```csharp +using System.CodeDom; +using System.CodeDom.Compiler; +using Microsoft.CSharp; + +// Create a new CodeCompileUnit to hold the code +var compileUnit = new CodeCompileUnit(); + +// Create a namespace +var codeNamespace = new CodeNamespace("MyNamespace"); +compileUnit.Namespaces.Add(codeNamespace); + +// Create a class +var classDeclaration = new CodeTypeDeclaration("MyClass") +{ + IsClass = true +}; +codeNamespace.Types.Add(classDeclaration); + +// Add a simple method to the class +var method = new CodeMemberMethod +{ + Name = "HelloWorld", + ReturnType = new CodeTypeReference(typeof(void)), +}; +classDeclaration.Members.Add(method); + +var methodInvocation = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("Console"), + "WriteLine", + new CodePrimitiveExpression("Hello, World!")); +method.Statements.Add(methodInvocation); + +// Generate C# code from the CodeDOM structure +CodeDomProvider provider = new CSharpCodeProvider(); + +using (var writer = new StringWriter()) +{ + var codeGenereationOptions = new CodeGeneratorOptions() + { + BlankLinesBetweenMembers = false, + IndentString = " ", + }; + + provider.GenerateCodeFromCompileUnit(compileUnit, writer, codeGenereationOptions); + Console.WriteLine(writer.GetStringBuilder().ToString()); +} +``` + +This example generates: + +```csharp +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace MyNamespace { + + public class MyClass { + private void HelloWorld() { + Console.WriteLine("Hello, World!"); + } + } +} +``` + +## Main Types + + + +The main types provided by this library are: + +* `System.CodeDom.CodeObject` +* `System.CodeDom.CodeCompileUnit` +* `System.CodeDom.CodeNamespace` +* `System.CodeDom.CodeTypeDeclaration` +* `System.CodeDom.CodeMemberMethod` +* `System.CodeDom.CodeTypeReference` +* `System.CodeDom.CodeMethodInvokeExpression` +* `System.CodeDom.CodeTypeReferenceExpression` +* `System.CodeDom.CodePrimitiveExpression` +* `System.CodeDom.Compiler.CodeDomProvider` +* `System.CodeDom.Compiler.CodeGeneratorOptions` +* `Microsoft.CSharp.CSharpCodeProvider` +* `Microsoft.VisualBasic.VBCodeProvider` + +## Additional Documentation + + + +* [API documentation](https://learn.microsoft.com/dotnet/api/system.codedom) +* [Compile and generate dynamic source code](https://learn.microsoft.com/dotnet/framework/reflection-and-codedom/dynamic-source-code-generation-and-compilation) + +## Feedback & Contributing + + + +System.CodeDom 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.CodeDom/src/System.CodeDom.csproj b/src/libraries/System.CodeDom/src/System.CodeDom.csproj index a987278ff0539..76ba0e1a9d3f6 100644 --- a/src/libraries/System.CodeDom/src/System.CodeDom.csproj +++ b/src/libraries/System.CodeDom/src/System.CodeDom.csproj @@ -6,19 +6,11 @@ false false true - Provides types that can be used to model the structure of a source code document and to output source code for that model in a supported language. - -Commonly Used Types: -System.CodeDom.CodeObject -System.CodeDom.Compiler.CodeDomProvider -Microsoft.CSharp.CSharpCodeProvider -Microsoft.VisualBasic.VBCodeProvider + Provides types that can be used to model the structure of a source code document and to output source code for that model in C# or Visual Basic. disable $(NoWarn);nullable - - false 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 0000000000000..57bbc8bf0329b --- /dev/null +++ b/src/libraries/System.Composition.AttributedModel/src/PACKAGE.md @@ -0,0 +1,140 @@ +## About + + + +`System.Composition.AttributedModel` is part of the Managed Extensibility Framework (MEF) 2.0, a composition library for .NET that enables dependency injection through attributes or conventions. + +This package provides the foundational attributes that allow you to declare parts for composition, such as imports, exports, and metadata. +It is used to mark classes, properties, methods, and constructors for MEF's discovery and composition process. + +## Key Features + + + +* Provides attributes for declaring composable parts, importing dependencies, metadata, and creating shared or non-shared parts + +## How to Use + + + +Mark classes for export and import using attributes. + +```csharp +using System.Composition; +using System.Composition.Hosting; + +var configuration = new ContainerConfiguration() + .WithPart() + .WithPart(); + +using CompositionHost container = configuration.CreateContainer(); + +Application app = container.GetExport(); +app.Service.Execute(); +// Service is running! + +[Export] +public class Application +{ + [Import] + public Service Service { get; set; } +} + +[Export] +public class Service +{ + public void Execute() => Console.WriteLine("Service is running!"); +} +``` + +Metadata can be used to differentiate between multiple exports of the same contract. + +```csharp +using System.Composition; +using System.Composition.Hosting; + +ContainerConfiguration configuration = new ContainerConfiguration() + .WithPart() + .WithPart() + .WithPart(); + +using CompositionHost container = configuration.CreateContainer(); + +Application app = container.GetExport(); +app.Run(); +// Using FileLogger to log. +// FileLogger: Hello, World! +// Using ConsoleLogger to log. +// ConsoleLogger: Hello, World! + +public interface ILogger +{ + void Log(string message); +} + +[Export(typeof(ILogger))] +[ExportMetadata("Name", "FileLogger")] +public class FileLogger : ILogger +{ + public void Log(string message) => Console.WriteLine($"FileLogger: {message}"); +} + +[Export(typeof(ILogger))] +[ExportMetadata("Name", "ConsoleLogger")] +public class ConsoleLogger : ILogger +{ + public void Log(string message) => Console.WriteLine($"ConsoleLogger: {message}"); +} + +[Export] +public class Application +{ + [ImportMany] + public required IEnumerable>> Loggers { get; set; } + + public void Run() + { + foreach (var logger in Loggers) + { + var name = logger.Metadata["Name"]; + + Console.WriteLine($"Using {name} to log."); + logger.Value.Log("Hello, World!"); + } + } +} +``` + +## Main Types + + + +The main types provided by this library are: + +* `System.Composition.ExportAttribute` +* `System.Composition.ImportAttribute` +* `System.Composition.ExportMetadataAttribute` + +## Additional Documentation + + + +* [API documentation](https://learn.microsoft.com/dotnet/api/system.composition) +* [Managed Extensibility Framework (MEF)](https://learn.microsoft.com/dotnet/framework/mef/) + +## Related Packages + + + +* [System.Composition](https://www.nuget.org/packages/System.Composition) +* [System.Composition.Convention](https://www.nuget.org/packages/System.Composition.Convention) +* [System.Composition.Hosting](https://www.nuget.org/packages/System.Composition.Hosting) +* [System.Composition.Runtime](https://www.nuget.org/packages/System.Composition.Runtime) +* [System.Composition.TypedParts](https://www.nuget.org/packages/System.Composition.TypedParts) + +## Feedback & Contributing + + + +System.Composition.AttributedModel 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.Composition.AttributedModel/src/System.Composition.AttributedModel.csproj b/src/libraries/System.Composition.AttributedModel/src/System.Composition.AttributedModel.csproj index 21e5bd32d21de..44856544cf5dd 100644 --- a/src/libraries/System.Composition.AttributedModel/src/System.Composition.AttributedModel.csproj +++ b/src/libraries/System.Composition.AttributedModel/src/System.Composition.AttributedModel.csproj @@ -5,17 +5,10 @@ Microsoft false true - Provides common attributes used by System.Composition types. - -Commonly Used Types: -System.Composition.ExportAttribute -System.Composition.ImportAttribute -System.Composition.Convention.AttributedModelProvider + Provides the foundational attributes that allow you to declare parts for composition, such as imports, exports, and metadata with the Managed Extensibility Framework (MEF). disable $(NoWarn);nullable - - false 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 0000000000000..4f6e1fdc2358c --- /dev/null +++ b/src/libraries/System.Composition.Convention/src/PACKAGE.md @@ -0,0 +1,97 @@ +## About + + + +`System.Composition.Convention` is part of the Managed Extensibility Framework (MEF) 2.0, a composition library for .NET that enables dependency injection through attributes or conventions. + +This package simplifies the process of applying consistent patterns for part exports, imports, and metadata by using convention-based configurations. +It is useful for scenarios where you want to avoid repetitive attribute-based decoration and instead define conventions for registering types in your composition container. + +## Key Features + + + +* Configure exports, imports, and metadata for parts using conventions rather than attributes. +* Allows defining conventions through a fluent API, making configuration more flexible and readable. + +## How to Use + + + +Configure parts for composition without using attributes. + +```csharp +using System.Composition.Convention; +using System.Composition.Hosting; + +var conventions = new ConventionBuilder(); + +// Apply conventions: any class that implements ILogger will be exported as ILogger +conventions + .ForTypesDerivedFrom() + .Export(); + +var configuration = new ContainerConfiguration() + .WithPart(conventions) + .WithPart(conventions); + +using CompositionHost container = configuration.CreateContainer(); + +var loggers = container.GetExports(); + +foreach (var logger in loggers) +{ + logger.Log("Hello, World!"); +} +// FileLogger: Hello, World! +// ConsoleLogger: Hello, World! + +public interface ILogger +{ + void Log(string message); +} + +public class FileLogger : ILogger +{ + public void Log(string message) => Console.WriteLine($"FileLogger: {message}"); +} + +public class ConsoleLogger : ILogger +{ + public void Log(string message) => Console.WriteLine($"ConsoleLogger: {message}"); +} +``` + +## Main Types + + + +The main types provided by this library are: + +* `System.Composition.Convention.ConventionBuilder` +* `System.Composition.Convention.PartConventionBuilder` +* `System.Composition.Convention.ParameterImportConventionBuilder` + +## Additional Documentation + + + +* [API documentation](https://learn.microsoft.com/dotnet/api/system.composition.convention) +* [Managed Extensibility Framework (MEF)](https://learn.microsoft.com/dotnet/framework/mef/) + +## Related Packages + + + +* [System.Composition](https://www.nuget.org/packages/System.Composition) +* [System.Composition.AttributedModel](https://www.nuget.org/packages/System.Composition.AttributedModel) +* [System.Composition.Hosting](https://www.nuget.org/packages/System.Composition.Hosting) +* [System.Composition.Runtime](https://www.nuget.org/packages/System.Composition.Runtime) +* [System.Composition.TypedParts](https://www.nuget.org/packages/System.Composition.TypedParts) + +## Feedback & Contributing + + + +System.Composition.Convention 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.Composition.Convention/src/System.Composition.Convention.csproj b/src/libraries/System.Composition.Convention/src/System.Composition.Convention.csproj index 8e1f44ee3df72..2544944eec76e 100644 --- a/src/libraries/System.Composition.Convention/src/System.Composition.Convention.csproj +++ b/src/libraries/System.Composition.Convention/src/System.Composition.Convention.csproj @@ -6,19 +6,10 @@ Microsoft false true - Provides types that support using Managed Extensibility Framework with a convention-based configuration model. - -Commonly Used Types: -System.Composition.Convention.ConventionBuilder -System.Composition.Convention.ExportConventionBuilder -System.Composition.Convention.ImportConventionBuilder -System.Composition.Convention.PartConventionBuilder -System.Composition.Convention.ParameterImportConventionBuilder + Provides types that support using Managed Extensibility Framework (MEF) with a convention-based configuration model. disable $(NoWarn);nullable - - false 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 0000000000000..9f5556e7a4d7b --- /dev/null +++ b/src/libraries/System.Composition.Hosting/src/PACKAGE.md @@ -0,0 +1,80 @@ +## About + + + +`System.Composition.Hosting` is part of the Managed Extensibility Framework (MEF) 2.0, a composition library for .NET that enables dependency injection through attributes or conventions. + +This package provides core services for creating composition containers. +It offers tools to configure and manage the composition of parts within your application, facilitating dependency injection and enabling modular architectures. + +## Key Features + + + +* Create and manage composition containers for dynamic dependency injection. + +## How to Use + + + +Create a composition host and compose parts. + +```csharp +using System.Composition; +using System.Composition.Hosting; + +// Create a container configuration +var configuration = new ContainerConfiguration() + .WithPart(); + +// Create the composition host (container) +using CompositionHost container = configuration.CreateContainer(); + +// Get an instance of the service +var service = container.GetExport(); +service.Run(); +// Service is running! + +public interface IService +{ + void Run(); +} + +[Export(typeof(IService))] +public class Service : IService +{ + public void Run() => Console.WriteLine("Service is running!"); +} +``` + +## Main Types + + + +The main type provided by this library is: + +* `System.Composition.CompositionHost` + +## Additional Documentation + + + +* [API documentation](https://learn.microsoft.com/dotnet/api/system.composition.hosting) +* [Managed Extensibility Framework (MEF)](https://learn.microsoft.com/dotnet/framework/mef/) + +## Related Packages + + + +* [System.Composition](https://www.nuget.org/packages/System.Composition) +* [System.Composition.AttributedModel](https://www.nuget.org/packages/System.Composition.AttributedModel) +* [System.Composition.Convention](https://www.nuget.org/packages/System.Composition.Convention) +* [System.Composition.Runtime](https://www.nuget.org/packages/System.Composition.Runtime) +* [System.Composition.TypedParts](https://www.nuget.org/packages/System.Composition.TypedParts) + +## Feedback & Contributing + + + +System.Composition.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). diff --git a/src/libraries/System.Composition.Hosting/src/System.Composition.Hosting.csproj b/src/libraries/System.Composition.Hosting/src/System.Composition.Hosting.csproj index cd017f48b6939..18d027e8ad14b 100644 --- a/src/libraries/System.Composition.Hosting/src/System.Composition.Hosting.csproj +++ b/src/libraries/System.Composition.Hosting/src/System.Composition.Hosting.csproj @@ -7,15 +7,10 @@ Microsoft false true - Provides Managed Extensibility Framework types that are useful to developers of extensible applications, or hosts. - -Commonly Used Types: -System.Composition.Hosting.CompositionHost + Provides Managed Extensibility Framework (MEF) types that are useful to developers of extensible applications, or hosts. disable $(NoWarn);nullable - - false 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 0000000000000..177bb8026881e --- /dev/null +++ b/src/libraries/System.Composition.Runtime/src/PACKAGE.md @@ -0,0 +1,87 @@ +## About + + + +`System.Composition.Runtime` is part of the Managed Extensibility Framework (MEF) 2.0, a composition library for .NET that enables dependency injection through attributes or conventions. + +This package enables the discovery and composition of parts in applications using MEF 2.0. +It offers the runtime implementation needed for managing composable parts, resolving dependencies, and dynamically wiring components together. + +## Key Features + + + +* Facilitates runtime discovery and composition of parts. + +## How to Use + + + +Resolve dependencies on the fly and can be useful for dynamically loaded components or plugins. + +```csharp +using System.Composition; +using System.Composition.Hosting; + +var configuration = new ContainerConfiguration() + .WithPart(); + +using CompositionHost container = configuration.CreateContainer(); + +var consumer = new Consumer(container); +consumer.Execute(); +// Service is running. + +public interface IService +{ + void Run(); +} + +[Export(typeof(IService))] +public class Service : IService +{ + public void Run() => Console.WriteLine("Service is running."); +} + +public class Consumer(CompositionContext context) +{ + public void Execute() + { + // Use the context to resolve the service + var service = context.GetExport(); + service.Run(); + } +} +``` + +## Main Types + + + +The main type provided by this library is: + +* `System.Composition.CompositionContext` + +## Additional Documentation + + + +* [API documentation](https://learn.microsoft.com/dotnet/api/system.composition.compositioncontext) +* [Managed Extensibility Framework (MEF)](https://learn.microsoft.com/dotnet/framework/mef/) + +## Related Packages + + + +* [System.Composition](https://www.nuget.org/packages/System.Composition) +* [System.Composition.AttributedModel](https://www.nuget.org/packages/System.Composition.AttributedModel) +* [System.Composition.Convention](https://www.nuget.org/packages/System.Composition.Convention) +* [System.Composition.Hosting](https://www.nuget.org/packages/System.Composition.Hosting) +* [System.Composition.TypedParts](https://www.nuget.org/packages/System.Composition.TypedParts) + +## Feedback & Contributing + + + +System.Composition.Runtime 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.Composition.Runtime/src/System.Composition.Runtime.csproj b/src/libraries/System.Composition.Runtime/src/System.Composition.Runtime.csproj index 57ee9457ea35b..93ef06e572afe 100644 --- a/src/libraries/System.Composition.Runtime/src/System.Composition.Runtime.csproj +++ b/src/libraries/System.Composition.Runtime/src/System.Composition.Runtime.csproj @@ -7,15 +7,10 @@ Microsoft false true - Contains runtime components of the Managed Extensibility Framework. - -Commonly Used Types: -System.Composition.CompositionContext + Contains runtime components of the Managed Extensibility Framework (MEF). disable $(NoWarn);nullable - - false 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 0000000000000..de02f4525c866 --- /dev/null +++ b/src/libraries/System.Composition.TypedParts/src/PACKAGE.md @@ -0,0 +1,88 @@ +## About + + + +`System.Composition.TypedParts` is part of the Managed Extensibility Framework (MEF) 2.0, a composition library for .NET that enables dependency injection through attributes or conventions. + +Provides `ContainerConfiguration` and some extension methods for the Managed Extensibility Framework (MEF). + +## Key Features + + + +* Provides container configuration. + +## How to Use + + + +Register parts from an entire assembly. + +```csharp +using System.Composition; +using System.Composition.Hosting; +using System.Reflection; + +// Register all parts from the current assembly +var configuration = new ContainerConfiguration() + .WithAssembly(Assembly.GetExecutingAssembly()); + +using CompositionHost container = configuration.CreateContainer(); + +var handlers = container.GetExports(); +foreach (var handler in handlers) +{ + handler.Handle(); +} +// HandlerA is handling. +// HandlerB is handling. + +public interface IHandler +{ + void Handle(); +} + +[Export(typeof(IHandler))] +public class HandlerA : IHandler +{ + public void Handle() => Console.WriteLine("HandlerA is handling."); +} + +[Export(typeof(IHandler))] +public class HandlerB : IHandler +{ + public void Handle() => Console.WriteLine("HandlerB is handling."); +} +``` + +## Main Types + + + +The main types provided by this library are: + +* `System.Composition.Hosting.ContainerConfiguration` +* `System.Composition.CompositionContextExtensions` + +## Additional Documentation + + + +* [Managed Extensibility Framework (MEF)](https://learn.microsoft.com/dotnet/framework/mef/) + +## Related Packages + + + +* [System.Composition](https://www.nuget.org/packages/System.Composition) +* [System.Composition.AttributedModel](https://www.nuget.org/packages/System.Composition.AttributedModel) +* [System.Composition.Convention](https://www.nuget.org/packages/System.Composition.Convention) +* [System.Composition.Hosting](https://www.nuget.org/packages/System.Composition.Hosting) +* [System.Composition.Runtime](https://www.nuget.org/packages/System.Composition.Runtime) + +## Feedback & Contributing + + + +System.Composition.TypedParts 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.Composition.TypedParts/src/System.Composition.TypedParts.csproj b/src/libraries/System.Composition.TypedParts/src/System.Composition.TypedParts.csproj index 4e82792a39994..3a2874d9d3f0b 100644 --- a/src/libraries/System.Composition.TypedParts/src/System.Composition.TypedParts.csproj +++ b/src/libraries/System.Composition.TypedParts/src/System.Composition.TypedParts.csproj @@ -8,16 +8,10 @@ Microsoft false true - Provides some extension methods for the Managed Extensibility Framework. - -Commonly Used Types: -System.Composition.CompositionContextExtensions -System.Composition.Hosting.ContainerConfiguration + Provides container configuration and some extension methods for the Managed Extensibility Framework (MEF). disable $(NoWarn);nullable - - false diff --git a/src/libraries/System.Composition/src/PACKAGE.md b/src/libraries/System.Composition/src/PACKAGE.md new file mode 100644 index 0000000000000..d6378b7ed0d56 --- /dev/null +++ b/src/libraries/System.Composition/src/PACKAGE.md @@ -0,0 +1,77 @@ +## About + + + +Provides the Managed Extensibility Framework (MEF) 2.0, a lightweight, attribute-driven Dependency Injection (DI) container. + +MEF simplifies the composition of applications by allowing components to be loosely coupled and dynamically discovered. +This package supports the development of modular and maintainable applications by enabling parts to be composed at runtime. + +## Key Features + + + +* Components are discovered and composed using attributes. +* Provides dependency injection capabilities for loosely coupled modules. + +## How to Use + + + +Running code from a discovered component. + +```csharp +using System.Composition; +using System.Composition.Hosting; + +var configuration = new ContainerConfiguration().WithPart(); + +using var container = configuration.CreateContainer(); + +var service = container.GetExport(); +service.Execute(); +// Output: Service is running! + +[Export] +public class Service +{ + public void Execute() => Console.WriteLine("Service is running!"); +} +``` + +## Main Types + + + +The main types provided by this library are: + +* `System.Composition.ExportAttribute` +* `System.Composition.ImportAttribute` +* `System.Composition.Convention.ConventionBuilder` +* `System.Composition.Hosting.CompositionHost` +* `System.Composition.CompositionContext` +* `System.Composition.CompositionContextExtensions` + +## Additional Documentation + + + +* [API documentation](https://learn.microsoft.com/dotnet/api/system.composition) +* [Managed Extensibility Framework (MEF)](https://learn.microsoft.com/dotnet/framework/mef/) + +## Related Packages + + + +* [System.Composition.AttributedModel](https://www.nuget.org/packages/System.Composition.AttributedModel) +* [System.Composition.Convention](https://www.nuget.org/packages/System.Composition.Convention) +* [System.Composition.Hosting](https://www.nuget.org/packages/System.Composition.Hosting) +* [System.Composition.Runtime](https://www.nuget.org/packages/System.Composition.Runtime) +* [System.Composition.TypedParts](https://www.nuget.org/packages/System.Composition.TypedParts) + +## Feedback & Contributing + + + +System.Composition 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.Composition/src/System.Composition.csproj b/src/libraries/System.Composition/src/System.Composition.csproj index 0d0c67320ef72..a360f80b58e2b 100644 --- a/src/libraries/System.Composition/src/System.Composition.csproj +++ b/src/libraries/System.Composition/src/System.Composition.csproj @@ -8,21 +8,10 @@ $(NoWarn);NU5128 false - This package provides a version of the Managed Extensibility Framework (MEF) that is lightweight and specifically optimized for high throughput scenarios, such as the web. - -Commonly Used Types: -System.Composition.ExportAttribute -System.Composition.ImportAttribute -System.Composition.Convention.ConventionBuilder -System.Composition.Hosting.CompositionHost -System.Composition.CompositionContext -System.Composition.CompositionContextExtensions - + Provides a version of the Managed Extensibility Framework (MEF) that is lightweight and specifically optimized for high throughput scenarios, such as the web. disable $(NoWarn);nullable - - false From b5d252376312bb5fa87e6bbd3c42f414fb756e88 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 12 Sep 2024 13:57:57 -0700 Subject: [PATCH 26/34] [release/9.0] Fixes hang in WinUI apps published to AOT (#107751) * Fix exception during GC callback in WinUI scenarios due to removing from and adding to the nativeObjectReference list around the same time and causing removal to fail. * Move common logic * Change collection type to HashSet to match with JIT implementation and to improve performance of remove given it now takes a lock * Move to using a custom collection to protect against GC freezing threads during add / remove. * Address PR feedback by using alternative approach to handle race * Address PR feedback * Address PR feedback around handle being freed. --------- Co-authored-by: Manodasan Wignarajah Co-authored-by: Jeff Schwartz --- .../InteropServices/ComWrappers.NativeAot.cs | 264 ++++++++++++++++-- 1 file changed, 242 insertions(+), 22 deletions(-) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.NativeAot.cs index f8547cb408f8d..cc33e85d73917 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.NativeAot.cs @@ -1,7 +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; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; @@ -41,7 +41,7 @@ public abstract partial class ComWrappers private static readonly Guid IID_IWeakReferenceSource = new Guid(0x00000038, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46); private static readonly ConditionalWeakTable s_rcwTable = new ConditionalWeakTable(); - private static readonly List s_referenceTrackerNativeObjectWrapperCache = new List(); + private static readonly GCHandleSet s_referenceTrackerNativeObjectWrapperCache = new GCHandleSet(); private readonly ConditionalWeakTable _ccwTable = new ConditionalWeakTable(); private readonly Lock _lock = new Lock(useTrivialWaits: true); @@ -984,10 +984,7 @@ private unsafe bool TryGetOrCreateObjectForComInstanceInternal( throw new NotSupportedException(); } _rcwCache.Add(identity, wrapper._proxyHandle); - if (wrapper is ReferenceTrackerNativeObjectWrapper referenceTrackerNativeObjectWrapper) - { - s_referenceTrackerNativeObjectWrapperCache.Add(referenceTrackerNativeObjectWrapper._nativeObjectWrapperWeakHandle); - } + AddWrapperToReferenceTrackerHandleCache(wrapper); return true; } } @@ -1040,10 +1037,7 @@ private unsafe bool TryGetOrCreateObjectForComInstanceInternal( wrapper.Release(); throw new NotSupportedException(); } - if (wrapper is ReferenceTrackerNativeObjectWrapper referenceTrackerNativeObjectWrapper) - { - s_referenceTrackerNativeObjectWrapperCache.Add(referenceTrackerNativeObjectWrapper._nativeObjectWrapperWeakHandle); - } + AddWrapperToReferenceTrackerHandleCache(wrapper); return true; } @@ -1079,10 +1073,7 @@ private unsafe bool TryGetOrCreateObjectForComInstanceInternal( throw new NotSupportedException(); } _rcwCache.Add(identity, wrapper._proxyHandle); - if (wrapper is ReferenceTrackerNativeObjectWrapper referenceTrackerNativeObjectWrapper) - { - s_referenceTrackerNativeObjectWrapperCache.Add(referenceTrackerNativeObjectWrapper._nativeObjectWrapperWeakHandle); - } + AddWrapperToReferenceTrackerHandleCache(wrapper); } } @@ -1090,6 +1081,14 @@ private unsafe bool TryGetOrCreateObjectForComInstanceInternal( } #pragma warning restore IDE0060 + private static void AddWrapperToReferenceTrackerHandleCache(NativeObjectWrapper wrapper) + { + if (wrapper is ReferenceTrackerNativeObjectWrapper referenceTrackerNativeObjectWrapper) + { + s_referenceTrackerNativeObjectWrapperCache.Add(referenceTrackerNativeObjectWrapper._nativeObjectWrapperWeakHandle); + } + } + private void RemoveRCWFromCache(IntPtr comPointer, GCHandle expectedValue) { using (_lock.EnterScope()) @@ -1220,17 +1219,30 @@ internal static void ReleaseExternalObjectsFromCurrentThread() IntPtr contextToken = GetContextToken(); List objects = new List(); - foreach (GCHandle weakNativeObjectWrapperHandle in s_referenceTrackerNativeObjectWrapperCache) + + // Here we aren't part of a GC callback, so other threads can still be running + // who are adding and removing from the collection. This means we can possibly race + // with a handle being removed and freed and we can end up accessing a freed handle. + // To avoid this, we take a lock on modifications to the collection while we gather + // the objects. + using (s_referenceTrackerNativeObjectWrapperCache.ModificationLock.EnterScope()) { - ReferenceTrackerNativeObjectWrapper? nativeObjectWrapper = Unsafe.As(weakNativeObjectWrapperHandle.Target); - if (nativeObjectWrapper != null && - nativeObjectWrapper._contextToken == contextToken) + foreach (GCHandle weakNativeObjectWrapperHandle in s_referenceTrackerNativeObjectWrapperCache) { - objects.Add(nativeObjectWrapper._proxyHandle.Target); + ReferenceTrackerNativeObjectWrapper? nativeObjectWrapper = Unsafe.As(weakNativeObjectWrapperHandle.Target); + if (nativeObjectWrapper != null && + nativeObjectWrapper._contextToken == contextToken) + { + object? target = nativeObjectWrapper._proxyHandle.Target; + if (target != null) + { + objects.Add(target); + } - // Separate the wrapper from the tracker runtime prior to - // passing them. - nativeObjectWrapper.DisconnectTracker(); + // Separate the wrapper from the tracker runtime prior to + // passing them. + nativeObjectWrapper.DisconnectTracker(); + } } } @@ -1630,4 +1642,212 @@ private static unsafe IntPtr ObjectToComWeakRef(object target, out long wrapperI return IntPtr.Zero; } } + + // This is a GCHandle HashSet implementation based on LowLevelDictionary. + // It uses no locking for readers. While for writers (add / remove), + // it handles the locking itself. + // This implementation specifically makes sure that any readers of this + // collection during GC aren't impacted by other threads being + // frozen while in the middle of an write. It makes no guarantees on + // whether you will observe the element being added / removed, but does + // make sure the collection is in a good state and doesn't run into issues + // while iterating. + internal sealed class GCHandleSet : IEnumerable + { + private const int DefaultSize = 7; + + private Entry?[] _buckets = new Entry[DefaultSize]; + private int _numEntries; + private readonly Lock _lock = new Lock(useTrivialWaits: true); + + public Lock ModificationLock => _lock; + + public void Add(GCHandle handle) + { + using (_lock.EnterScope()) + { + int bucket = GetBucket(handle, _buckets.Length); + Entry? prev = null; + Entry? entry = _buckets[bucket]; + while (entry != null) + { + // Handle already exists, nothing to add. + if (handle.Equals(entry.m_value)) + { + return; + } + + prev = entry; + entry = entry.m_next; + } + + Entry newEntry = new Entry() + { + m_value = handle + }; + + if (prev == null) + { + _buckets[bucket] = newEntry; + } + else + { + prev.m_next = newEntry; + } + + // _numEntries is only maintained for the purposes of deciding whether to + // expand the bucket and is not used during iteration to handle the + // scenario where element is in bucket but _numEntries hasn't been incremented + // yet. + _numEntries++; + if (_numEntries > (_buckets.Length * 2)) + { + ExpandBuckets(); + } + } + } + + private void ExpandBuckets() + { + int newNumBuckets = _buckets.Length * 2 + 1; + Entry?[] newBuckets = new Entry[newNumBuckets]; + for (int i = 0; i < _buckets.Length; i++) + { + Entry? entry = _buckets[i]; + while (entry != null) + { + Entry? nextEntry = entry.m_next; + + int bucket = GetBucket(entry.m_value, newNumBuckets); + + // We are allocating new entries for the bucket to ensure that + // if there is an enumeration already in progress, we don't + // modify what it observes by changing next in existing instances. + Entry newEntry = new Entry() + { + m_value = entry.m_value, + m_next = newBuckets[bucket], + }; + newBuckets[bucket] = newEntry; + + entry = nextEntry; + } + } + _buckets = newBuckets; + } + + public void Remove(GCHandle handle) + { + using (_lock.EnterScope()) + { + int bucket = GetBucket(handle, _buckets.Length); + Entry? prev = null; + Entry? entry = _buckets[bucket]; + while (entry != null) + { + if (handle.Equals(entry.m_value)) + { + if (prev == null) + { + _buckets[bucket] = entry.m_next; + } + else + { + prev.m_next = entry.m_next; + } + _numEntries--; + return; + } + + prev = entry; + entry = entry.m_next; + } + } + } + + private static int GetBucket(GCHandle handle, int numBuckets) + { + int h = handle.GetHashCode(); + return (int)((uint)h % (uint)numBuckets); + } + + public Enumerator GetEnumerator() => new Enumerator(this); + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)this).GetEnumerator(); + + private sealed class Entry + { + public GCHandle m_value; + public Entry? m_next; + } + + public struct Enumerator : IEnumerator + { + private readonly Entry?[] _buckets; + private int _currentIdx; + private Entry? _currentEntry; + + public Enumerator(GCHandleSet set) + { + // We hold onto the buckets of the set rather than the set itself + // so that if it is ever expanded, we are not impacted by that during + // enumeration. + _buckets = set._buckets; + Reset(); + } + + public GCHandle Current + { + get + { + if (_currentEntry == null) + { + throw new InvalidOperationException("InvalidOperation_EnumOpCantHappen"); + } + + return _currentEntry.m_value; + } + } + + object IEnumerator.Current => Current; + + public void Dispose() + { + } + + public bool MoveNext() + { + if (_currentEntry != null) + { + _currentEntry = _currentEntry.m_next; + } + + if (_currentEntry == null) + { + // Certain buckets might be empty, so loop until we find + // one with an entry. + while (++_currentIdx != _buckets.Length) + { + _currentEntry = _buckets[_currentIdx]; + if (_currentEntry != null) + { + return true; + } + } + + return false; + } + + return true; + } + + public void Reset() + { + _currentIdx = -1; + _currentEntry = null; + } + } + } } From c3cb3e31c1835866b01209bb294eb4885e5af24a Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Thu, 12 Sep 2024 16:07:44 -0500 Subject: [PATCH 27/34] Bump to 8.0.10, 6.0.35 for downlevel (#107702) --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index 07bcc1757a107..37a40f34894d6 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -7,7 +7,7 @@ 0 0 9.0.100 - 8.0.9 + 8.0.10 7.0.20 6.0.$([MSBuild]::Add($([System.Version]::Parse('$(PackageVersionNet8)').Build),25)) rc From c6d8192481ad28dbaf6284aaf2738a70e6774960 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 12 Sep 2024 15:58:00 -0700 Subject: [PATCH 28/34] fix slag instruction (#107750) Co-authored-by: saitama951 Co-authored-by: Jeff Schwartz --- src/mono/mono/mini/mini-s390x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/mini/mini-s390x.c b/src/mono/mono/mini/mini-s390x.c index e90a0e6770e15..3419a29768c70 100644 --- a/src/mono/mono/mini/mini-s390x.c +++ b/src/mono/mono/mini/mini-s390x.c @@ -3471,7 +3471,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) s390_srag (code, ins->dreg, ins->dreg, 0, 32); break; case OP_MOVE_I4_TO_F: - s390_slag (code, s390_r0, ins->sreg1, 0, 32); + s390_sllg (code, s390_r0, ins->sreg1, 0, 32); s390_ldgr (code, ins->dreg, s390_r0); break; case OP_FCONV_TO_R4: From 9bff9c5017d8444fdf76959c112dd9fed2da9317 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 12 Sep 2024 21:33:19 -0600 Subject: [PATCH 29/34] Move UseSystemZlib into SetupOSSpecificProps (#107770) Co-authored-by: Hugo Woodiwiss --- .../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 d2696ffbcad6d..d5b7ade91d211 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets @@ -24,12 +24,12 @@ The .NET Foundation licenses this file to you under the MIT license. lld bfd 1572864 - true + true libRuntime.WorkstationGC libRuntime.ServerGC From ccfa4058a50c8e862f76c7550104bf0adae11293 Mon Sep 17 00:00:00 2001 From: Pavel Savara Date: Fri, 13 Sep 2024 17:57:35 +0200 Subject: [PATCH 30/34] log profiler (#107747) Co-authored-by: Jeff Schwartz --- .../Directory.Build.props | 1 + src/mono/browser/browser.proj | 4 +- src/mono/browser/build/BrowserWasmApp.targets | 2 + src/mono/browser/runtime/cwraps.ts | 4 +- src/mono/browser/runtime/driver.c | 12 ++++ .../browser/runtime/es6/dotnet.es6.lib.js | 2 + src/mono/browser/runtime/profiler.ts | 8 ++- src/mono/browser/runtime/startup.ts | 5 +- src/mono/browser/runtime/types/internal.ts | 7 +++ src/mono/mono.proj | 3 + src/mono/mono/mini/mini-wasm.c | 1 - src/mono/mono/profiler/CMakeLists.txt | 15 +++++ src/mono/mono/profiler/helper.c | 6 ++ src/mono/mono/profiler/log-args.c | 4 ++ src/mono/mono/profiler/log.c | 63 ++++++++++++++++++- src/mono/mono/profiler/log.h | 1 + 16 files changed, 131 insertions(+), 7 deletions(-) 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 f2379fc9ff34d..6fd91975b78a8 100644 --- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props +++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props @@ -220,6 +220,7 @@ + diff --git a/src/mono/browser/browser.proj b/src/mono/browser/browser.proj index 759fa68ae5474..669270cf332d0 100644 --- a/src/mono/browser/browser.proj +++ b/src/mono/browser/browser.proj @@ -385,8 +385,8 @@ $(ArtifactsObjDir)wasm/pinvoke-table.h $(ArtifactsObjDir)wasm/wasm_m2n_invoke.g.h - -g -Os -DDEBUG=1 -DENABLE_AOT_PROFILER=1 -DENABLE_BROWSER_PROFILER=1 - -Oz -DENABLE_BROWSER_PROFILER=1 + -g -Os -DDEBUG=1 -DENABLE_AOT_PROFILER=1 -DENABLE_BROWSER_PROFILER=1 -DENABLE_LOG_PROFILER=1 + -Oz $(CMakeConfigurationEmccFlags) -s ASSERTIONS=1 -O2 diff --git a/src/mono/browser/build/BrowserWasmApp.targets b/src/mono/browser/build/BrowserWasmApp.targets index 3b5683433fe86..79ab3cfd83313 100644 --- a/src/mono/browser/build/BrowserWasmApp.targets +++ b/src/mono/browser/build/BrowserWasmApp.targets @@ -314,6 +314,7 @@ <_EmccCFlags Include="-DLINK_ICALLS=1" Condition="'$(WasmLinkIcalls)' == 'true'" /> <_EmccCFlags Include="-DENABLE_AOT_PROFILER=1" Condition="$(WasmProfilers.Contains('aot'))" /> <_EmccCFlags Include="-DENABLE_BROWSER_PROFILER=1" Condition="$(WasmProfilers.Contains('browser'))" /> + <_EmccCFlags Include="-DENABLE_LOG_PROFILER=1" Condition="$(WasmProfilers.Contains('log'))" /> <_EmccCFlags Include="-DENABLE_JS_INTEROP_BY_VALUE=1" Condition="'$(WasmEnableJsInteropByValue)' == 'true'" /> <_EmccCFlags Include="-DGEN_PINVOKE=1" /> @@ -368,6 +369,7 @@ + diff --git a/src/mono/browser/runtime/cwraps.ts b/src/mono/browser/runtime/cwraps.ts index 2819e0c44b7f1..c65651dd95de2 100644 --- a/src/mono/browser/runtime/cwraps.ts +++ b/src/mono/browser/runtime/cwraps.ts @@ -65,9 +65,10 @@ const fn_signatures: SigLine[] = [ [false, "mono_wasm_exit", "void", ["number"]], [true, "mono_wasm_getenv", "number", ["string"]], [true, "mono_wasm_set_main_args", "void", ["number", "number"]], - // These two need to be lazy because they may be missing + // These three need to be lazy because they may be missing [() => !runtimeHelpers.emscriptenBuildOptions.enableAotProfiler, "mono_wasm_profiler_init_aot", "void", ["string"]], [() => !runtimeHelpers.emscriptenBuildOptions.enableBrowserProfiler, "mono_wasm_profiler_init_browser", "void", ["string"]], + [() => !runtimeHelpers.emscriptenBuildOptions.enableLogProfiler, "mono_wasm_profiler_init_log", "void", ["string"]], [true, "mono_wasm_profiler_init_browser", "void", ["number"]], [false, "mono_wasm_exec_regression", "number", ["number", "string"]], [false, "mono_wasm_invoke_jsexport", "void", ["number", "number"]], @@ -165,6 +166,7 @@ export interface t_ThreadingCwraps { export interface t_ProfilerCwraps { mono_wasm_profiler_init_aot(desc: string): void; mono_wasm_profiler_init_browser(desc: string): void; + mono_wasm_profiler_init_log(desc: string): void; } export interface t_Cwraps { diff --git a/src/mono/browser/runtime/driver.c b/src/mono/browser/runtime/driver.c index 1b3663e4f3f3c..2a1d5b1dbbf16 100644 --- a/src/mono/browser/runtime/driver.c +++ b/src/mono/browser/runtime/driver.c @@ -430,6 +430,18 @@ mono_wasm_profiler_init_browser (const char *desc) #endif +#ifdef ENABLE_LOG_PROFILER + +void mono_profiler_init_log (const char *desc); + +EMSCRIPTEN_KEEPALIVE void +mono_wasm_profiler_init_log (const char *desc) +{ + mono_profiler_init_log (desc); +} + +#endif + EMSCRIPTEN_KEEPALIVE void mono_wasm_init_finalizer_thread (void) { diff --git a/src/mono/browser/runtime/es6/dotnet.es6.lib.js b/src/mono/browser/runtime/es6/dotnet.es6.lib.js index 69b6c31376f9e..687025478570e 100644 --- a/src/mono/browser/runtime/es6/dotnet.es6.lib.js +++ b/src/mono/browser/runtime/es6/dotnet.es6.lib.js @@ -11,6 +11,7 @@ const WASM_ENABLE_SIMD = process.env.WASM_ENABLE_SIMD === "1"; const WASM_ENABLE_EH = process.env.WASM_ENABLE_EH === "1"; const ENABLE_BROWSER_PROFILER = process.env.ENABLE_BROWSER_PROFILER === "1"; const ENABLE_AOT_PROFILER = process.env.ENABLE_AOT_PROFILER === "1"; +const ENABLE_LOG_PROFILER = process.env.ENABLE_LOG_PROFILER === "1"; const RUN_AOT_COMPILATION = process.env.RUN_AOT_COMPILATION === "1"; var methodIndexByName = undefined; var gitHash = undefined; @@ -88,6 +89,7 @@ function injectDependencies() { `wasmEnableEH: ${WASM_ENABLE_EH ? "true" : "false"},` + `enableAotProfiler: ${ENABLE_AOT_PROFILER ? "true" : "false"}, ` + `enableBrowserProfiler: ${ENABLE_BROWSER_PROFILER ? "true" : "false"}, ` + + `enableLogProfiler: ${ENABLE_LOG_PROFILER ? "true" : "false"}, ` + `runAOTCompilation: ${RUN_AOT_COMPILATION ? "true" : "false"}, ` + `wasmEnableThreads: ${USE_PTHREADS ? "true" : "false"}, ` + `gitHash: "${gitHash}", ` + diff --git a/src/mono/browser/runtime/profiler.ts b/src/mono/browser/runtime/profiler.ts index a223a7fdbf4a7..0829b3ec71a66 100644 --- a/src/mono/browser/runtime/profiler.ts +++ b/src/mono/browser/runtime/profiler.ts @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. import { ENVIRONMENT_IS_WEB, mono_assert, runtimeHelpers } from "./globals"; -import { MonoMethod, AOTProfilerOptions, BrowserProfilerOptions } from "./types/internal"; +import { MonoMethod, AOTProfilerOptions, BrowserProfilerOptions, LogProfilerOptions } from "./types/internal"; import { profiler_c_functions as cwraps } from "./cwraps"; import { utf8ToString } from "./strings"; @@ -34,6 +34,12 @@ export function mono_wasm_init_browser_profiler (options: BrowserProfilerOptions cwraps.mono_wasm_profiler_init_browser(arg); } +export function mono_wasm_init_log_profiler (options: LogProfilerOptions): void { + mono_assert(runtimeHelpers.emscriptenBuildOptions.enableLogProfiler, "Log profiler is not enabled, please use log; in your project file."); + mono_assert(options.takeHeapshot, "Log profiler is not enabled, the takeHeapshot method must be defined in LogProfilerOptions.takeHeapshot"); + cwraps.mono_wasm_profiler_init_log( (options.configuration || "log:alloc,output=output.mlpd") + `,take-heapshot-method=${options.takeHeapshot}`); +} + export const enum MeasuredBlock { emscriptenStartup = "mono.emscriptenStartup", instantiateWasm = "mono.instantiateWasm", diff --git a/src/mono/browser/runtime/startup.ts b/src/mono/browser/runtime/startup.ts index b29bbbecf2a8d..b27364136c223 100644 --- a/src/mono/browser/runtime/startup.ts +++ b/src/mono/browser/runtime/startup.ts @@ -9,7 +9,7 @@ import { exportedRuntimeAPI, INTERNAL, loaderHelpers, Module, runtimeHelpers, cr import cwraps, { init_c_exports, threads_c_functions as tcwraps } from "./cwraps"; import { mono_wasm_raise_debug_event, mono_wasm_runtime_ready } from "./debug"; import { toBase64StringImpl } from "./base64"; -import { mono_wasm_init_aot_profiler, mono_wasm_init_browser_profiler } from "./profiler"; +import { mono_wasm_init_aot_profiler, mono_wasm_init_browser_profiler, mono_wasm_init_log_profiler } from "./profiler"; import { initialize_marshalers_to_cs } from "./marshal-to-cs"; import { initialize_marshalers_to_js } from "./marshal-to-js"; import { init_polyfills_async } from "./polyfills"; @@ -543,6 +543,9 @@ export async function start_runtime () { if (runtimeHelpers.config.browserProfilerOptions) mono_wasm_init_browser_profiler(runtimeHelpers.config.browserProfilerOptions); + if (runtimeHelpers.config.logProfilerOptions) + mono_wasm_init_log_profiler(runtimeHelpers.config.logProfilerOptions); + if (WasmEnableThreads) { // this is not mono-attached thread, so we can start it earlier await mono_wasm_init_diagnostics(); diff --git a/src/mono/browser/runtime/types/internal.ts b/src/mono/browser/runtime/types/internal.ts index 4ec8ced41c32a..5be1b4a617adf 100644 --- a/src/mono/browser/runtime/types/internal.ts +++ b/src/mono/browser/runtime/types/internal.ts @@ -77,6 +77,7 @@ export type MonoConfigInternal = MonoConfig & { assets?: AssetEntryInternal[], runtimeOptions?: string[], // array of runtime options as strings aotProfilerOptions?: AOTProfilerOptions, // dictionary-style Object. If omitted, aot profiler will not be initialized. + logProfilerOptions?: LogProfilerOptions, // dictionary-style Object. If omitted, log profiler will not be initialized. browserProfilerOptions?: BrowserProfilerOptions, // dictionary-style Object. If omitted, browser profiler will not be initialized. waitForDebugger?: number, appendElementOnExit?: boolean @@ -273,6 +274,11 @@ export type AOTProfilerOptions = { export type BrowserProfilerOptions = { } +export type LogProfilerOptions = { + takeHeapshot?: string, + configuration?: string // log profiler options string" +} + // how we extended emscripten Module export type DotnetModule = EmscriptenModule & DotnetModuleConfig; export type DotnetModuleInternal = EmscriptenModule & DotnetModuleConfig & EmscriptenModuleInternal; @@ -289,6 +295,7 @@ export type EmscriptenBuildOptions = { wasmEnableEH: boolean, enableAotProfiler: boolean, enableBrowserProfiler: boolean, + enableLogProfiler: boolean, runAOTCompilation: boolean, wasmEnableThreads: boolean, gitHash: string, diff --git a/src/mono/mono.proj b/src/mono/mono.proj index 5be3d221fd5b7..8fe15830cabb5 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -1185,6 +1185,9 @@ JS_ENGINES = [NODE_JS] <_MonoRuntimeArtifacts Condition="'$(TargetsBrowser)' == 'true' and '$(BuildMonoAOTCrossCompilerOnly)' != 'true'" Include="$(MonoObjDir)out\lib\libmono-profiler-aot.a"> $(RuntimeBinDir)libmono-profiler-aot.a + <_MonoRuntimeArtifacts Condition="'$(TargetsBrowser)' == 'true' and '$(BuildMonoAOTCrossCompilerOnly)' != 'true'" Include="$(MonoObjDir)out\lib\libmono-profiler-log.a"> + $(RuntimeBinDir)libmono-profiler-log.a + <_MonoRuntimeArtifacts Condition="'$(TargetsBrowser)' == 'true' and '$(BuildMonoAOTCrossCompilerOnly)' != 'true'" Include="$(MonoObjDir)out\lib\libmono-profiler-browser.a"> $(RuntimeBinDir)libmono-profiler-browser.a diff --git a/src/mono/mono/mini/mini-wasm.c b/src/mono/mono/mini/mini-wasm.c index 4f094b9246810..2a210e4af6e01 100644 --- a/src/mono/mono/mini/mini-wasm.c +++ b/src/mono/mono/mini/mini-wasm.c @@ -577,7 +577,6 @@ mono_init_native_crash_info (void) void mono_runtime_setup_stat_profiler (void) { - g_error ("mono_runtime_setup_stat_profiler"); } gboolean diff --git a/src/mono/mono/profiler/CMakeLists.txt b/src/mono/mono/profiler/CMakeLists.txt index e172774a6ebc5..f4271dc8bd4f8 100644 --- a/src/mono/mono/profiler/CMakeLists.txt +++ b/src/mono/mono/profiler/CMakeLists.txt @@ -6,6 +6,7 @@ include_directories( ${PROJECT_BINARY_DIR}/../../mono/eglib ${CMAKE_CURRENT_SOURCE_DIR}/../.. ${PROJECT_SOURCE_DIR}/../ + ${PROJECT_SOURCE_DIR}/../../../native/public ${PROJECT_SOURCE_DIR}/../eglib ${PROJECT_SOURCE_DIR}/../sgen) @@ -47,4 +48,18 @@ if(NOT DISABLE_LIBS) set_target_properties(mono-profiler-browser-static PROPERTIES OUTPUT_NAME mono-profiler-browser) install(TARGETS mono-profiler-browser-static LIBRARY) endif() + + if(HOST_BROWSER) + add_library(mono-profiler-log-static STATIC helper.c log.c log-args.c) + set_target_properties(mono-profiler-log-static PROPERTIES OUTPUT_NAME mono-profiler-log) + install(TARGETS mono-profiler-log-static LIBRARY) + + if(NOT DISABLE_LOG_PROFILER_GZ) + if (CLR_CMAKE_USE_SYSTEM_ZLIB) + target_link_libraries(mono-profiler-log-static PRIVATE ${Z_LIBS}) + else() + target_link_libraries(mono-profiler-log-static PRIVATE zlib) + endif() + endif() + endif() endif() diff --git a/src/mono/mono/profiler/helper.c b/src/mono/mono/profiler/helper.c index bbff8e7bf957b..05fc31b670840 100644 --- a/src/mono/mono/profiler/helper.c +++ b/src/mono/mono/profiler/helper.c @@ -8,7 +8,9 @@ #include +#if !defined (HOST_WASM) #include +#endif #ifdef HAVE_UNISTD_H #include @@ -42,6 +44,7 @@ mono_profhelper_close_socket_fd (SOCKET fd) void mono_profhelper_setup_command_server (SOCKET *server_socket, int *command_port, const char* profiler_name) { +#if !defined (HOST_WASM) *server_socket = socket (PF_INET, SOCK_STREAM, 0); if (*server_socket == INVALID_SOCKET) { @@ -77,11 +80,13 @@ mono_profhelper_setup_command_server (SOCKET *server_socket, int *command_port, } *command_port = ntohs (server_address.sin_port); +#endif } void mono_profhelper_add_to_fd_set (fd_set *set, SOCKET fd, int *max_fd) { +#if !defined (HOST_WASM) /* * This should only trigger for the basic FDs (server socket, pipes) at * startup if for some mysterious reason they're too large. In this case, @@ -99,4 +104,5 @@ mono_profhelper_add_to_fd_set (fd_set *set, SOCKET fd, int *max_fd) if (*max_fd < GUINT64_TO_INT(fd)) *max_fd = (int)fd; +#endif } diff --git a/src/mono/mono/profiler/log-args.c b/src/mono/mono/profiler/log-args.c index c8609177d18b0..124a629a14ca3 100644 --- a/src/mono/mono/profiler/log-args.c +++ b/src/mono/mono/profiler/log-args.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -98,6 +99,9 @@ parse_arg (const char *arg, ProfilerConfig *config) } else if (match_option (arg, "heapshot-on-shutdown", NULL)) { config->hs_on_shutdown = TRUE; config->enable_mask |= PROFLOG_HEAPSHOT_ALIAS; + } else if (match_option (arg, "take-heapshot-method", &val)) { + printf ("take-heapshot-method: %s\n", val); + set_log_profiler_take_heapshot_method(val); } else if (match_option (arg, "sample", &val)) { set_sample_freq (config, val); config->sampling_mode = MONO_PROFILER_SAMPLE_MODE_PROCESS; diff --git a/src/mono/mono/profiler/log.c b/src/mono/mono/profiler/log.c index abe5f3f479f57..24d3834296604 100644 --- a/src/mono/mono/profiler/log.c +++ b/src/mono/mono/profiler/log.c @@ -189,6 +189,8 @@ typedef struct { int small_id; } MonoProfilerThread; +static MonoMethodDesc *log_profiler_take_heapshot_method; + // Default value in `profiler_tls` for new threads. #define MONO_PROFILER_THREAD_ZERO ((MonoProfilerThread *) NULL) @@ -617,6 +619,7 @@ buffer_lock_helper (void); static void buffer_lock (void) { +#if !defined (HOST_WASM) /* * If the thread holding the exclusive lock tries to modify the * reader count, just make it a no-op. This way, we also avoid @@ -657,6 +660,8 @@ buffer_lock (void) } mono_memory_barrier (); + +#endif // HOST_WASM } static void @@ -685,6 +690,7 @@ buffer_lock_helper (void) static void buffer_unlock (void) { +#if !defined (HOST_WASM) mono_memory_barrier (); gint32 state = mono_atomic_load_i32 (&log_profiler.buffer_lock_state); @@ -697,6 +703,7 @@ buffer_unlock (void) g_assert (!(state >> 16) && "Why is the exclusive lock held?"); mono_atomic_dec_i32 (&log_profiler.buffer_lock_state); +#endif // HOST_WASM } static void @@ -3499,6 +3506,7 @@ runtime_initialized (MonoProfiler *profiler) mono_os_sem_init (&log_profiler.attach_threads_sem, 0); +#if !defined (HOST_WASM) /* * We must start the helper thread before the writer thread. This is * because start_helper_thread () sets up the command port which is written @@ -3507,6 +3515,9 @@ runtime_initialized (MonoProfiler *profiler) start_helper_thread (); start_writer_thread (); start_dumper_thread (); +#else + dump_header (); +#endif /* * Wait for all the internal threads to be started. If we don't do this, we @@ -3588,7 +3599,7 @@ create_profiler (const char *args, const char *filename, GPtrArray *filters) } } if (*nf == '|') { -#if HAVE_API_SUPPORT_WIN32_PIPE_OPEN_CLOSE && !defined (HOST_WIN32) +#if HAVE_API_SUPPORT_WIN32_PIPE_OPEN_CLOSE && !defined (HOST_WIN32) && !defined (HOST_WASM) log_profiler.file = popen (nf + 1, "w"); log_profiler.pipe_output = 1; #else @@ -3636,6 +3647,44 @@ create_profiler (const char *args, const char *filename, GPtrArray *filters) log_profiler.startup_time = current_time (); } +void +set_log_profiler_take_heapshot_method (const char *val) +{ + log_profiler_take_heapshot_method = mono_method_desc_new (val, TRUE); + + if (!log_profiler_take_heapshot_method) { + mono_profiler_printf_err ("Could not parse method description: %s", val); + exit (1); + } +} + +static void +proflog_trigger_heapshot (void); + +static void +prof_jit_done (MonoProfiler *prof, MonoMethod *method, MonoJitInfo *jinfo) +{ + MonoImage *image = mono_class_get_image (mono_method_get_class (method)); + + if (!image->assembly || method->wrapper_type || !log_profiler_take_heapshot_method) + return; + + if (log_profiler_take_heapshot_method && mono_method_desc_match (log_profiler_take_heapshot_method, method)) { + printf ("log-profiler | taking heapshot\n"); + proflog_trigger_heapshot (); + return; + } + else { + printf ("log-profiler not called (%p)\n", log_profiler_take_heapshot_method); + } +} + +static void +prof_inline_method (MonoProfiler *prof, MonoMethod *method, MonoMethod *inlined_method) +{ + prof_jit_done (prof, inlined_method, NULL); +} + MONO_API void mono_profiler_init_log (const char *desc); @@ -3758,6 +3807,9 @@ mono_profiler_init_log (const char *desc) mono_profiler_enable_allocations (); mono_profiler_enable_clauses (); mono_profiler_enable_sampling (handle); + mono_profiler_set_jit_done_callback (handle, prof_jit_done); + mono_profiler_set_inline_method_callback (handle, prof_inline_method); + /* * If no sample option was given by the user, this just leaves the sampling @@ -3770,3 +3822,12 @@ mono_profiler_init_log (const char *desc) done: ; } + +static void +proflog_trigger_heapshot (void) +{ + trigger_heapshot (); + + while (handle_writer_queue_entry ()); + while (handle_dumper_queue_entry ()); +} \ No newline at end of file diff --git a/src/mono/mono/profiler/log.h b/src/mono/mono/profiler/log.h index 9e3b320a7cfb2..a246afd1c1788 100644 --- a/src/mono/mono/profiler/log.h +++ b/src/mono/mono/profiler/log.h @@ -526,5 +526,6 @@ typedef struct { } ProfilerConfig; void proflog_parse_args (ProfilerConfig *config, const char *desc); +void set_log_profiler_take_heapshot_method (const char *val); #endif /* __MONO_PROFLOG_H__ */ From 15ef393020eda6b430db93f3079237a477dd06bd Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Fri, 13 Sep 2024 08:58:07 -0700 Subject: [PATCH 31/34] Arm64/Sve: Remove entries of SVE APIs take 32-bit address (#107758) (#107780) * Remove entry of APIs because of #103297 * comment out the test cases for unsupported APIs Co-authored-by: Jeff Schwartz --- .../Arm/Sve.PlatformNotSupported.cs | 132 ++++++++++-------- .../src/System/Runtime/Intrinsics/Arm/Sve.cs | 132 ++++++++++-------- .../ref/System.Runtime.Intrinsics.cs | 24 ++-- .../GenerateHWIntrinsicTests_Arm.cs | 16 +-- 4 files changed, 164 insertions(+), 140 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs index 1e21a643d6c95..54152ef6dd905 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.PlatformNotSupported.cs @@ -3172,11 +3172,12 @@ internal Arm64() { } /// public static unsafe void GatherPrefetch16Bit(Vector mask, void* address, Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw new PlatformNotSupportedException(); } - /// - /// void svprfh_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) - /// PRFH op, Pg, [Zbases.S, #0] - /// - public static unsafe void GatherPrefetch16Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw new PlatformNotSupportedException(); } + // + // void svprfh_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) + // PRFH op, Pg, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe void GatherPrefetch16Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw new PlatformNotSupportedException(); } /// /// void svprfh_gather_[u32]index(svbool_t pg, const void *base, svuint32_t indices, enum svprfop op) @@ -3208,11 +3209,12 @@ internal Arm64() { } /// public static unsafe void GatherPrefetch16Bit(Vector mask, void* address, Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw new PlatformNotSupportedException(); } - /// - /// void svprfh_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) - /// PRFH op, Pg, [Zbases.S, #0] - /// - public static unsafe void GatherPrefetch16Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw new PlatformNotSupportedException(); } + // + // void svprfh_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) + // PRFH op, Pg, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe void GatherPrefetch16Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw new PlatformNotSupportedException(); } /// /// void svprfh_gather_[u32]index(svbool_t pg, const void *base, svuint32_t indices, enum svprfop op) @@ -3247,11 +3249,12 @@ internal Arm64() { } /// public static unsafe void GatherPrefetch32Bit(Vector mask, void* address, Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw new PlatformNotSupportedException(); } - /// - /// void svprfw_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) - /// PRFW op, Pg, [Zbases.S, #0] - /// - public static unsafe void GatherPrefetch32Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw new PlatformNotSupportedException(); } + // + // void svprfw_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) + // PRFW op, Pg, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe void GatherPrefetch32Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw new PlatformNotSupportedException(); } /// /// void svprfw_gather_[u32]index(svbool_t pg, const void *base, svuint32_t indices, enum svprfop op) @@ -3283,11 +3286,12 @@ internal Arm64() { } /// public static unsafe void GatherPrefetch32Bit(Vector mask, void* address, Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw new PlatformNotSupportedException(); } - /// - /// void svprfw_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) - /// PRFW op, Pg, [Zbases.S, #0] - /// - public static unsafe void GatherPrefetch32Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw new PlatformNotSupportedException(); } + // + // void svprfw_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) + // PRFW op, Pg, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe void GatherPrefetch32Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw new PlatformNotSupportedException(); } /// /// void svprfw_gather_[u32]index(svbool_t pg, const void *base, svuint32_t indices, enum svprfop op) @@ -3322,11 +3326,12 @@ internal Arm64() { } /// public static unsafe void GatherPrefetch64Bit(Vector mask, void* address, Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw new PlatformNotSupportedException(); } - /// - /// void svprfd_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) - /// PRFD op, Pg, [Zbases.S, #0] - /// - public static unsafe void GatherPrefetch64Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw new PlatformNotSupportedException(); } + // + // void svprfd_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) + // PRFD op, Pg, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe void GatherPrefetch64Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw new PlatformNotSupportedException(); } /// /// void svprfd_gather_[u32]index(svbool_t pg, const void *base, svuint32_t indices, enum svprfop op) @@ -3358,11 +3363,12 @@ internal Arm64() { } /// public static unsafe void GatherPrefetch64Bit(Vector mask, void* address, Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw new PlatformNotSupportedException(); } - /// - /// void svprfd_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) - /// PRFD op, Pg, [Zbases.S, #0] - /// - public static unsafe void GatherPrefetch64Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw new PlatformNotSupportedException(); } + // + // void svprfd_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) + // PRFD op, Pg, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe void GatherPrefetch64Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw new PlatformNotSupportedException(); } /// /// void svprfd_gather_[u32]index(svbool_t pg, const void *base, svuint32_t indices, enum svprfop op) @@ -3397,11 +3403,12 @@ internal Arm64() { } /// public static unsafe void GatherPrefetch8Bit(Vector mask, void* address, Vector offsets, [ConstantExpected] SvePrefetchType prefetchType) { throw new PlatformNotSupportedException(); } - /// - /// void svprfb_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) - /// PRFB op, Pg, [Zbases.S, #0] - /// - public static unsafe void GatherPrefetch8Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw new PlatformNotSupportedException(); } + // + // void svprfb_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) + // PRFB op, Pg, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe void GatherPrefetch8Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw new PlatformNotSupportedException(); } /// /// void svprfb_gather_[u32]offset(svbool_t pg, const void *base, svuint32_t offsets, enum svprfop op) @@ -3433,11 +3440,12 @@ internal Arm64() { } /// public static unsafe void GatherPrefetch8Bit(Vector mask, void* address, Vector offsets, [ConstantExpected] SvePrefetchType prefetchType) { throw new PlatformNotSupportedException(); } - /// - /// void svprfb_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) - /// PRFB op, Pg, [Zbases.S, #0] - /// - public static unsafe void GatherPrefetch8Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw new PlatformNotSupportedException(); } + // + // void svprfb_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) + // PRFB op, Pg, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe void GatherPrefetch8Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw new PlatformNotSupportedException(); } /// /// void svprfb_gather_[u32]offset(svbool_t pg, const void *base, svuint32_t offsets, enum svprfop op) @@ -3925,11 +3933,12 @@ internal Arm64() { } /// public static unsafe Vector GatherVectorInt16SignExtendFirstFaulting(Vector mask, short* address, Vector indices) { throw new PlatformNotSupportedException(); } - /// - /// svint32_t svldff1sh_gather[_u32base]_s32(svbool_t pg, svuint32_t bases) - /// LDFF1SH Zresult.S, Pg/Z, [Zbases.S, #0] - /// - public static unsafe Vector GatherVectorInt16SignExtendFirstFaulting(Vector mask, Vector addresses) { throw new PlatformNotSupportedException(); } + // + // svint32_t svldff1sh_gather[_u32base]_s32(svbool_t pg, svuint32_t bases) + // LDFF1SH Zresult.S, Pg/Z, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe Vector GatherVectorInt16SignExtendFirstFaulting(Vector mask, Vector addresses) { throw new PlatformNotSupportedException(); } /// /// svint32_t svldff1sh_gather_[u32]index_s32(svbool_t pg, const int16_t *base, svuint32_t indices) @@ -3961,11 +3970,12 @@ internal Arm64() { } /// public static unsafe Vector GatherVectorInt16SignExtendFirstFaulting(Vector mask, short* address, Vector indices) { throw new PlatformNotSupportedException(); } - /// - /// svuint32_t svldff1sh_gather[_u32base]_u32(svbool_t pg, svuint32_t bases) - /// LDFF1SH Zresult.S, Pg/Z, [Zbases.S, #0] - /// - public static unsafe Vector GatherVectorInt16SignExtendFirstFaulting(Vector mask, Vector addresses) { throw new PlatformNotSupportedException(); } + // + // svuint32_t svldff1sh_gather[_u32base]_u32(svbool_t pg, svuint32_t bases) + // LDFF1SH Zresult.S, Pg/Z, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe Vector GatherVectorInt16SignExtendFirstFaulting(Vector mask, Vector addresses) { throw new PlatformNotSupportedException(); } /// /// svuint32_t svldff1sh_gather_[u32]index_u32(svbool_t pg, const int16_t *base, svuint32_t indices) @@ -4311,11 +4321,12 @@ internal Arm64() { } /// public static unsafe Vector GatherVectorSByteSignExtendFirstFaulting(Vector mask, sbyte* address, Vector offsets) { throw new PlatformNotSupportedException(); } - /// - /// svint32_t svldff1sb_gather[_u32base]_s32(svbool_t pg, svuint32_t bases) - /// LDFF1SB Zresult.S, Pg/Z, [Zbases.S, #0] - /// - public static unsafe Vector GatherVectorSByteSignExtendFirstFaulting(Vector mask, Vector addresses) { throw new PlatformNotSupportedException(); } + // + // svint32_t svldff1sb_gather[_u32base]_s32(svbool_t pg, svuint32_t bases) + // LDFF1SB Zresult.S, Pg/Z, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe Vector GatherVectorSByteSignExtendFirstFaulting(Vector mask, Vector addresses) { throw new PlatformNotSupportedException(); } /// /// svint32_t svldff1sb_gather_[u32]offset_s32(svbool_t pg, const int8_t *base, svuint32_t offsets) @@ -4347,11 +4358,12 @@ internal Arm64() { } /// public static unsafe Vector GatherVectorSByteSignExtendFirstFaulting(Vector mask, sbyte* address, Vector offsets) { throw new PlatformNotSupportedException(); } - /// - /// svuint32_t svldff1sb_gather[_u32base]_u32(svbool_t pg, svuint32_t bases) - /// LDFF1SB Zresult.S, Pg/Z, [Zbases.S, #0] - /// - public static unsafe Vector GatherVectorSByteSignExtendFirstFaulting(Vector mask, Vector addresses) { throw new PlatformNotSupportedException(); } + // + // svuint32_t svldff1sb_gather[_u32base]_u32(svbool_t pg, svuint32_t bases) + // LDFF1SB Zresult.S, Pg/Z, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe Vector GatherVectorSByteSignExtendFirstFaulting(Vector mask, Vector addresses) { throw new PlatformNotSupportedException(); } /// /// svuint32_t svldff1sb_gather_[u32]offset_u32(svbool_t pg, const int8_t *base, svuint32_t offsets) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs index 6afca70f8a093..b049ad9beabc3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve.cs @@ -3169,11 +3169,12 @@ internal Arm64() { } /// public static unsafe void GatherPrefetch16Bit(Vector mask, void* address, Vector indices, [ConstantExpected] SvePrefetchType prefetchType) => GatherPrefetch16Bit(mask, address, indices, prefetchType); - /// - /// void svprfh_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) - /// PRFH op, Pg, [Zbases.S, #0] - /// - public static unsafe void GatherPrefetch16Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) => GatherPrefetch16Bit(mask, addresses, prefetchType); + // + // void svprfh_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) + // PRFH op, Pg, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe void GatherPrefetch16Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) => GatherPrefetch16Bit(mask, addresses, prefetchType); /// /// void svprfh_gather_[u32]index(svbool_t pg, const void *base, svuint32_t indices, enum svprfop op) @@ -3205,11 +3206,12 @@ internal Arm64() { } /// public static unsafe void GatherPrefetch16Bit(Vector mask, void* address, Vector indices, [ConstantExpected] SvePrefetchType prefetchType) => GatherPrefetch16Bit(mask, address, indices, prefetchType); - /// - /// void svprfh_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) - /// PRFH op, Pg, [Zbases.S, #0] - /// - public static unsafe void GatherPrefetch16Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) => GatherPrefetch16Bit(mask, addresses, prefetchType); + // + // void svprfh_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) + // PRFH op, Pg, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe void GatherPrefetch16Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) => GatherPrefetch16Bit(mask, addresses, prefetchType); /// /// void svprfh_gather_[u32]index(svbool_t pg, const void *base, svuint32_t indices, enum svprfop op) @@ -3244,11 +3246,12 @@ internal Arm64() { } /// public static unsafe void GatherPrefetch32Bit(Vector mask, void* address, Vector indices, [ConstantExpected] SvePrefetchType prefetchType) => GatherPrefetch32Bit(mask, address, indices, prefetchType); - /// - /// void svprfw_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) - /// PRFW op, Pg, [Zbases.S, #0] - /// - public static unsafe void GatherPrefetch32Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) => GatherPrefetch32Bit(mask, addresses, prefetchType); + // + // void svprfw_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) + // PRFW op, Pg, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe void GatherPrefetch32Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) => GatherPrefetch32Bit(mask, addresses, prefetchType); /// /// void svprfw_gather_[u32]index(svbool_t pg, const void *base, svuint32_t indices, enum svprfop op) @@ -3280,11 +3283,12 @@ internal Arm64() { } /// public static unsafe void GatherPrefetch32Bit(Vector mask, void* address, Vector indices, [ConstantExpected] SvePrefetchType prefetchType) => GatherPrefetch32Bit(mask, address, indices, prefetchType); - /// - /// void svprfw_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) - /// PRFW op, Pg, [Zbases.S, #0] - /// - public static unsafe void GatherPrefetch32Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) => GatherPrefetch32Bit(mask, addresses, prefetchType); + // + // void svprfw_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) + // PRFW op, Pg, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe void GatherPrefetch32Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) => GatherPrefetch32Bit(mask, addresses, prefetchType); /// /// void svprfw_gather_[u32]index(svbool_t pg, const void *base, svuint32_t indices, enum svprfop op) @@ -3319,11 +3323,12 @@ internal Arm64() { } /// public static unsafe void GatherPrefetch64Bit(Vector mask, void* address, Vector indices, [ConstantExpected] SvePrefetchType prefetchType) => GatherPrefetch64Bit(mask, address, indices, prefetchType); - /// - /// void svprfd_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) - /// PRFD op, Pg, [Zbases.S, #0] - /// - public static unsafe void GatherPrefetch64Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) => GatherPrefetch64Bit(mask, addresses, prefetchType); + // + // void svprfd_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) + // PRFD op, Pg, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe void GatherPrefetch64Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) => GatherPrefetch64Bit(mask, addresses, prefetchType); /// /// void svprfd_gather_[u32]index(svbool_t pg, const void *base, svuint32_t indices, enum svprfop op) @@ -3355,11 +3360,12 @@ internal Arm64() { } /// public static unsafe void GatherPrefetch64Bit(Vector mask, void* address, Vector indices, [ConstantExpected] SvePrefetchType prefetchType) => GatherPrefetch64Bit(mask, address, indices, prefetchType); - /// - /// void svprfd_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) - /// PRFD op, Pg, [Zbases.S, #0] - /// - public static unsafe void GatherPrefetch64Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) => GatherPrefetch64Bit(mask, addresses, prefetchType); + // + // void svprfd_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) + // PRFD op, Pg, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe void GatherPrefetch64Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) => GatherPrefetch64Bit(mask, addresses, prefetchType); /// /// void svprfd_gather_[u32]index(svbool_t pg, const void *base, svuint32_t indices, enum svprfop op) @@ -3394,11 +3400,12 @@ internal Arm64() { } /// public static unsafe void GatherPrefetch8Bit(Vector mask, void* address, Vector offsets, [ConstantExpected] SvePrefetchType prefetchType) => GatherPrefetch8Bit(mask, address, offsets, prefetchType); - /// - /// void svprfb_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) - /// PRFB op, Pg, [Zbases.S, #0] - /// - public static unsafe void GatherPrefetch8Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) => GatherPrefetch8Bit(mask, addresses, prefetchType); + // + // void svprfb_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) + // PRFB op, Pg, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe void GatherPrefetch8Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) => GatherPrefetch8Bit(mask, addresses, prefetchType); /// /// void svprfb_gather_[u32]offset(svbool_t pg, const void *base, svuint32_t offsets, enum svprfop op) @@ -3430,11 +3437,12 @@ internal Arm64() { } /// public static unsafe void GatherPrefetch8Bit(Vector mask, void* address, Vector offsets, [ConstantExpected] SvePrefetchType prefetchType) => GatherPrefetch8Bit(mask, address, offsets, prefetchType); - /// - /// void svprfb_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) - /// PRFB op, Pg, [Zbases.S, #0] - /// - public static unsafe void GatherPrefetch8Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) => GatherPrefetch8Bit(mask, addresses, prefetchType); + // + // void svprfb_gather[_u32base](svbool_t pg, svuint32_t bases, enum svprfop op) + // PRFB op, Pg, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe void GatherPrefetch8Bit(Vector mask, Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) => GatherPrefetch8Bit(mask, addresses, prefetchType); /// /// void svprfb_gather_[u32]offset(svbool_t pg, const void *base, svuint32_t offsets, enum svprfop op) @@ -3922,11 +3930,12 @@ internal Arm64() { } /// public static unsafe Vector GatherVectorInt16SignExtendFirstFaulting(Vector mask, short* address, Vector indices) => GatherVectorInt16SignExtendFirstFaulting(mask, address, indices); - /// - /// svint32_t svldff1sh_gather[_u32base]_s32(svbool_t pg, svuint32_t bases) - /// LDFF1SH Zresult.S, Pg/Z, [Zbases.S, #0] - /// - public static unsafe Vector GatherVectorInt16SignExtendFirstFaulting(Vector mask, Vector addresses) => GatherVectorInt16SignExtendFirstFaulting(mask, addresses); + // + // svint32_t svldff1sh_gather[_u32base]_s32(svbool_t pg, svuint32_t bases) + // LDFF1SH Zresult.S, Pg/Z, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe Vector GatherVectorInt16SignExtendFirstFaulting(Vector mask, Vector addresses) => GatherVectorInt16SignExtendFirstFaulting(mask, addresses); /// /// svint32_t svldff1sh_gather_[u32]index_s32(svbool_t pg, const int16_t *base, svuint32_t indices) @@ -3958,11 +3967,12 @@ internal Arm64() { } /// public static unsafe Vector GatherVectorInt16SignExtendFirstFaulting(Vector mask, short* address, Vector indices) => GatherVectorInt16SignExtendFirstFaulting(mask, address, indices); - /// - /// svuint32_t svldff1sh_gather[_u32base]_u32(svbool_t pg, svuint32_t bases) - /// LDFF1SH Zresult.S, Pg/Z, [Zbases.S, #0] - /// - public static unsafe Vector GatherVectorInt16SignExtendFirstFaulting(Vector mask, Vector addresses) => GatherVectorInt16SignExtendFirstFaulting(mask, addresses); + // + // svuint32_t svldff1sh_gather[_u32base]_u32(svbool_t pg, svuint32_t bases) + // LDFF1SH Zresult.S, Pg/Z, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe Vector GatherVectorInt16SignExtendFirstFaulting(Vector mask, Vector addresses) => GatherVectorInt16SignExtendFirstFaulting(mask, addresses); /// /// svuint32_t svldff1sh_gather_[u32]index_u32(svbool_t pg, const int16_t *base, svuint32_t indices) @@ -4308,11 +4318,12 @@ internal Arm64() { } /// public static unsafe Vector GatherVectorSByteSignExtendFirstFaulting(Vector mask, sbyte* address, Vector offsets) => GatherVectorSByteSignExtendFirstFaulting(mask, address, offsets); - /// - /// svint32_t svldff1sb_gather[_u32base]_s32(svbool_t pg, svuint32_t bases) - /// LDFF1SB Zresult.S, Pg/Z, [Zbases.S, #0] - /// - public static unsafe Vector GatherVectorSByteSignExtendFirstFaulting(Vector mask, Vector addresses) => GatherVectorSByteSignExtendFirstFaulting(mask, addresses); + // + // svint32_t svldff1sb_gather[_u32base]_s32(svbool_t pg, svuint32_t bases) + // LDFF1SB Zresult.S, Pg/Z, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe Vector GatherVectorSByteSignExtendFirstFaulting(Vector mask, Vector addresses) => GatherVectorSByteSignExtendFirstFaulting(mask, addresses); /// /// svint32_t svldff1sb_gather_[u32]offset_s32(svbool_t pg, const int8_t *base, svuint32_t offsets) @@ -4344,11 +4355,12 @@ internal Arm64() { } /// public static unsafe Vector GatherVectorSByteSignExtendFirstFaulting(Vector mask, sbyte* address, Vector offsets) => GatherVectorSByteSignExtendFirstFaulting(mask, address, offsets); - /// - /// svuint32_t svldff1sb_gather[_u32base]_u32(svbool_t pg, svuint32_t bases) - /// LDFF1SB Zresult.S, Pg/Z, [Zbases.S, #0] - /// - public static unsafe Vector GatherVectorSByteSignExtendFirstFaulting(Vector mask, Vector addresses) => GatherVectorSByteSignExtendFirstFaulting(mask, addresses); + // + // svuint32_t svldff1sb_gather[_u32base]_u32(svbool_t pg, svuint32_t bases) + // LDFF1SB Zresult.S, Pg/Z, [Zbases.S, #0] + // + // Removed as per #103297 + // public static unsafe Vector GatherVectorSByteSignExtendFirstFaulting(Vector mask, Vector addresses) => GatherVectorSByteSignExtendFirstFaulting(mask, addresses); /// /// svuint32_t svldff1sb_gather_[u32]offset_u32(svbool_t pg, const int8_t *base, svuint32_t offsets) diff --git a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index ae105a47f3b7c..4c6cb9a8c3cd7 100644 --- a/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -4766,49 +4766,49 @@ internal Arm64() { } public static System.Numerics.Vector FusedMultiplySubtractNegated(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static unsafe void GatherPrefetch16Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch16Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } - public static void GatherPrefetch16Bit(System.Numerics.Vector mask, System.Numerics.Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } + // public static void GatherPrefetch16Bit(System.Numerics.Vector mask, System.Numerics.Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch16Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static void GatherPrefetch16Bit(System.Numerics.Vector mask, System.Numerics.Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch16Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch16Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch16Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } - public static void GatherPrefetch16Bit(System.Numerics.Vector mask, System.Numerics.Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } + // public static void GatherPrefetch16Bit(System.Numerics.Vector mask, System.Numerics.Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch16Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static void GatherPrefetch16Bit(System.Numerics.Vector mask, System.Numerics.Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch16Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch32Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch32Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } - public static void GatherPrefetch32Bit(System.Numerics.Vector mask, System.Numerics.Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } + // public static void GatherPrefetch32Bit(System.Numerics.Vector mask, System.Numerics.Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch32Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static void GatherPrefetch32Bit(System.Numerics.Vector mask, System.Numerics.Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch32Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch32Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch32Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } - public static void GatherPrefetch32Bit(System.Numerics.Vector mask, System.Numerics.Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } + // public static void GatherPrefetch32Bit(System.Numerics.Vector mask, System.Numerics.Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch32Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static void GatherPrefetch32Bit(System.Numerics.Vector mask, System.Numerics.Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch32Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch64Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch64Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } - public static void GatherPrefetch64Bit(System.Numerics.Vector mask, System.Numerics.Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } + // public static void GatherPrefetch64Bit(System.Numerics.Vector mask, System.Numerics.Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch64Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static void GatherPrefetch64Bit(System.Numerics.Vector mask, System.Numerics.Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch64Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch64Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch64Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } - public static void GatherPrefetch64Bit(System.Numerics.Vector mask, System.Numerics.Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } + // public static void GatherPrefetch64Bit(System.Numerics.Vector mask, System.Numerics.Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch64Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static void GatherPrefetch64Bit(System.Numerics.Vector mask, System.Numerics.Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch64Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector indices, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch8Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector offsets, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch8Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector offsets, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } - public static void GatherPrefetch8Bit(System.Numerics.Vector mask, System.Numerics.Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } + // public static void GatherPrefetch8Bit(System.Numerics.Vector mask, System.Numerics.Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch8Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector offsets, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static void GatherPrefetch8Bit(System.Numerics.Vector mask, System.Numerics.Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch8Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector offsets, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch8Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector offsets, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch8Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector offsets, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } - public static void GatherPrefetch8Bit(System.Numerics.Vector mask, System.Numerics.Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } + // public static void GatherPrefetch8Bit(System.Numerics.Vector mask, System.Numerics.Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch8Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector offsets, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static void GatherPrefetch8Bit(System.Numerics.Vector mask, System.Numerics.Vector addresses, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } public static unsafe void GatherPrefetch8Bit(System.Numerics.Vector mask, void* address, System.Numerics.Vector offsets, [ConstantExpected] SvePrefetchType prefetchType) { throw null; } @@ -4885,13 +4885,13 @@ internal Arm64() { } public static System.Numerics.Vector GatherVectorInt16SignExtend(System.Numerics.Vector mask, System.Numerics.Vector addresses) { throw null; } public static unsafe System.Numerics.Vector GatherVectorInt16SignExtend(System.Numerics.Vector mask, short* address, System.Numerics.Vector indices) { throw null; } public static unsafe System.Numerics.Vector GatherVectorInt16SignExtendFirstFaulting(System.Numerics.Vector mask, short* address, System.Numerics.Vector indices) { throw null; } - public static unsafe System.Numerics.Vector GatherVectorInt16SignExtendFirstFaulting(System.Numerics.Vector mask, System.Numerics.Vector addresses) { throw null; } + // public static unsafe System.Numerics.Vector GatherVectorInt16SignExtendFirstFaulting(System.Numerics.Vector mask, System.Numerics.Vector addresses) { throw null; } public static unsafe System.Numerics.Vector GatherVectorInt16SignExtendFirstFaulting(System.Numerics.Vector mask, short* address, System.Numerics.Vector indices) { throw null; } public static unsafe System.Numerics.Vector GatherVectorInt16SignExtendFirstFaulting(System.Numerics.Vector mask, short* address, System.Numerics.Vector indices) { throw null; } public static unsafe System.Numerics.Vector GatherVectorInt16SignExtendFirstFaulting(System.Numerics.Vector mask, System.Numerics.Vector addresses) { throw null; } public static unsafe System.Numerics.Vector GatherVectorInt16SignExtendFirstFaulting(System.Numerics.Vector mask, short* address, System.Numerics.Vector indices) { throw null; } public static unsafe System.Numerics.Vector GatherVectorInt16SignExtendFirstFaulting(System.Numerics.Vector mask, short* address, System.Numerics.Vector indices) { throw null; } - public static unsafe System.Numerics.Vector GatherVectorInt16SignExtendFirstFaulting(System.Numerics.Vector mask, System.Numerics.Vector addresses) { throw null; } + // public static unsafe System.Numerics.Vector GatherVectorInt16SignExtendFirstFaulting(System.Numerics.Vector mask, System.Numerics.Vector addresses) { throw null; } public static unsafe System.Numerics.Vector GatherVectorInt16SignExtendFirstFaulting(System.Numerics.Vector mask, short* address, System.Numerics.Vector indices) { throw null; } public static unsafe System.Numerics.Vector GatherVectorInt16SignExtendFirstFaulting(System.Numerics.Vector mask, short* address, System.Numerics.Vector indices) { throw null; } public static unsafe System.Numerics.Vector GatherVectorInt16SignExtendFirstFaulting(System.Numerics.Vector mask, System.Numerics.Vector addresses) { throw null; } @@ -4945,13 +4945,13 @@ internal Arm64() { } public static System.Numerics.Vector GatherVectorSByteSignExtend(System.Numerics.Vector mask, System.Numerics.Vector addresses) { throw null; } public static unsafe System.Numerics.Vector GatherVectorSByteSignExtend(System.Numerics.Vector mask, sbyte* address, System.Numerics.Vector indices) { throw null; } public static unsafe System.Numerics.Vector GatherVectorSByteSignExtendFirstFaulting(System.Numerics.Vector mask, sbyte* address, System.Numerics.Vector offsets) { throw null; } - public static unsafe System.Numerics.Vector GatherVectorSByteSignExtendFirstFaulting(System.Numerics.Vector mask, System.Numerics.Vector addresses) { throw null; } + // public static unsafe System.Numerics.Vector GatherVectorSByteSignExtendFirstFaulting(System.Numerics.Vector mask, System.Numerics.Vector addresses) { throw null; } public static unsafe System.Numerics.Vector GatherVectorSByteSignExtendFirstFaulting(System.Numerics.Vector mask, sbyte* address, System.Numerics.Vector offsets) { throw null; } public static unsafe System.Numerics.Vector GatherVectorSByteSignExtendFirstFaulting(System.Numerics.Vector mask, sbyte* address, System.Numerics.Vector offsets) { throw null; } public static unsafe System.Numerics.Vector GatherVectorSByteSignExtendFirstFaulting(System.Numerics.Vector mask, System.Numerics.Vector addresses) { throw null; } public static unsafe System.Numerics.Vector GatherVectorSByteSignExtendFirstFaulting(System.Numerics.Vector mask, sbyte* address, System.Numerics.Vector offsets) { throw null; } public static unsafe System.Numerics.Vector GatherVectorSByteSignExtendFirstFaulting(System.Numerics.Vector mask, sbyte* address, System.Numerics.Vector offsets) { throw null; } - public static unsafe System.Numerics.Vector GatherVectorSByteSignExtendFirstFaulting(System.Numerics.Vector mask, System.Numerics.Vector addresses) { throw null; } + // public static unsafe System.Numerics.Vector GatherVectorSByteSignExtendFirstFaulting(System.Numerics.Vector mask, System.Numerics.Vector addresses) { throw null; } public static unsafe System.Numerics.Vector GatherVectorSByteSignExtendFirstFaulting(System.Numerics.Vector mask, sbyte* address, System.Numerics.Vector offsets) { throw null; } public static unsafe System.Numerics.Vector GatherVectorSByteSignExtendFirstFaulting(System.Numerics.Vector mask, sbyte* address, System.Numerics.Vector offsets) { throw null; } public static unsafe System.Numerics.Vector GatherVectorSByteSignExtendFirstFaulting(System.Numerics.Vector mask, System.Numerics.Vector addresses) { throw null; } diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index 264531af67e39..4ae21113f1302 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -3472,8 +3472,8 @@ ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskUInt32", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskUInt32", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1Type"] = "SveMaskPattern"}), ("SveCreateTrueMaskTest.template", new Dictionary { ["TestName"] = "Sve_CreateTrueMaskUInt64", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "CreateTrueMaskUInt64", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1Type"] = "SveMaskPattern"}), - ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Bases_ushort_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), - ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Bases_short_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)16"}), + // ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Bases_ushort_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), + // ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Bases_short_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)16"}), ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Bases_ushort_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)58"}), ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Bases_short_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)123"}), ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Indices_ushort_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), @@ -3484,8 +3484,8 @@ ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Indices_short_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)123"}), ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Indices_ushort_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)99"}), ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch16Bit_Indices_short_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch16Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)254"}), - ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Bases_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)230"}), - ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Bases_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL2Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)23"}), + // ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Bases_uint_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)230"}), + // ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Bases_int_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL2Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)23"}), ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Bases_uint_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL3Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)22"}), ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Bases_int_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)99"}), ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Indices_uint_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL1NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)16"}), @@ -3496,8 +3496,8 @@ ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Indices_int_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)134"}), ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Indices_uint_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL3NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)35"}), ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch32Bit_Indices_int_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch32Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)153"}), - ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Bases_ulong_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), - ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Bases_long_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL2Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), + // ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Bases_ulong_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), + // ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Bases_long_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL2Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Bases_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL3NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Bases_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Indices_ulong_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)242"}), @@ -3508,8 +3508,8 @@ ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Indices_long_long", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL3NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)166"}), ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Indices_ulong_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)234"}), ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch64Bit_Indices_long_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch64Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL1NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)46"}), - ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Bases_byte_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL2Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), - ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Bases_sbyte_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL3NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), + // ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Bases_byte_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL2Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), + // ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Bases_sbyte_uint", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidPrefetch"] = "SvePrefetchType.LoadL3NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Bases_byte_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.LoadL1NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), ("SveGatherPrefetchVectorBases.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Bases_sbyte_ulong", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidPrefetch"] = "SvePrefetchType.StoreL2NonTemporal", ["InvalidPrefetch"] = "(SvePrefetchType)100"}), ("SveGatherPrefetchIndices.template", new Dictionary { ["TestName"] = "Sve_GatherPrefetch8Bit_Indices_byte_int", ["Isa"] = "Sve", ["LoadIsa"] = "Sve", ["Method"] = "GatherPrefetch8Bit", ["RetBaseType"] = "void", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2BaseType"] = "void", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "SvePrefetchType",["LargestVectorSize"] = "64", ["NextValueOp1"] = "Helpers.getMaskByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ValidPrefetch"] = "SvePrefetchType.StoreL3Temporal", ["InvalidPrefetch"] = "(SvePrefetchType)51"}), From 2081c29c9ffc75b5b191bcba8fcc58162e3e549c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 13 Sep 2024 09:18:18 -0700 Subject: [PATCH 32/34] Fix memory corruption bug in virtual static method dispatch (#107776) - Use `TypeHandle::CanCastTo` instead of `MethodTable::CanCastTo` - The issue is that the `MethodTable` api requires cooperative mode, and the `TypeHandle` supports either mode Fixes #107754 Co-authored-by: David Wrighton Co-authored-by: Jeff Schwartz --- src/coreclr/vm/methodtable.cpp | 13 ++++-- .../VariantVirtualStaticDefaultDispatch.cs | 44 +++++++++++++++++++ ...VariantVirtualStaticDefaultDispatch.csproj | 8 ++++ 3 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 src/tests/Loader/classloader/StaticVirtualMethods/Regression/VariantVirtualStaticDefaultDispatch.cs create mode 100644 src/tests/Loader/classloader/StaticVirtualMethods/Regression/VariantVirtualStaticDefaultDispatch.csproj diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index 5e0ba6c09bfd5..c8072a2731256 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -7868,8 +7868,9 @@ MethodTable::ResolveVirtualStaticMethod( ClassLoadLevel level) { CONTRACTL{ - THROWS; - GC_TRIGGERS; + MODE_ANY; + THROWS; + GC_TRIGGERS; } CONTRACTL_END; bool verifyImplemented = (resolveVirtualStaticMethodFlags & ResolveVirtualStaticMethodFlags::VerifyImplemented) != ResolveVirtualStaticMethodFlags::None; @@ -8029,6 +8030,12 @@ MethodTable::ResolveVirtualStaticMethod( MethodDesc* MethodTable::TryResolveVirtualStaticMethodOnThisType(MethodTable* pInterfaceType, MethodDesc* pInterfaceMD, ResolveVirtualStaticMethodFlags resolveVirtualStaticMethodFlags, ClassLoadLevel level) { + CONTRACTL{ + MODE_ANY; + THROWS; + GC_TRIGGERS; + } CONTRACTL_END; + bool instantiateMethodParameters = (resolveVirtualStaticMethodFlags & ResolveVirtualStaticMethodFlags::InstantiateResultOverFinalMethodDesc) != ResolveVirtualStaticMethodFlags::None; bool allowVariance = (resolveVirtualStaticMethodFlags & ResolveVirtualStaticMethodFlags::AllowVariantMatches) != ResolveVirtualStaticMethodFlags::None; bool verifyImplemented = (resolveVirtualStaticMethodFlags & ResolveVirtualStaticMethodFlags::VerifyImplemented) != ResolveVirtualStaticMethodFlags::None; @@ -8084,7 +8091,7 @@ MethodTable::TryResolveVirtualStaticMethodOnThisType(MethodTable* pInterfaceType { // Allow variant, but not equivalent interface match if (!pInterfaceType->HasSameTypeDefAs(pInterfaceMT) || - !pInterfaceMT->CanCastTo(pInterfaceType, NULL)) + !TypeHandle(pInterfaceMT).CanCastTo(pInterfaceType, NULL)) { continue; } diff --git a/src/tests/Loader/classloader/StaticVirtualMethods/Regression/VariantVirtualStaticDefaultDispatch.cs b/src/tests/Loader/classloader/StaticVirtualMethods/Regression/VariantVirtualStaticDefaultDispatch.cs new file mode 100644 index 0000000000000..8effd9e5c3335 --- /dev/null +++ b/src/tests/Loader/classloader/StaticVirtualMethods/Regression/VariantVirtualStaticDefaultDispatch.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.Runtime.CompilerServices; +using Xunit; + +// This test comes from https://github.com/dotnet/runtime/issues/107754 + +namespace VariantVirtualStaticDefaultDispatch +{ + interface IStaticConstraint + { + public abstract static void M(); + } + + interface IStaticConstraintDefaultImpl : IStaticConstraint + { + static void IStaticConstraint.M() { } + } + + interface IConstraintCheck where U : IStaticConstraint + { + } + + struct StructThatImplementsConstraint : IStaticConstraintDefaultImpl + { + } + + public class Tests + { + [MethodImpl(MethodImplOptions.NoInlining)] + static void M() where U: IStaticConstraint + { + U.M(); + } + + [Fact] + public static void RunTest() + { + System.Console.WriteLine(typeof(IConstraintCheck)); + M(); + } + } +} diff --git a/src/tests/Loader/classloader/StaticVirtualMethods/Regression/VariantVirtualStaticDefaultDispatch.csproj b/src/tests/Loader/classloader/StaticVirtualMethods/Regression/VariantVirtualStaticDefaultDispatch.csproj new file mode 100644 index 0000000000000..a49d38ec92d3b --- /dev/null +++ b/src/tests/Loader/classloader/StaticVirtualMethods/Regression/VariantVirtualStaticDefaultDispatch.csproj @@ -0,0 +1,8 @@ + + + Full + + + + + From 3b622e74a8f4879ea48ae3a838a976ea107c8d16 Mon Sep 17 00:00:00 2001 From: Mark Plesko Date: Fri, 13 Sep 2024 14:08:31 -0700 Subject: [PATCH 33/34] [release/9.0] Revert "[GC] Avoid OOM in large-allocation-only workloads (#105521)" (#107712) * Partially revert "[GC] Avoid OOM in large-allocation-only workloads (#105521)" This partially reverts commit b27a80867ea2fc832fd9a77b48fe7bb879143dee. This is done instead of a full revert because there were merge conflicts with bfb674ec. This also minimizes diffs with main in case of future backports. This reverts the distribute_free_regions but keeps the factoring. It also keeps the aging of huge free regions, but nothing is done with those ages. * Revert more of "[GC] Avoid OOM in large-allocation-only workloads (#105521)" This reverts the rest of commit b27a80867ea2fc832fd9a77b48fe7bb879143dee except for the age helper. --------- Co-authored-by: Jeff Schwartz --- src/coreclr/gc/gc.cpp | 64 ++++------------------------------------- src/coreclr/gc/gcpriv.h | 4 +-- 2 files changed, 6 insertions(+), 62 deletions(-) diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index 5f72e93eef9e5..2d58c0118463b 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -9666,7 +9666,7 @@ int gc_heap::grow_brick_card_tables (uint8_t* start, dprintf (GC_TABLE_LOG, ("card table: %zx(translated: %zx), seg map: %zx, mark array: %zx", (size_t)ct, (size_t)translated_ct, (size_t)new_seg_mapping_table, (size_t)card_table_mark_array (ct))); - if (is_bgc_in_progress()) + if (hp->is_bgc_in_progress()) { dprintf (GC_TABLE_LOG, ("new low: %p, new high: %p, latest mark array is %p(translate: %p)", saved_g_lowest_address, saved_g_highest_address, @@ -9793,7 +9793,7 @@ int gc_heap::grow_brick_card_tables (uint8_t* start, else { #ifdef BACKGROUND_GC - if (is_bgc_in_progress()) + if (hp->is_bgc_in_progress()) { dprintf (GC_TABLE_LOG, ("in range new seg %p, mark_array is %p", new_seg, hp->mark_array)); if (!commit_mark_array_new_seg (hp, new_seg)) @@ -13093,21 +13093,6 @@ void region_free_list::age_free_regions (region_free_list free_lists[count_free_ } } -size_t region_free_list::get_size_free_regions(int max_age) -{ - size_t result = 0; - - for (heap_segment* region = head_free_region; region != nullptr; region = heap_segment_next (region)) - { - if (heap_segment_age_in_free (region) <= max_age) - { - result += get_region_size(region); - } - } - - return result; -} - void region_free_list::print (int hn, const char* msg, int* ages) { dprintf (3, ("h%2d PRINTING-------------------------------", hn)); @@ -13229,13 +13214,7 @@ void region_free_list::sort_by_committed_and_age() void gc_heap::age_free_regions (const char* msg) { - // If we are doing an ephemeral GC as a precursor to a BGC, then we will age all of the region - // kinds during the ephemeral GC and skip the call to age_free_regions during the BGC itself. - bool age_all_region_kinds = (settings.condemned_generation == max_generation) || is_bgc_in_progress(); - if (age_all_region_kinds) - { - global_free_huge_regions.age_free_regions(); - } + bool age_all_region_kinds = (settings.condemned_generation == max_generation); #ifdef MULTIPLE_HEAPS for (int i = 0; i < n_heaps; i++) @@ -13436,7 +13415,6 @@ void gc_heap::distribute_free_regions() global_free_huge_regions.transfer_regions (&global_regions_to_decommit[huge_free_region]); size_t free_space_in_huge_regions = global_free_huge_regions.get_size_free_regions(); - size_t free_space_in_young_huge_regions = global_free_huge_regions.get_size_free_regions(MIN_AGE_TO_DECOMMIT_HUGE - 1); ptrdiff_t num_regions_to_decommit[kind_count]; int region_factor[kind_count] = { 1, LARGE_REGION_FACTOR }; @@ -13450,7 +13428,6 @@ void gc_heap::distribute_free_regions() #endif //!MULTIPLE_HEAPS size_t num_huge_region_units_to_consider[kind_count] = { 0, free_space_in_huge_regions / region_size[large_free_region] }; - size_t num_young_huge_region_units_to_consider[kind_count] = { 0, free_space_in_young_huge_regions / region_size[large_free_region] }; for (int kind = basic_free_region; kind < kind_count; kind++) { @@ -13469,22 +13446,9 @@ void gc_heap::distribute_free_regions() ptrdiff_t balance = total_num_free_regions[kind] + num_huge_region_units_to_consider[kind] - total_budget_in_region_units[kind]; - // Ignore young huge regions if they are contributing to a surplus. - if (balance > 0) - { - if (balance > static_cast(num_young_huge_region_units_to_consider[kind])) - { - balance -= num_young_huge_region_units_to_consider[kind]; - } - else - { - balance = 0; - } - } - if ( #ifdef BACKGROUND_GC - (background_running_p() && (settings.condemned_generation != max_generation)) || + background_running_p() || #endif (balance < 0)) { @@ -37777,15 +37741,7 @@ void gc_heap::allow_fgc() BOOL gc_heap::is_bgc_in_progress() { -#ifdef MULTIPLE_HEAPS - // All heaps are changed to/from the bgc_initialized state during the VM suspension at the start of BGC, - // so checking any heap will work. - gc_heap* hp = g_heaps[0]; -#else - gc_heap* hp = pGenGCHeap; -#endif //MULTIPLE_HEAPS - - return (background_running_p() || (hp->current_bgc_state == bgc_initialized)); + return (background_running_p() || (current_bgc_state == bgc_initialized)); } void gc_heap::clear_commit_flag() @@ -38300,16 +38256,6 @@ void gc_heap::background_mark_phase () if (bgc_t_join.joined()) #endif //MULTIPLE_HEAPS { -#ifdef USE_REGIONS - // There's no need to distribute a second time if we just did an ephemeral GC, and we don't want to - // age the free regions twice. - if (!do_ephemeral_gc_p) - { - distribute_free_regions (); - age_free_regions ("BGC"); - } -#endif //USE_REGIONS - #ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP // Resetting write watch for software write watch is pretty fast, much faster than for hardware write watch. Reset // can be done while the runtime is suspended or after the runtime is restarted, the preference was to reset while diff --git a/src/coreclr/gc/gcpriv.h b/src/coreclr/gc/gcpriv.h index 660ca2dad38ae..a9cc0fb7c6aad 100644 --- a/src/coreclr/gc/gcpriv.h +++ b/src/coreclr/gc/gcpriv.h @@ -1402,7 +1402,6 @@ class region_free_list size_t get_num_free_regions(); size_t get_size_committed_in_free() { return size_committed_in_free_regions; } size_t get_size_free_regions() { return size_free_regions; } - size_t get_size_free_regions(int max_age); heap_segment* get_first_free_region() { return head_free_region; } static void unlink_region (heap_segment* region); static void add_region (heap_segment* region, region_free_list to_free_list[count_free_region_kinds]); @@ -3206,7 +3205,7 @@ class gc_heap // Restores BGC settings if necessary. PER_HEAP_ISOLATED_METHOD void recover_bgc_settings(); - PER_HEAP_ISOLATED_METHOD BOOL is_bgc_in_progress(); + PER_HEAP_METHOD BOOL is_bgc_in_progress(); PER_HEAP_METHOD void clear_commit_flag(); @@ -6079,7 +6078,6 @@ class heap_segment // the region's free list. #define MAX_AGE_IN_FREE 99 #define AGE_IN_FREE_TO_DECOMMIT 20 - #define MIN_AGE_TO_DECOMMIT_HUGE 2 int age_in_free; // This is currently only used by regions that are swept in plan - // we then thread this list onto the generation's free list. From 46cfb747b4c22471242dee0d106f5c79cf9fd4c5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 13 Sep 2024 18:59:49 -0700 Subject: [PATCH 34/34] Fix perf problems found in investigation of issue #107728 - `CheckRunClassInitThrowing` didn't check to see if the class had been initialized before taking a lock - `EnsureTlsIndexAllocated` didn't check if the Tls index had been allocated before setting the flag via an expensive Interlocked call to indicate that it had been allocated - And finally `JIT_GetNonGCThreadStaticBaseOptimized` and `JIT_GetGCThreadStaticBaseOptimized` were missing the fast paths which avoided even calling those apis at all. (#107817) Perf with a small benchmark which does complex multithreaded work... | Runtime | Time | | ---- | ---- | | .NET 8 | 00.9414682 s | | .NET 9 before this fix | 22.8079382 | | .NET 9 with this fix | 00.2004539 | Fixes #107728 Co-authored-by: David Wrighton --- src/coreclr/vm/jithelpers.cpp | 12 ++++++++++++ src/coreclr/vm/methodtable.cpp | 10 +++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/coreclr/vm/jithelpers.cpp b/src/coreclr/vm/jithelpers.cpp index f8893f7351fe6..9dab914dbc931 100644 --- a/src/coreclr/vm/jithelpers.cpp +++ b/src/coreclr/vm/jithelpers.cpp @@ -901,6 +901,12 @@ HCIMPL1(void*, JIT_GetNonGCThreadStaticBaseOptimized, UINT32 staticBlockIndex) FCALL_CONTRACT; + staticBlock = GetThreadLocalStaticBaseIfExistsAndInitialized(staticBlockIndex); + if (staticBlock != NULL) + { + return staticBlock; + } + HELPER_METHOD_FRAME_BEGIN_RET_0(); // Set up a frame TLSIndex tlsIndex(staticBlockIndex); // Check if the class constructor needs to be run @@ -975,6 +981,12 @@ HCIMPL1(void*, JIT_GetGCThreadStaticBaseOptimized, UINT32 staticBlockIndex) FCALL_CONTRACT; + staticBlock = GetThreadLocalStaticBaseIfExistsAndInitialized(staticBlockIndex); + if (staticBlock != NULL) + { + return staticBlock; + } + HELPER_METHOD_FRAME_BEGIN_RET_0(); // Set up a frame TLSIndex tlsIndex(staticBlockIndex); diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index c8072a2731256..27dfd82a691ed 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -3840,8 +3840,8 @@ void MethodTable::CheckRunClassInitThrowing() // To find GC hole easier... TRIGGERSGC(); - // Don't initialize shared generic instantiations (e.g. MyClass<__Canon>) - if (IsSharedByGenericInstantiations()) + // Don't initialize shared generic instantiations (e.g. MyClass<__Canon>), or an already initialized MethodTable + if (IsClassInited() || IsSharedByGenericInstantiations()) return; _ASSERTE(!ContainsGenericVariables()); @@ -3946,7 +3946,11 @@ void MethodTable::EnsureTlsIndexAllocated() CONTRACTL_END; PTR_MethodTableAuxiliaryData pAuxiliaryData = GetAuxiliaryDataForWrite(); - if (!pAuxiliaryData->IsTlsIndexAllocated() && GetNumThreadStaticFields() > 0) + + if (pAuxiliaryData->IsTlsIndexAllocated()) + return; + + if (GetNumThreadStaticFields() > 0) { ThreadStaticsInfo *pThreadStaticsInfo = MethodTableAuxiliaryData::GetThreadStaticsInfo(GetAuxiliaryDataForWrite()); // Allocate space for normal statics if we might have them