From 03e18c04cb01a9f13a7f4fd42a4f54b996593d82 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 7 Jun 2022 21:17:56 +0000 Subject: [PATCH 001/337] Update dependencies from https://github.com/dotnet/linker build 20220607.2 Microsoft.NET.ILLink.Tasks From Version 7.0.100-1.22306.1 -> To Version 7.0.100-1.22307.2 --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 346cd4414a5aa7..ae2a4854e3a4e0 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -238,9 +238,9 @@ https://github.com/dotnet/runtime 0864cc5539e0ddd109b443b0bee804878cd7ba76 - + https://github.com/dotnet/linker - 1481a51970586b26208a7bc6173dc77d658f3508 + 8ad504e47ca0b2a06c6d531aba26835ee9b10104 https://github.com/dotnet/xharness diff --git a/eng/Versions.props b/eng/Versions.props index ae0db208b95d25..3a8782e3eadf0d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -168,7 +168,7 @@ 7.0.0-preview-20220429.1 - 7.0.100-1.22306.1 + 7.0.100-1.22307.2 $(MicrosoftNETILLinkTasksVersion) 7.0.0-preview.5.22269.3 From 34146b62c22f336556ac5225dfca9d5655049c81 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Tue, 7 Jun 2022 16:25:56 -0700 Subject: [PATCH 002/337] Suppress trim warnings For trim annotations which reference compiler-generated code --- .../src/System/Diagnostics/DiagnosticSourceEventSource.cs | 3 +++ .../src/System/Diagnostics/Tracing/EventSource.cs | 3 +++ .../src/System/Diagnostics/Tracing/RuntimeEventSource.cs | 4 ++++ .../System/Runtime/Serialization/PrimitiveDataContract.cs | 4 ++++ .../src/System/Xml/Serialization/Types.cs | 8 ++++++++ 5 files changed, 22 insertions(+) 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 67767349084fc4..a8d700d47c99a0 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/DiagnosticSourceEventSource.cs @@ -660,6 +660,9 @@ public FilterAndTransform(string filterAndPayloadSpec, int startIdx, int endIdx, [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "DiagnosticSource.Write is marked with RequiresUnreferencedCode.")] + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2119", + Justification = "DAM on EventSource references this compiler-generated local function which calls a " + + "method that requires unreferenced code. EventSource will not access this local function.")] void OnEventWritten(KeyValuePair evnt) { // The filter given to the DiagnosticSource may not work if users don't is 'IsEnabled' as expected. diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs index 7db1b785a40898..199bf2d0fd761d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs @@ -2206,6 +2206,9 @@ private unsafe void WriteEventString(string msgString) #if !ES_BUILD_STANDALONE [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "The call to TraceLoggingEventTypes with the below parameter values are trim safe")] + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2119", + Justification = "DAM on EventSource references this compiler-generated local function which calls a " + + "constructor that requires unreferenced code. EventSource will not access this local function.")] #endif static TraceLoggingEventTypes GetTrimSafeTraceLoggingEventTypes() => new TraceLoggingEventTypes(EventName, EventTags.None, new Type[] { typeof(string) }); diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs index 2976184d51e948..8f7a4588fb58da 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/RuntimeEventSource.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Threading; +using System.Diagnostics.CodeAnalysis; namespace System.Diagnostics.Tracing { @@ -66,6 +67,9 @@ internal void LogAppContextSwitch(string switchName, int value) base.WriteEvent((int)EventId.AppContextSwitch, switchName, value); } + [UnconditionalSuppressMessage ("ReflectionAnalysis", "IL2119", + Justification = "DAM on EventSource references the compiler-generated lambda methods some of which call PInvokes " + + "which are considered potentially dangerous. Event source will not use these lambdas.")] protected override void OnEventCommand(EventCommandEventArgs command) { if (command.Command == EventCommand.Enable) diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/PrimitiveDataContract.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/PrimitiveDataContract.cs index f255598035af04..b5bfbbb22559ff 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/PrimitiveDataContract.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/PrimitiveDataContract.cs @@ -625,6 +625,10 @@ public override void WriteXmlElement(XmlWriterDelegator xmlWriter, object? obj, internal sealed class DateTimeDataContract : PrimitiveDataContract { + [UnconditionalSuppressMessage ("ReflectionAnalysis", "IL2118", + Justification = "DAM on the first parameter of the PrimitiveDataContract constructor references methods of DateTime, " + + "which has a compiler-generated local function LowGranularityNonCachedFallback that calls PInvokes " + + "which are considered potentially dangerous. Data contract serialization will not access this local function.")] public DateTimeDataContract() : base(typeof(DateTime), DictionaryGlobals.DateTimeLocalName, DictionaryGlobals.SchemaNamespace) { } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Types.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Types.cs index 5d0e76505c371f..5f0ee4a7931f65 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Types.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Types.cs @@ -510,6 +510,10 @@ internal sealed class TypeScope "token" }; + [UnconditionalSuppressMessage ("ReflectionAnalysis", "IL2118", + Justification = "DAM on AddPrimitive references methods of DateTime, which has a compiler-generated local function " + + "LowGranularityNonCachedFallback that calls PInvokes which are considered potentially dangerous. " + + "XML serialization will not access this local function.")] static TypeScope() { AddPrimitive(typeof(string), "string", "String", TypeFlags.CanBeAttributeValue | TypeFlags.CanBeElementValue | TypeFlags.CanBeTextValue | TypeFlags.Reference | TypeFlags.HasDefaultConstructor); @@ -605,6 +609,10 @@ internal static bool IsKnownType(Type type) return false; } + [UnconditionalSuppressMessage ("ReflectionAnalysis", "IL2118", + Justification = "DAM on AddPrimitive references methods of DateTime, which has a compiler-generated local function " + + "LowGranularityNonCachedFallback that calls PInvokes which are considered potentially dangerous. " + + "XML serialization will not access this local function.")] private static void AddSoapEncodedTypes(string ns) { AddSoapEncodedPrimitive(typeof(string), "normalizedString", ns, "String", new XmlQualifiedName("normalizedString", XmlSchema.Namespace), TypeFlags.AmbiguousDataType | TypeFlags.CanBeAttributeValue | TypeFlags.CanBeElementValue | TypeFlags.Reference | TypeFlags.HasDefaultConstructor); From c6cea6b022b3da0917fb4e7177c01f260990466b Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 8 Jun 2022 18:33:33 +0000 Subject: [PATCH 003/337] Update dependencies from https://github.com/dotnet/linker build 20220608.1 Microsoft.NET.ILLink.Tasks From Version 7.0.100-1.22306.1 -> To Version 7.0.100-1.22308.1 --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index ae2a4854e3a4e0..8e3805215c6a4f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -238,9 +238,9 @@ https://github.com/dotnet/runtime 0864cc5539e0ddd109b443b0bee804878cd7ba76 - + https://github.com/dotnet/linker - 8ad504e47ca0b2a06c6d531aba26835ee9b10104 + 978b631362f2ffdccdf63fbe3ffe59dfe985ae3d https://github.com/dotnet/xharness diff --git a/eng/Versions.props b/eng/Versions.props index 3a8782e3eadf0d..891951aa506c2c 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -168,7 +168,7 @@ 7.0.0-preview-20220429.1 - 7.0.100-1.22307.2 + 7.0.100-1.22308.1 $(MicrosoftNETILLinkTasksVersion) 7.0.0-preview.5.22269.3 From 1b7d8e5b785ac0d9cc50f099fe5dca558d534430 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 8 Jun 2022 17:08:25 -0700 Subject: [PATCH 004/337] Suppress trim warnings in tests --- .../tests/TrimmingTests/EventSourceManifestTest.cs | 3 +++ src/libraries/System.Runtime/tests/System/Type/TypeTests.cs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/libraries/System.Diagnostics.Tracing/tests/TrimmingTests/EventSourceManifestTest.cs b/src/libraries/System.Diagnostics.Tracing/tests/TrimmingTests/EventSourceManifestTest.cs index 92dfa41915d144..261a70393d614d 100644 --- a/src/libraries/System.Diagnostics.Tracing/tests/TrimmingTests/EventSourceManifestTest.cs +++ b/src/libraries/System.Diagnostics.Tracing/tests/TrimmingTests/EventSourceManifestTest.cs @@ -35,6 +35,9 @@ void EventSourceTest_Method_4(){} int EventSourceTest_Method_7() => 5; } + [UnconditionalSuppressMessage ("ReflectionAnalysis", "IL2118", + Justification = "DAM on EventSource.GenerateManifest references compiler-generated local function GetTrimSafeTraceLoggingEventTypes " + + "which calls a constructor that requires unreferenced code. EventSource will not access this local function.")] public static int Main() { string manifest = EventSource.GenerateManifest(typeof(EventSourceTest), null); diff --git a/src/libraries/System.Runtime/tests/System/Type/TypeTests.cs b/src/libraries/System.Runtime/tests/System/Type/TypeTests.cs index 9872ae4ceea9f3..679100ae68ac21 100644 --- a/src/libraries/System.Runtime/tests/System/Type/TypeTests.cs +++ b/src/libraries/System.Runtime/tests/System/Type/TypeTests.cs @@ -149,6 +149,9 @@ public static IEnumerable FindMembers_TestData() [Theory] [MemberData(nameof(FindMembers_TestData))] + [UnconditionalSuppressMessage ("ReflectionAnalysis", "IL2118", + Justification = "DAM on FindMembers references compiler-generated members which use reflection. " + + "These members are not accessed by the test.")] public void FindMembers_Invoke_ReturnsExpected(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, object filterCriteria, int expectedLength) { Assert.Equal(expectedLength, typeof(TypeTests).FindMembers(memberType, bindingAttr, filter, filterCriteria).Length); From f737d509daaff03862a42c13469a174f640ad756 Mon Sep 17 00:00:00 2001 From: Sven Boemer Date: Wed, 8 Jun 2022 17:39:48 -0700 Subject: [PATCH 005/337] Add using --- src/libraries/System.Runtime/tests/System/Type/TypeTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/System.Runtime/tests/System/Type/TypeTests.cs b/src/libraries/System.Runtime/tests/System/Type/TypeTests.cs index 679100ae68ac21..419f0d4b6283cb 100644 --- a/src/libraries/System.Runtime/tests/System/Type/TypeTests.cs +++ b/src/libraries/System.Runtime/tests/System/Type/TypeTests.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Reflection; From 77136b1657fe55a27c5ae2cccbb74f123615021d Mon Sep 17 00:00:00 2001 From: Andy Gocke Date: Wed, 8 Jun 2022 21:59:33 -0700 Subject: [PATCH 006/337] Add RUC --- .../tests/ModuleBuilder/ModuleBuilderDefineType.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libraries/System.Reflection.Emit/tests/ModuleBuilder/ModuleBuilderDefineType.cs b/src/libraries/System.Reflection.Emit/tests/ModuleBuilder/ModuleBuilderDefineType.cs index a4b5ecb392f02c..7c5bf90ea11c0c 100644 --- a/src/libraries/System.Reflection.Emit/tests/ModuleBuilder/ModuleBuilderDefineType.cs +++ b/src/libraries/System.Reflection.Emit/tests/ModuleBuilder/ModuleBuilderDefineType.cs @@ -3,9 +3,11 @@ using System.Collections.Generic; using Xunit; +using System.Diagnostics.CodeAnalysis; namespace System.Reflection.Emit.Tests { + [RequiresUnreferencedCode("Uses reflection to construct test cases")] public class ModuleBuilderDefineType { public static IEnumerable TestData() From 1873182e161645a8bf3985444ed72e9efd0c47c3 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Thu, 9 Jun 2022 16:35:10 +0000 Subject: [PATCH 007/337] [wasm] Disable all trim warnings for tests, when using .. `EnableAggressiveTrimming=true`, since the tests are not expected to be trim-safe. Based on @vitek-karas' suggestion. --- eng/testing/tests.wasm.targets | 2 ++ 1 file changed, 2 insertions(+) diff --git a/eng/testing/tests.wasm.targets b/eng/testing/tests.wasm.targets index 21d7098d448461..bcc4923f40d778 100644 --- a/eng/testing/tests.wasm.targets +++ b/eng/testing/tests.wasm.targets @@ -5,6 +5,8 @@ true $(BundleTestAppTargets);BundleTestWasmApp true + + true $([MSBuild]::NormalizeDirectory($(MonoProjectRoot), 'wasm', 'emsdk')) From 5a73676bde9f02bb7d7cadb6471896e2c1bfe1b7 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Thu, 9 Jun 2022 17:29:41 +0000 Subject: [PATCH 008/337] [wasm] fix test failing when trimming ``` [06:37:05] fail: [FAIL] System.Diagnostics.Tests.StopwatchTests.DebuggerAttributesValid [06:37:05] info: System.InvalidOperationException : Expected one DebuggerDisplayAttribute on System.Diagnostics.Stopwatch. [06:37:05] info: at System.Diagnostics.DebuggerAttributes.ValidateDebuggerDisplayReferences(Object obj) [06:37:05] info: at System.Diagnostics.Tests.StopwatchTests.DebuggerAttributesValid() [06:37:05] info: at System.Reflection.MethodInvoker.InterpretedInvoke(Object , Span`1 , BindingFlags ) ``` Fixed by preserving the `DebuggerDisplayAttribute`. --- .../System.Runtime.Extensions/tests/ILLink.Descriptors.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libraries/System.Runtime.Extensions/tests/ILLink.Descriptors.xml b/src/libraries/System.Runtime.Extensions/tests/ILLink.Descriptors.xml index 0fc8748461f835..16e4a8a62c64a4 100644 --- a/src/libraries/System.Runtime.Extensions/tests/ILLink.Descriptors.xml +++ b/src/libraries/System.Runtime.Extensions/tests/ILLink.Descriptors.xml @@ -4,4 +4,7 @@ + + + From 9080239fb2b47717126f30d3890c1a48eb100527 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Thu, 9 Jun 2022 19:37:34 +0200 Subject: [PATCH 009/337] JIT: Unspecialize handle types after arithmetic ops in VN (#70452) VN was retaining the precise handle types when applying arithmetic operations to handles. This meant that we could not rely on handles of types like GTF_ICON_METHOD_HDL actually containing an embedded method handle after constant propagation. This change generalizes the handle type to GTF_ICON_CONST_PTR or GTF_ICON_GLOBAL_PTR whenever VN does anything that semantically "unassociates" the icon from the specialized handle type. --- src/coreclr/jit/valuenum.cpp | 41 ++++++++++++++++++++++++++++++++---- src/coreclr/jit/valuenum.h | 2 ++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index be7fc14611f0f8..f32b7d79ddb0b9 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -2869,13 +2869,15 @@ ValueNum ValueNumStore::EvalFuncForConstantArgs(var_types typ, VNFunc func, Valu { int resVal = EvalOp(func, ConstantValue(arg0VN)); // Unary op on a handle results in a handle. - return IsVNHandle(arg0VN) ? VNForHandle(ssize_t(resVal), GetHandleFlags(arg0VN)) : VNForIntCon(resVal); + return IsVNHandle(arg0VN) ? VNForHandle(ssize_t(resVal), GetFoldedArithOpResultHandleFlags(arg0VN)) + : VNForIntCon(resVal); } case TYP_LONG: { INT64 resVal = EvalOp(func, ConstantValue(arg0VN)); // Unary op on a handle results in a handle. - return IsVNHandle(arg0VN) ? VNForHandle(ssize_t(resVal), GetHandleFlags(arg0VN)) : VNForLongCon(resVal); + return IsVNHandle(arg0VN) ? VNForHandle(ssize_t(resVal), GetFoldedArithOpResultHandleFlags(arg0VN)) + : VNForLongCon(resVal); } case TYP_FLOAT: { @@ -3106,7 +3108,7 @@ ValueNum ValueNumStore::EvalFuncForConstantArgs(var_types typ, VNFunc func, Valu ValueNum handleVN = IsVNHandle(arg0VN) ? arg0VN : IsVNHandle(arg1VN) ? arg1VN : NoVN; if (handleVN != NoVN) { - result = VNForHandle(ssize_t(resultVal), GetHandleFlags(handleVN)); // Use VN for Handle + result = VNForHandle(ssize_t(resultVal), GetFoldedArithOpResultHandleFlags(handleVN)); } else { @@ -3132,7 +3134,7 @@ ValueNum ValueNumStore::EvalFuncForConstantArgs(var_types typ, VNFunc func, Valu if (handleVN != NoVN) { - result = VNForHandle(ssize_t(resultVal), GetHandleFlags(handleVN)); // Use VN for Handle + result = VNForHandle(ssize_t(resultVal), GetFoldedArithOpResultHandleFlags(handleVN)); } else { @@ -5119,6 +5121,37 @@ GenTreeFlags ValueNumStore::GetHandleFlags(ValueNum vn) return handle->m_flags; } +GenTreeFlags ValueNumStore::GetFoldedArithOpResultHandleFlags(ValueNum vn) +{ + GenTreeFlags flags = GetHandleFlags(vn); + assert((flags & GTF_ICON_HDL_MASK) == flags); + + switch (flags) + { + case GTF_ICON_SCOPE_HDL: + case GTF_ICON_CLASS_HDL: + case GTF_ICON_METHOD_HDL: + case GTF_ICON_FIELD_HDL: + case GTF_ICON_TOKEN_HDL: + case GTF_ICON_STR_HDL: + case GTF_ICON_CONST_PTR: + case GTF_ICON_VARG_HDL: + case GTF_ICON_PINVKI_HDL: + case GTF_ICON_FTN_ADDR: + case GTF_ICON_CIDMID_HDL: + case GTF_ICON_TLS_HDL: + case GTF_ICON_STATIC_BOX_PTR: + return GTF_ICON_CONST_PTR; + case GTF_ICON_STATIC_HDL: + case GTF_ICON_GLOBAL_PTR: + case GTF_ICON_BBC_PTR: + return GTF_ICON_GLOBAL_PTR; + default: + assert(!"Unexpected handle type"); + return flags; + } +} + bool ValueNumStore::IsVNHandle(ValueNum vn) { if (vn == NoVN) diff --git a/src/coreclr/jit/valuenum.h b/src/coreclr/jit/valuenum.h index 22755856066a7d..fc9ed09913c630 100644 --- a/src/coreclr/jit/valuenum.h +++ b/src/coreclr/jit/valuenum.h @@ -379,6 +379,8 @@ class ValueNumStore // returns true iff vn is known to be a constant int32 that is > 0 bool IsVNPositiveInt32Constant(ValueNum vn); + GenTreeFlags GetFoldedArithOpResultHandleFlags(ValueNum vn); + public: // Initializes any static variables of ValueNumStore. static void InitValueNumStoreStatics(); From a325e52ecb3b3c970cfb4da4dddeab3eda20df9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Rylek?= Date: Thu, 9 Jun 2022 20:06:07 +0200 Subject: [PATCH 010/337] Fix Crossgen2 PDB generator (#70407) * Fix Crossgen2 PDB generator During my perf investigation work I have found out that PDB emitter in Crossgen2 is broken. I tracked this down to the change https://github.com/dotnet/runtime/commit/fdf6485c800ec580656d7491795e10881d493afb#diff-24e48862e3b82f52e7fa04f22700b1c976a012bfeb08a246406f4e5ec579699b that caused two behavioral changes in the PDB emitter: 1) The logic around QueryPDBNameEx got refactored to use a char[] instead of a StringBuilder and that silently caused _pdbFilePath to be set to the string "System.Char[]" instead of the actual path (cf PdbWriter.cs#221 in the quoted commit). 2) The COM wrapper refactoring ended up bumping the refcount on the _ngenWriter by one so that it never got actually closed and properly flushed; due to this the resulting PDB was invalid. Thanks Tomas --- src/coreclr/tools/aot/ILCompiler.Diagnostics/PdbWriter.cs | 7 ++++++- .../aot/ILCompiler.Diagnostics/SymNgenWriterWrapper.cs | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/coreclr/tools/aot/ILCompiler.Diagnostics/PdbWriter.cs b/src/coreclr/tools/aot/ILCompiler.Diagnostics/PdbWriter.cs index be0d8af909f727..62bdb023525e6f 100644 --- a/src/coreclr/tools/aot/ILCompiler.Diagnostics/PdbWriter.cs +++ b/src/coreclr/tools/aot/ILCompiler.Diagnostics/PdbWriter.cs @@ -218,7 +218,12 @@ private void WritePDBDataHelper(string dllPath, IEnumerable methods) const int capacity = 1024; var pdbFilePathBuilder = new char[capacity]; _ngenWriter.QueryPDBNameExW(pdbFilePathBuilder, new IntPtr(capacity - 1) /* remove 1 byte for null */); - _pdbFilePath = pdbFilePathBuilder.ToString(); + int length = 0; + while (length < pdbFilePathBuilder.Length && pdbFilePathBuilder[length] != '\0') + { + length++; + } + _pdbFilePath = new string(pdbFilePathBuilder, 0, length); } _ngenWriter.OpenModW(originalDllPath, Path.GetFileName(originalDllPath), out _pdbMod); diff --git a/src/coreclr/tools/aot/ILCompiler.Diagnostics/SymNgenWriterWrapper.cs b/src/coreclr/tools/aot/ILCompiler.Diagnostics/SymNgenWriterWrapper.cs index 8a1166f43a39bf..619f319888fc9f 100644 --- a/src/coreclr/tools/aot/ILCompiler.Diagnostics/SymNgenWriterWrapper.cs +++ b/src/coreclr/tools/aot/ILCompiler.Diagnostics/SymNgenWriterWrapper.cs @@ -21,6 +21,7 @@ private SymNgenWriterWrapper(IntPtr writer2Inst) { var iid = ISymNGenWriter2.IID; int hr = Marshal.QueryInterface(ptr, ref iid, out IntPtr ngenWriterInst); + Marshal.Release(ptr); if (hr != 0) { return null; From a3a556050bdf6f36771bbd9a41bde2bec617649b Mon Sep 17 00:00:00 2001 From: Andy Gocke Date: Thu, 9 Jun 2022 11:28:23 -0700 Subject: [PATCH 011/337] Manually skip IL2118 --- eng/testing/tests.wasm.targets | 2 ++ 1 file changed, 2 insertions(+) diff --git a/eng/testing/tests.wasm.targets b/eng/testing/tests.wasm.targets index bcc4923f40d778..6870091c66bb27 100644 --- a/eng/testing/tests.wasm.targets +++ b/eng/testing/tests.wasm.targets @@ -7,6 +7,8 @@ true true + + $(NoWarn);IL2118 $([MSBuild]::NormalizeDirectory($(MonoProjectRoot), 'wasm', 'emsdk')) From 77a8d3c818317ac55b2f0c2aca2d68526792a3ab Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 9 Jun 2022 20:55:29 +0200 Subject: [PATCH 012/337] [main] Update dependencies from dotnet/arcade (#69643) * Update dependencies from https://github.com/dotnet/arcade build 20220519.3 Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.ApiCompat , Microsoft.DotNet.XUnitExtensions , Microsoft.DotNet.GenAPI , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.GenFacades , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.Helix.Sdk From Version 2.5.1-beta.22255.2 -> To Version 2.5.1-beta.22269.3 * Update dependencies from https://github.com/dotnet/arcade build 20220523.1 Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.ApiCompat , Microsoft.DotNet.XUnitExtensions , Microsoft.DotNet.GenAPI , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.GenFacades , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.Helix.Sdk From Version 2.5.1-beta.22255.2 -> To Version 2.5.1-beta.22273.1 * Update dependencies from https://github.com/dotnet/arcade build 20220524.3 Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.ApiCompat , Microsoft.DotNet.XUnitExtensions , Microsoft.DotNet.GenAPI , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.GenFacades , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.Helix.Sdk From Version 2.5.1-beta.22255.2 -> To Version 2.5.1-beta.22274.3 * Update dependencies from https://github.com/dotnet/arcade build 20220524.7 Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.ApiCompat , Microsoft.DotNet.XUnitExtensions , Microsoft.DotNet.GenAPI , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.GenFacades , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.Helix.Sdk From Version 2.5.1-beta.22255.2 -> To Version 2.5.1-beta.22274.7 * Update dependencies from https://github.com/dotnet/arcade build 20220525.1 Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.ApiCompat , Microsoft.DotNet.XUnitExtensions , Microsoft.DotNet.GenAPI , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.GenFacades , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.Helix.Sdk From Version 2.5.1-beta.22255.2 -> To Version 2.5.1-beta.22275.1 * Update dependencies from https://github.com/dotnet/arcade build 20220525.2 Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.ApiCompat , Microsoft.DotNet.XUnitExtensions , Microsoft.DotNet.GenAPI , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.GenFacades , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.Helix.Sdk From Version 2.5.1-beta.22255.2 -> To Version 2.5.1-beta.22275.2 * Update dependencies from https://github.com/dotnet/arcade build 20220526.1 Microsoft.DotNet.ApiCompat , Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 7.0.0-beta.22255.2 -> To Version 7.0.0-beta.22276.1 * Update dependencies from https://github.com/dotnet/arcade build 20220530.2 Microsoft.DotNet.ApiCompat , Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 7.0.0-beta.22255.2 -> To Version 7.0.0-beta.22280.2 * Update dependencies from https://github.com/dotnet/arcade build 20220531.1 Microsoft.DotNet.ApiCompat , Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 7.0.0-beta.22255.2 -> To Version 7.0.0-beta.22281.1 * Update dependencies from https://github.com/dotnet/arcade build 20220601.2 Microsoft.DotNet.ApiCompat , Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 7.0.0-beta.22255.2 -> To Version 7.0.0-beta.22301.2 * Update dependencies from https://github.com/dotnet/arcade build 20220606.1 Microsoft.DotNet.ApiCompat , Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 7.0.0-beta.22255.2 -> To Version 7.0.0-beta.22306.1 * Update dependencies from https://github.com/dotnet/arcade build 20220606.2 Microsoft.DotNet.ApiCompat , Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 7.0.0-beta.22255.2 -> To Version 7.0.0-beta.22306.2 * Update dependencies from https://github.com/dotnet/arcade build 20220608.5 Microsoft.DotNet.ApiCompat , Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 7.0.0-beta.22255.2 -> To Version 7.0.0-beta.22308.5 Co-authored-by: dotnet-maestro[bot] Co-authored-by: Premek Vysoky Co-authored-by: Larry Ewing --- eng/Version.Details.xml | 76 +++++++++++++++--------------- eng/Versions.props | 32 ++++++------- eng/common/init-tools-native.ps1 | 11 +++-- eng/common/native/init-compiler.sh | 2 +- eng/common/tools.ps1 | 4 ++ global.json | 6 +-- 6 files changed, 68 insertions(+), 63 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index df1d92585c1e8e..1aa1706e9d202e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -54,77 +54,77 @@ - + https://github.com/dotnet/arcade - ba1c3aff4be864c493031d989259ef92aaa23fc3 + d681cd3568168a97aa4cf50a61af9ec74d307eb8 - + https://github.com/dotnet/arcade - ba1c3aff4be864c493031d989259ef92aaa23fc3 + d681cd3568168a97aa4cf50a61af9ec74d307eb8 - + https://github.com/dotnet/arcade - ba1c3aff4be864c493031d989259ef92aaa23fc3 + d681cd3568168a97aa4cf50a61af9ec74d307eb8 - + https://github.com/dotnet/arcade - ba1c3aff4be864c493031d989259ef92aaa23fc3 + d681cd3568168a97aa4cf50a61af9ec74d307eb8 - + https://github.com/dotnet/arcade - ba1c3aff4be864c493031d989259ef92aaa23fc3 + d681cd3568168a97aa4cf50a61af9ec74d307eb8 - + https://github.com/dotnet/arcade - ba1c3aff4be864c493031d989259ef92aaa23fc3 + d681cd3568168a97aa4cf50a61af9ec74d307eb8 - + https://github.com/dotnet/arcade - ba1c3aff4be864c493031d989259ef92aaa23fc3 + d681cd3568168a97aa4cf50a61af9ec74d307eb8 - + https://github.com/dotnet/arcade - ba1c3aff4be864c493031d989259ef92aaa23fc3 + d681cd3568168a97aa4cf50a61af9ec74d307eb8 - + https://github.com/dotnet/arcade - ba1c3aff4be864c493031d989259ef92aaa23fc3 + d681cd3568168a97aa4cf50a61af9ec74d307eb8 - + https://github.com/dotnet/arcade - ba1c3aff4be864c493031d989259ef92aaa23fc3 + d681cd3568168a97aa4cf50a61af9ec74d307eb8 - + https://github.com/dotnet/arcade - ba1c3aff4be864c493031d989259ef92aaa23fc3 + d681cd3568168a97aa4cf50a61af9ec74d307eb8 - + https://github.com/dotnet/arcade - ba1c3aff4be864c493031d989259ef92aaa23fc3 + d681cd3568168a97aa4cf50a61af9ec74d307eb8 - + https://github.com/dotnet/arcade - ba1c3aff4be864c493031d989259ef92aaa23fc3 + d681cd3568168a97aa4cf50a61af9ec74d307eb8 - + https://github.com/dotnet/arcade - ba1c3aff4be864c493031d989259ef92aaa23fc3 + d681cd3568168a97aa4cf50a61af9ec74d307eb8 - + https://github.com/dotnet/arcade - ba1c3aff4be864c493031d989259ef92aaa23fc3 + d681cd3568168a97aa4cf50a61af9ec74d307eb8 - + https://github.com/dotnet/arcade - ba1c3aff4be864c493031d989259ef92aaa23fc3 + d681cd3568168a97aa4cf50a61af9ec74d307eb8 - + https://github.com/dotnet/arcade - ba1c3aff4be864c493031d989259ef92aaa23fc3 + d681cd3568168a97aa4cf50a61af9ec74d307eb8 - + https://github.com/dotnet/arcade - ba1c3aff4be864c493031d989259ef92aaa23fc3 + d681cd3568168a97aa4cf50a61af9ec74d307eb8 https://github.com/microsoft/vstest @@ -254,9 +254,9 @@ https://github.com/dotnet/xharness a1d9a67e971fc0b8724507847491fe93f65728db - + https://github.com/dotnet/arcade - ba1c3aff4be864c493031d989259ef92aaa23fc3 + d681cd3568168a97aa4cf50a61af9ec74d307eb8 https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/eng/Versions.props b/eng/Versions.props index 981629491f417a..58bed2dbf29d8d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -53,22 +53,22 @@ 2.0.0-preview.4.22252.4 - 7.0.0-beta.22255.2 - 7.0.0-beta.22255.2 - 7.0.0-beta.22255.2 - 7.0.0-beta.22255.2 - 7.0.0-beta.22255.2 - 7.0.0-beta.22255.2 - 2.5.1-beta.22255.2 - 7.0.0-beta.22255.2 - 7.0.0-beta.22255.2 - 7.0.0-beta.22255.2 - 7.0.0-beta.22255.2 - 7.0.0-beta.22255.2 - 7.0.0-beta.22255.2 - 7.0.0-beta.22255.2 - 7.0.0-beta.22255.2 - 7.0.0-beta.22255.2 + 7.0.0-beta.22308.5 + 7.0.0-beta.22308.5 + 7.0.0-beta.22308.5 + 7.0.0-beta.22308.5 + 7.0.0-beta.22308.5 + 7.0.0-beta.22308.5 + 2.5.1-beta.22308.5 + 7.0.0-beta.22308.5 + 7.0.0-beta.22308.5 + 7.0.0-beta.22308.5 + 7.0.0-beta.22308.5 + 7.0.0-beta.22308.5 + 7.0.0-beta.22308.5 + 7.0.0-beta.22308.5 + 7.0.0-beta.22308.5 + 7.0.0-beta.22308.5 6.0.0-preview.1.102 diff --git a/eng/common/init-tools-native.ps1 b/eng/common/init-tools-native.ps1 index 413adea4365b12..24a5e65de1b3e3 100644 --- a/eng/common/init-tools-native.ps1 +++ b/eng/common/init-tools-native.ps1 @@ -93,7 +93,7 @@ try { $ToolVersion = "" } $ArcadeToolsDirectory = "C:\arcade-tools" - if (Test-Path $ArcadeToolsDirectory -eq $False) { + if (-not (Test-Path $ArcadeToolsDirectory)) { Write-Error "Arcade tools directory '$ArcadeToolsDirectory' was not found; artifacts were not properly installed." exit 1 } @@ -103,13 +103,14 @@ try { exit 1 } $BinPathFile = "$($ToolDirectory.FullName)\binpath.txt" - if (Test-Path -Path "$BinPathFile" -eq $False) { + if (-not (Test-Path -Path "$BinPathFile")) { Write-Error "Unable to find binpath.txt in '$($ToolDirectory.FullName)' ($ToolName $ToolVersion); artifact is either installed incorrectly or is not a bootstrappable tool." exit 1 } $BinPath = Get-Content "$BinPathFile" - Write-Host "Adding $ToolName to the path ($(Convert-Path -Path $BinPath))..." - Write-Host "##vso[task.prependpath]$(Convert-Path -Path $BinPath)" + $ToolPath = Convert-Path -Path $BinPath + Write-Host "Adding $ToolName to the path ($ToolPath)..." + Write-Host "##vso[task.prependpath]$ToolPath" } } exit 0 @@ -188,7 +189,7 @@ try { Write-Host "##vso[task.prependpath]$(Convert-Path -Path $InstallBin)" return $InstallBin } - else { + elseif (-not ($PathPromotion)) { Write-PipelineTelemetryError -Category 'NativeToolsBootstrap' -Message 'Native tools install directory does not exist, installation failed' exit 1 } diff --git a/eng/common/native/init-compiler.sh b/eng/common/native/init-compiler.sh index 4b99a9cad3b772..6d7ba15e5f2b5d 100644 --- a/eng/common/native/init-compiler.sh +++ b/eng/common/native/init-compiler.sh @@ -71,7 +71,7 @@ if [[ -z "$CLR_CC" ]]; then # Set default versions if [[ -z "$majorVersion" ]]; then # note: gcc (all versions) and clang versions higher than 6 do not have minor version in file name, if it is zero. - if [[ "$compiler" == "clang" ]]; then versions=( 14 13 12 11 10 9 8 7 6.0 5.0 4.0 3.9 3.8 3.7 3.6 3.5 ) + if [[ "$compiler" == "clang" ]]; then versions=( 13 12 11 10 9 8 7 6.0 5.0 4.0 3.9 3.8 3.7 3.6 3.5 ) elif [[ "$compiler" == "gcc" ]]; then versions=( 12 11 10 9 8 7 6 5 4.9 ); fi for version in "${versions[@]}"; do diff --git a/eng/common/tools.ps1 b/eng/common/tools.ps1 index 797f05292a8515..423bd962e9661b 100644 --- a/eng/common/tools.ps1 +++ b/eng/common/tools.ps1 @@ -635,6 +635,10 @@ function InitializeNativeTools() { InstallDirectory = "$ToolsDir" } } + if (Test-Path variable:NativeToolsOnMachine) { + Write-Host "Variable NativeToolsOnMachine detected, enabling native tool path promotion..." + $nativeArgs += @{ PathPromotion = $true } + } & "$PSScriptRoot/init-tools-native.ps1" @nativeArgs } } diff --git a/global.json b/global.json index 7809f8ebf190d0..2ae7c6b778d6e2 100644 --- a/global.json +++ b/global.json @@ -8,9 +8,9 @@ "dotnet": "7.0.100-preview.3.22179.4" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.22266.1", - "Microsoft.DotNet.Helix.Sdk": "7.0.0-beta.22266.1", - "Microsoft.DotNet.SharedFramework.Sdk": "7.0.0-beta.22266.1", + "Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.22308.5", + "Microsoft.DotNet.Helix.Sdk": "7.0.0-beta.22308.5", + "Microsoft.DotNet.SharedFramework.Sdk": "7.0.0-beta.22308.5", "Microsoft.Build.NoTargets": "3.5.0", "Microsoft.Build.Traversal": "3.1.6", "Microsoft.NET.Sdk.IL": "7.0.0-preview.6.22305.4" From d78f3648b45aeccdcfc198525eff1c3a2ade6e05 Mon Sep 17 00:00:00 2001 From: Steve Dunn Date: Thu, 9 Jun 2022 20:14:03 +0100 Subject: [PATCH 013/337] Support immutable types with configuration binding (#67258) Merging. Thanks @SteveDunn for your contribution. --- .../src/ConfigurationBinder.cs | 138 +++- ...oft.Extensions.Configuration.Binder.csproj | 9 +- .../src/Resources/Strings.resx | 19 +- .../tests/ConfigurationBinderTests.cs | 639 +++++++++++++++++- ...tensions.Configuration.Binder.Tests.csproj | 1 + 5 files changed, 790 insertions(+), 16 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs index e56a0875bd46ec..2d2f5658188a44 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs @@ -9,6 +9,7 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; +using Microsoft.Extensions.Internal; namespace Microsoft.Extensions.Configuration { @@ -328,9 +329,10 @@ private static object BindToCollection(Type type, IConfiguration config, BinderO [RequiresUnreferencedCode(TrimmingWarningMessage)] private static void BindInstance( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] - Type type, - BindingPoint bindingPoint, IConfiguration config, BinderOptions options) + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type, + BindingPoint bindingPoint, + IConfiguration config, + BinderOptions options) { // if binding IConfigurationSection, break early if (type == typeof(IConfigurationSection)) @@ -381,7 +383,7 @@ private static void BindInstance( return; // We are already done if binding to a new collection instance worked } - bindingPoint.SetValue(CreateInstance(type)); + bindingPoint.SetValue(CreateInstance(type, config, options)); } // See if it's a Dictionary @@ -407,23 +409,63 @@ private static void BindInstance( } } - [RequiresUnreferencedCode("In case type is a Nullable, cannot statically analyze what the underlying type is so its members may be trimmed.")] - private static object CreateInstance([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type type) + [RequiresUnreferencedCode( + "In case type is a Nullable, cannot statically analyze what the underlying type is so its members may be trimmed.")] + private static object CreateInstance( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | + DynamicallyAccessedMemberTypes.NonPublicConstructors)] + Type type, + IConfiguration config, + BinderOptions options) { Debug.Assert(!type.IsArray); - if (type.IsAbstract) + if (type.IsInterface || type.IsAbstract) { throw new InvalidOperationException(SR.Format(SR.Error_CannotActivateAbstractOrInterface, type)); } - if (!type.IsValueType) + ConstructorInfo[] constructors = type.GetConstructors(BindingFlags.Public | BindingFlags.Instance); + + bool hasParameterlessConstructor = + type.IsValueType || constructors.Any(ctor => ctor.GetParameters().Length == 0); + + if (!type.IsValueType && constructors.Length == 0) + { + throw new InvalidOperationException(SR.Format(SR.Error_MissingPublicInstanceConstructor, type)); + } + + if (constructors.Length > 1 && !hasParameterlessConstructor) { - bool hasDefaultConstructor = type.GetConstructors(DeclaredOnlyLookup).Any(ctor => ctor.IsPublic && ctor.GetParameters().Length == 0); - if (!hasDefaultConstructor) + throw new InvalidOperationException(SR.Format(SR.Error_MultipleParameterizedConstructors, type)); + } + + if (constructors.Length == 1 && !hasParameterlessConstructor) + { + ConstructorInfo constructor = constructors[0]; + ParameterInfo[] parameters = constructor.GetParameters(); + + if (!CanBindToTheseConstructorParameters(parameters, out string nameOfInvalidParameter)) + { + throw new InvalidOperationException(SR.Format(SR.Error_CannotBindToConstructorParameter, type, nameOfInvalidParameter)); + } + + + List properties = GetAllProperties(type); + + if (!DoAllParametersHaveEquivalentProperties(parameters, properties, out string nameOfInvalidParameters)) + { + throw new InvalidOperationException(SR.Format(SR.Error_ConstructorParametersDoNotMatchProperties, type, nameOfInvalidParameters)); + } + + object?[] parameterValues = new object?[parameters.Length]; + + for (int index = 0; index < parameters.Length; index++) { - throw new InvalidOperationException(SR.Format(SR.Error_MissingParameterlessConstructor, type)); + parameterValues[index] = BindParameter(parameters[index], type, config, options); } + + return constructor.Invoke(parameterValues); } object? instance; @@ -439,6 +481,46 @@ private static object CreateInstance([DynamicallyAccessedMembers(DynamicallyAcce return instance ?? throw new InvalidOperationException(SR.Format(SR.Error_FailedToActivate, type)); } + private static bool DoAllParametersHaveEquivalentProperties(ParameterInfo[] parameters, + List properties, out string missing) + { + HashSet propertyNames = new(StringComparer.OrdinalIgnoreCase); + foreach (PropertyInfo prop in properties) + { + propertyNames.Add(prop.Name); + } + + List missingParameters = new(); + + foreach (ParameterInfo parameter in parameters) + { + string name = parameter.Name!; + if (!propertyNames.Contains(name)) + { + missingParameters.Add(name); + } + } + + missing = string.Join(",", missingParameters); + + return missing.Length == 0; + } + + private static bool CanBindToTheseConstructorParameters(ParameterInfo[] constructorParameters, out string nameOfInvalidParameter) + { + nameOfInvalidParameter = string.Empty; + foreach (ParameterInfo p in constructorParameters) + { + if (p.IsOut || p.IsIn || p.ParameterType.IsByRef) + { + nameOfInvalidParameter = p.Name!; // never null as we're not passed return value parameters: https://docs.microsoft.com/en-us/dotnet/api/system.reflection.parameterinfo.name?view=net-6.0#remarks + return false; + } + } + + return true; + } + [RequiresUnreferencedCode("Cannot statically analyze what the element type is of the value objects in the dictionary so its members may be trimmed.")] private static void BindDictionary( object dictionary, @@ -687,6 +769,40 @@ private static List GetAllProperties( return allProperties; } + [RequiresUnreferencedCode(PropertyTrimmingWarningMessage)] + private static object? BindParameter(ParameterInfo parameter, Type type, IConfiguration config, + BinderOptions options) + { + string? parameterName = parameter.Name; + + if (parameterName is null) + { + throw new InvalidOperationException(SR.Format(SR.Error_ParameterBeingBoundToIsUnnamed, type)); + } + + var propertyBindingPoint = new BindingPoint(initialValue: config.GetSection(parameterName).Value, isReadOnly: false); + + if (propertyBindingPoint.Value is null) + { + if (ParameterDefaultValue.TryGetDefaultValue(parameter, out object? defaultValue)) + { + propertyBindingPoint.SetValue(defaultValue); + } + else + { + throw new InvalidOperationException(SR.Format(SR.Error_ParameterHasNoMatchingConfig, type, parameterName)); + } + } + + BindInstance( + parameter.ParameterType, + propertyBindingPoint, + config.GetSection(parameterName), + options); + + return propertyBindingPoint.Value; + } + private static string GetPropertyName(MemberInfo property) { ThrowHelper.ThrowIfNull(property); diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Microsoft.Extensions.Configuration.Binder.csproj b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Microsoft.Extensions.Configuration.Binder.csproj index 747e97a01882fc..d74d502d6b573e 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Microsoft.Extensions.Configuration.Binder.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Microsoft.Extensions.Configuration.Binder.csproj @@ -9,14 +9,19 @@ - + + + + + + + diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Resources/Strings.resx b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Resources/Strings.resx index dca7cc1bf353b4..197b325252ef91 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Resources/Strings.resx +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/Resources/Strings.resx @@ -120,6 +120,12 @@ Cannot create instance of type '{0}' because it is either abstract or an interface. + + Cannot create instance of type '{0}' because one or more parameters cannot be bound to. Constructor parameters cannot be declared as in, out, or ref. Invalid parameters are: '{1}' + + + Cannot create instance of type '{0}' because one or more parameters cannot be bound to. Constructor parameters must have corresponding properties. Fields are not supported. Missing properties are: '{1}' + Failed to convert configuration value at '{0}' to type '{1}'. @@ -129,8 +135,17 @@ '{0}' was set on the provided {1}, but the following properties were not found on the instance of {2}: {3} - - Cannot create instance of type '{0}' because it is missing a public parameterless constructor. + + Cannot create instance of type '{0}' because it is missing a public instance constructor. + + + Cannot create instance of type '{0}' because it has multiple public parameterized constructors. + + + Cannot create instance of type '{0}' because one or more parameters are unnamed. + + + Cannot create instance of type '{0}' because parameter '{1}' has no matching config. Each parameter in the constructor that does not have a default value must have a corresponding config entry. Cannot create instance of type '{0}' because multidimensional arrays are not supported. diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/ConfigurationBinderTests.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/ConfigurationBinderTests.cs index 04e3ca51977627..932b6111fb25a3 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/ConfigurationBinderTests.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/ConfigurationBinderTests.cs @@ -112,6 +112,238 @@ public class DerivedOptionsWithIConfigurationSection : DerivedOptions public IConfigurationSection DerivedSection { get; set; } } + public record struct RecordStructTypeOptions(string Color, int Length); + + // Here, the constructor has three parameters, but not all of those match + // match to a property or field + public class ClassWhereParametersDoNotMatchProperties + { + public string Name { get; } + public string Address { get; } + + public ClassWhereParametersDoNotMatchProperties(string name, string address, int age) + { + Name = name; + Address = address; + } + } + + // Here, the constructor has three parameters, and two of them match properties + // and one of them match a field. + public class ClassWhereParametersMatchPropertiesAndFields + { + private int Age; + + public string Name { get; } + public string Address { get; } + + public ClassWhereParametersMatchPropertiesAndFields(string name, string address, int age) + { + Name = name; + Address = address; + Age = age; + } + + public int GetAge() => Age; + } + + public record RecordWhereParametersHaveDefaultValue(string Name, string Address, int Age = 42); + + public record ClassWhereParametersHaveDefaultValue + { + public string? Name { get; } + public string Address { get; } + public int Age { get; } + + public ClassWhereParametersHaveDefaultValue(string? name, string address, int age = 42) + { + Name = name; + Address = address; + Age = age; + } + } + + + public record RecordTypeOptions(string Color, int Length); + + public record Line(string Color, int Length, int Thickness); + + public class ClassWithMatchingParametersAndProperties + { + private readonly string _color; + + public ClassWithMatchingParametersAndProperties(string Color, int Length) + { + _color = Color; + this.Length = Length; + } + + public int Length { get; set; } + + public string Color + { + get => _color; + init => _color = "the color is " + value; + } + } + + public readonly record struct ReadonlyRecordStructTypeOptions(string Color, int Length); + + public class ContainerWithNestedImmutableObject + { + public string ContainerName { get; set; } + public ImmutableLengthAndColorClass LengthAndColor { get; set; } + } + + public struct MutableStructWithConstructor + { + public MutableStructWithConstructor(string randomParameter) + { + Color = randomParameter; + Length = randomParameter.Length; + } + + public string Color { get; set; } + public int Length { get; set; } + } + + public class ImmutableLengthAndColorClass + { + public ImmutableLengthAndColorClass(string color, int length) + { + Color = color; + Length = length; + } + + public string Color { get; } + public int Length { get; } + } + + public class ImmutableClassWithOneParameterizedConstructor + { + public ImmutableClassWithOneParameterizedConstructor(string string1, int int1, string string2, int int2) + { + String1 = string1; + Int1 = int1; + String2 = string2; + Int2 = int2; + } + + public string String1 { get; } + public string String2 { get; } + public int Int1 { get; } + public int Int2 { get; } + } + + public class ImmutableClassWithOneParameterizedConstructorButWithInParameter + { + public ImmutableClassWithOneParameterizedConstructorButWithInParameter(in string string1, int int1, string string2, int int2) + { + String1 = string1; + Int1 = int1; + String2 = string2; + Int2 = int2; + } + + public string String1 { get; } + public string String2 { get; } + public int Int1 { get; } + public int Int2 { get; } + } + + public class ImmutableClassWithOneParameterizedConstructorButWithRefParameter + { + public ImmutableClassWithOneParameterizedConstructorButWithRefParameter(string string1, ref int int1, string string2, int int2) + { + String1 = string1; + Int1 = int1; + String2 = string2; + Int2 = int2; + } + + public string String1 { get; } + public string String2 { get; } + public int Int1 { get; } + public int Int2 { get; } + } + + public class ImmutableClassWithOneParameterizedConstructorButWithOutParameter + { + public ImmutableClassWithOneParameterizedConstructorButWithOutParameter(string string1, int int1, + string string2, out decimal int2) + { + String1 = string1; + Int1 = int1; + String2 = string2; + int2 = 0; + } + + public string String1 { get; } + public string String2 { get; } + public int Int1 { get; } + public int Int2 { get; } + } + + public class ImmutableClassWithMultipleParameterizedConstructors + { + public ImmutableClassWithMultipleParameterizedConstructors(string string1, int int1) + { + String1 = string1; + Int1 = int1; + } + + public ImmutableClassWithMultipleParameterizedConstructors(string string1, int int1, string string2) + { + String1 = string1; + Int1 = int1; + String2 = string2; + } + + public ImmutableClassWithMultipleParameterizedConstructors(string string1, int int1, string string2, int int2) + { + String1 = string1; + Int1 = int1; + String2 = string2; + Int2 = int2; + } + + public ImmutableClassWithMultipleParameterizedConstructors(string string1) + { + String1 = string1; + } + + public string String1 { get; } + public string String2 { get; } + public int Int1 { get; } + public int Int2 { get; } + } + + public class SemiImmutableClass + { + public SemiImmutableClass(string color, int length) + { + Color = color; + Length = length; + } + + public string Color { get; } + public int Length { get; } + public decimal Thickness { get; set; } + } + + public class SemiImmutableClassWithInit + { + public SemiImmutableClassWithInit(string color, int length) + { + Color = color; + Length = length; + } + + public string Color { get; } + public int Length { get; } + public decimal Thickness { get; init; } + } + public struct ValueTypeOptions { public int MyInt32 { get; set; } @@ -934,10 +1166,136 @@ public void ExceptionWhenTryingToBindClassWithoutParameterlessConstructor() var exception = Assert.Throws( () => config.Bind(new TestOptions())); Assert.Equal( - SR.Format(SR.Error_MissingParameterlessConstructor, typeof(ClassWithoutPublicConstructor)), + SR.Format(SR.Error_MissingPublicInstanceConstructor, typeof(ClassWithoutPublicConstructor)), + exception.Message); + } + + [Fact] + public void ExceptionWhenTryingToBindClassWherePropertiesDoMatchConstructorParameters() + { + var input = new Dictionary + { + {"ClassWhereParametersDoNotMatchPropertiesProperty:Name", "John"}, + {"ClassWhereParametersDoNotMatchPropertiesProperty:Address", "123, Abc St."}, + {"ClassWhereParametersDoNotMatchPropertiesProperty:Age", "42"} + }; + + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(input); + var config = configurationBuilder.Build(); + + var exception = Assert.Throws( + () => config.Bind(new TestOptions())); + Assert.Equal( + SR.Format(SR.Error_ConstructorParametersDoNotMatchProperties, typeof(ClassWhereParametersDoNotMatchProperties), "age"), + exception.Message); + } + + [Fact] + public void ExceptionWhenTryingToBindToConstructorWithMissingConfig() + { + var input = new Dictionary + { + {"LineProperty:Color", "Red"}, + {"LineProperty:Length", "22"} + }; + + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(input); + var config = configurationBuilder.Build(); + + var exception = Assert.Throws( + () => config.Bind(new TestOptions())); + Assert.Equal( + SR.Format(SR.Error_ParameterHasNoMatchingConfig, typeof(Line), nameof(Line.Thickness)), + exception.Message); + } + + [Fact] + public void ExceptionWhenTryingToBindConfigToClassWhereNoMatchingParameterIsFoundInConstructor() + { + var input = new Dictionary + { + {"ClassWhereParametersDoNotMatchPropertiesProperty:Name", "John"}, + {"ClassWhereParametersDoNotMatchPropertiesProperty:Address", "123, Abc St."}, + {"ClassWhereParametersDoNotMatchPropertiesProperty:Age", "42"} + }; + + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(input); + var config = configurationBuilder.Build(); + + var exception = Assert.Throws( + () => config.Bind(new TestOptions())); + Assert.Equal( + SR.Format(SR.Error_ConstructorParametersDoNotMatchProperties, typeof(ClassWhereParametersDoNotMatchProperties), "age"), + exception.Message); + } + + [Fact] + public void BindsToClassConstructorParametersWithDefaultValues() + { + var input = new Dictionary + { + {"ClassWhereParametersHaveDefaultValueProperty:Name", "John"}, + {"ClassWhereParametersHaveDefaultValueProperty:Address", "123, Abc St."} + }; + + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(input); + var config = configurationBuilder.Build(); + + TestOptions testOptions = new TestOptions(); + + config.Bind(testOptions); + Assert.Equal("John", testOptions.ClassWhereParametersHaveDefaultValueProperty.Name); + Assert.Equal("123, Abc St.", testOptions.ClassWhereParametersHaveDefaultValueProperty.Address); + Assert.Equal(42, testOptions.ClassWhereParametersHaveDefaultValueProperty.Age); + } + + [Fact] + public void FieldsNotSupported_ExceptionBindingToConstructorWithParameterMatchingAField() + { + var input = new Dictionary + { + {"ClassWhereParametersMatchPropertiesAndFieldsProperty:Name", "John"}, + {"ClassWhereParametersMatchPropertiesAndFieldsProperty:Address", "123, Abc St."}, + {"ClassWhereParametersMatchPropertiesAndFieldsProperty:Age", "42"} + }; + + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(input); + var config = configurationBuilder.Build(); + + var exception = Assert.Throws( + () => config.Bind(new TestOptions())); + + Assert.Equal( + SR.Format(SR.Error_ConstructorParametersDoNotMatchProperties, typeof(ClassWhereParametersMatchPropertiesAndFields), "age"), exception.Message); } + [Fact] + public void BindsToRecordPrimaryConstructorParametersWithDefaultValues() + { + var input = new Dictionary + { + {"RecordWhereParametersHaveDefaultValueProperty:Name", "John"}, + {"RecordWhereParametersHaveDefaultValueProperty:Address", "123, Abc St."} + }; + + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(input); + var config = configurationBuilder.Build(); + + TestOptions testOptions = new TestOptions(); + + config.Bind(testOptions); + Assert.Equal("John", testOptions.RecordWhereParametersHaveDefaultValueProperty.Name); + Assert.Equal("123, Abc St.", testOptions.RecordWhereParametersHaveDefaultValueProperty.Address); + Assert.Equal(42, testOptions.RecordWhereParametersHaveDefaultValueProperty.Age); + } + [Fact] public void ExceptionWhenTryingToBindToTypeThrowsWhenActivated() { @@ -994,6 +1352,280 @@ public void CanBindValueTypeOptions() Assert.Equal("hello world", options.MyString); } + [Fact] + public void CanBindImmutableClass() + { + var dic = new Dictionary + { + {"Length", "42"}, + {"Color", "Green"}, + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + + var options = config.Get(); + Assert.Equal(42, options.Length); + Assert.Equal("Green", options.Color); + } + + [Fact] + public void CanBindMutableClassWitNestedImmutableObject() + { + var dic = new Dictionary + { + {"ContainerName", "Container123"}, + {"LengthAndColor:Length", "42"}, + {"LengthAndColor:Color", "Green"}, + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + + var options = config.Get(); + Assert.Equal("Container123", options.ContainerName); + Assert.Equal(42, options.LengthAndColor.Length); + Assert.Equal("Green", options.LengthAndColor.Color); + } + + // If the immutable type has multiple public parameterized constructors, then throw + // an exception. + [Fact] + public void CanBindImmutableClass_ThrowsOnMultipleParameterizedConstructors() + { + var dic = new Dictionary + { + {"String1", "s1"}, + {"Int1", "1"}, + {"String2", "s2"}, + {"Int2", "2"}, + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + + string expectedMessage = SR.Format(SR.Error_MultipleParameterizedConstructors, "Microsoft.Extensions.Configuration.Binder.Test.ConfigurationBinderTests+ImmutableClassWithMultipleParameterizedConstructors"); + + var ex = Assert.Throws(() => config.Get()); + + Assert.Equal(expectedMessage, ex.Message); + } + + // If the immutable type has a parameterized constructor, then throw + // that constructor has an 'in' parameter + [Fact] + public void CanBindImmutableClass_ThrowsOnParameterizedConstructorWithAnInParameter() + { + var dic = new Dictionary + { + {"String1", "s1"}, + {"Int1", "1"}, + {"String2", "s2"}, + {"Int2", "2"}, + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + + string expectedMessage = SR.Format(SR.Error_CannotBindToConstructorParameter, "Microsoft.Extensions.Configuration.Binder.Test.ConfigurationBinderTests+ImmutableClassWithOneParameterizedConstructorButWithInParameter", "string1"); + + var ex = Assert.Throws(() => config.Get()); + + Assert.Equal(expectedMessage, ex.Message); + } + + // If the immutable type has a parameterized constructors, then throw + // that constructor has a 'ref' parameter + [Fact] + public void CanBindImmutableClass_ThrowsOnParameterizedConstructorWithARefParameter() + { + var dic = new Dictionary + { + {"String1", "s1"}, + {"Int1", "1"}, + {"String2", "s2"}, + {"Int2", "2"}, + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + + string expectedMessage = SR.Format(SR.Error_CannotBindToConstructorParameter, "Microsoft.Extensions.Configuration.Binder.Test.ConfigurationBinderTests+ImmutableClassWithOneParameterizedConstructorButWithRefParameter", "int1"); + + var ex = Assert.Throws(() => config.Get()); + + Assert.Equal(expectedMessage, ex.Message); + } + + // If the immutable type has a parameterized constructors, then throw + // if the constructor has an 'out' parameter + [Fact] + public void CanBindImmutableClass_ThrowsOnParameterizedConstructorWithAnOutParameter() + { + var dic = new Dictionary + { + {"String1", "s1"}, + {"Int1", "1"}, + {"String2", "s2"}, + {"Int2", "2"}, + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + + string expectedMessage = SR.Format(SR.Error_CannotBindToConstructorParameter, "Microsoft.Extensions.Configuration.Binder.Test.ConfigurationBinderTests+ImmutableClassWithOneParameterizedConstructorButWithOutParameter", "int2"); + + var ex = Assert.Throws(() => config.Get()); + + Assert.Equal(expectedMessage, ex.Message); + } + + [Fact] + public void CanBindMutableStruct_UnmatchedConstructorsAreIgnored() + { + var dic = new Dictionary + { + {"Length", "42"}, + {"Color", "Green"}, + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + + var options = config.Get(); + Assert.Equal(42, options.Length); + Assert.Equal("Green", options.Color); + } + + // If the immutable type has a public parameterized constructor, + // then pick it. + [Fact] + public void CanBindImmutableClass_PicksParameterizedConstructorIfNoParameterlessConstructorExists() + { + var dic = new Dictionary + { + {"String1", "s1"}, + {"Int1", "1"}, + {"String2", "s2"}, + {"Int2", "2"}, + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + + var options = config.Get(); + Assert.Equal("s1", options.String1); + Assert.Equal("s2", options.String2); + Assert.Equal(1, options.Int1); + Assert.Equal(2, options.Int2); + } + + [Fact] + public void CanBindSemiImmutableClass() + { + var dic = new Dictionary + { + {"Length", "42"}, + {"Color", "Green"}, + {"Thickness", "1.23"}, + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + + var options = config.Get(); + Assert.Equal(42, options.Length); + Assert.Equal("Green", options.Color); + Assert.Equal(1.23m, options.Thickness); + } + + [Fact] + public void CanBindSemiImmutableClass_WithInitProperties() + { + var dic = new Dictionary + { + {"Length", "42"}, + {"Color", "Green"}, + {"Thickness", "1.23"}, + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + + var options = config.Get(); + Assert.Equal(42, options.Length); + Assert.Equal("Green", options.Color); + Assert.Equal(1.23m, options.Thickness); + } + + [Fact] + public void CanBindRecordOptions() + { + var dic = new Dictionary + { + {"Length", "42"}, + {"Color", "Green"}, + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + + var options = config.Get(); + Assert.Equal(42, options.Length); + Assert.Equal("Green", options.Color); + } + + [Fact] + public void CanBindRecordStructOptions() + { + var dic = new Dictionary + { + {"Length", "42"}, + {"Color", "Green"}, + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + + var options = config.Get(); + Assert.Equal(42, options.Length); + Assert.Equal("Green", options.Color); + } + + [Fact] + public void CanBindOnParametersAndProperties_PropertiesAreSetAfterTheConstructor() + { + var dic = new Dictionary + { + {"Length", "42"}, + {"Color", "Green"}, + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + + var options = config.Get(); + Assert.Equal(42, options.Length); + Assert.Equal("the color is Green", options.Color); + } + + [Fact] + public void CanBindReadonlyRecordStructOptions() + { + var dic = new Dictionary + { + {"Length", "42"}, + {"Color", "Green"}, + }; + var configurationBuilder = new ConfigurationBuilder(); + configurationBuilder.AddInMemoryCollection(dic); + var config = configurationBuilder.Build(); + + var options = config.Get(); + Assert.Equal(42, options.Length); + Assert.Equal("Green", options.Color); + } + [Fact] public void CanBindByteArray() { @@ -1153,6 +1785,11 @@ private class TestOptions public ISomeInterface ISomeInterfaceProperty { get; set; } public ClassWithoutPublicConstructor ClassWithoutPublicConstructorProperty { get; set; } + public ClassWhereParametersDoNotMatchProperties ClassWhereParametersDoNotMatchPropertiesProperty { get; set; } + public Line LineProperty { get; set; } + public ClassWhereParametersHaveDefaultValue ClassWhereParametersHaveDefaultValueProperty { get; set; } + public ClassWhereParametersMatchPropertiesAndFields ClassWhereParametersMatchPropertiesAndFieldsProperty { get; set; } + public RecordWhereParametersHaveDefaultValue RecordWhereParametersHaveDefaultValueProperty { get; set; } public int IntProperty { get; set; } diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Microsoft.Extensions.Configuration.Binder.Tests.csproj b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Microsoft.Extensions.Configuration.Binder.Tests.csproj index 8fcc6f146609b7..c15ba1c1c69d1b 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Microsoft.Extensions.Configuration.Binder.Tests.csproj +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/Microsoft.Extensions.Configuration.Binder.Tests.csproj @@ -10,6 +10,7 @@ Link="Common\ConfigurationProviderExtensions.cs" /> + From b603a5decc3de9e5c8146a1292be9a64d1bc71a4 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Thu, 9 Jun 2022 15:18:42 -0400 Subject: [PATCH 014/337] [wasm] Fix passing `shouldContinueOnError` through for the library tests (#70494) The new `Threading*` CI jobs on `runtime-wasm` use `shouldContinueOnError: false` because the tests are known to be unstable right now. But they were not getting correctly forwarded to the base templates. --- eng/pipelines/common/templates/wasm-library-aot-tests.yml | 2 ++ eng/pipelines/common/templates/wasm-library-tests.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/eng/pipelines/common/templates/wasm-library-aot-tests.yml b/eng/pipelines/common/templates/wasm-library-aot-tests.yml index 982002ce90520b..170be62247ca4c 100644 --- a/eng/pipelines/common/templates/wasm-library-aot-tests.yml +++ b/eng/pipelines/common/templates/wasm-library-aot-tests.yml @@ -8,6 +8,7 @@ parameters: platforms: [] runAOT: false runSmokeOnlyArg: '' + shouldContinueOnError: false jobs: @@ -23,3 +24,4 @@ jobs: extraHelixArgs: /p:NeedsToBuildWasmAppsOnHelix=true ${{ parameters.extraHelixArgs }} alwaysRun: ${{ parameters.alwaysRun }} runSmokeOnlyArg: $(_runSmokeTestsOnlyArg) + shouldContinueOnError: ${{ parameters.shouldContinueOnError }} diff --git a/eng/pipelines/common/templates/wasm-library-tests.yml b/eng/pipelines/common/templates/wasm-library-tests.yml index 8ebf5646fc7e56..365ea7386d4004 100644 --- a/eng/pipelines/common/templates/wasm-library-tests.yml +++ b/eng/pipelines/common/templates/wasm-library-tests.yml @@ -7,6 +7,7 @@ parameters: platforms: [] runSmokeOnlyArg: '' scenarios: ['normal'] + shouldContinueOnError: false jobs: @@ -20,6 +21,7 @@ jobs: buildConfig: Release runtimeFlavor: mono platforms: ${{ parameters.platforms }} + shouldContinueOnError: ${{ parameters.shouldContinueOnError }} variables: # map dependencies variables to local variables - name: librariesContainsChange From daffba6b2daf88822fc57c4d53e92d7ed6dd5092 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Thu, 9 Jun 2022 16:09:33 -0400 Subject: [PATCH 015/337] Enable IDE0110 (Remove unnecessary discard) (#70500) --- eng/CodeAnalysis.src.globalconfig | 2 +- .../src/System/Data/Odbc/OdbcParameterHelper.cs | 4 ++-- .../Net/Http/SocketsHttpHandler/Http3RequestStream.cs | 8 ++++---- .../MarshallingAttributeInfo.cs | 2 +- .../X509Certificates/StorePal.Android.AndroidKeyStore.cs | 6 +++--- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/eng/CodeAnalysis.src.globalconfig b/eng/CodeAnalysis.src.globalconfig index a9a8f29956cd27..f246a7b6af4dbf 100644 --- a/eng/CodeAnalysis.src.globalconfig +++ b/eng/CodeAnalysis.src.globalconfig @@ -1546,7 +1546,7 @@ dotnet_diagnostic.IDE0090.severity = silent dotnet_diagnostic.IDE0100.severity = suggestion # IDE0110: Remove unnecessary discard -dotnet_diagnostic.IDE0110.severity = suggestion +dotnet_diagnostic.IDE0110.severity = warning # IDE0120: Simplify LINQ expression dotnet_diagnostic.IDE0120.severity = none diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameterHelper.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameterHelper.cs index 03a01c9735a5e5..450bf1d2d56bba 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameterHelper.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameterHelper.cs @@ -243,8 +243,8 @@ private static int ValueSizeCore(object? value) string svalue => svalue.Length, byte[] bvalue => bvalue.Length, char[] cvalue => cvalue.Length, - byte _ => 1, - char _ => 1, + byte => 1, + char => 1, _ => 0 }; } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs index 64a609afedbff9..59bf3ff97f85a1 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3RequestStream.cs @@ -1189,15 +1189,15 @@ private void HandleReadResponseContentException(Exception ex, CancellationToken switch (ex) { // Peer aborted the stream - case QuicStreamAbortedException _: + case QuicStreamAbortedException: // User aborted the stream - case QuicOperationAbortedException _: + case QuicOperationAbortedException: throw new IOException(SR.net_http_client_execution_error, new HttpRequestException(SR.net_http_client_execution_error, ex)); - case QuicConnectionAbortedException _: + case QuicConnectionAbortedException: // Our connection was reset. Start aborting the connection. Exception abortException = _connection.Abort(ex); throw new IOException(SR.net_http_client_execution_error, new HttpRequestException(SR.net_http_client_execution_error, abortException)); - case Http3ConnectionException _: + case Http3ConnectionException: // A connection-level protocol error has occurred on our stream. _connection.Abort(ex); throw new IOException(SR.net_http_client_execution_error, new HttpRequestException(SR.net_http_client_execution_error, ex)); diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/MarshallingAttributeInfo.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/MarshallingAttributeInfo.cs index f2a98d6b246fd1..061cb4146e682d 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/MarshallingAttributeInfo.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/MarshallingAttributeInfo.cs @@ -455,7 +455,7 @@ private CountInfo CreateCountInfo(AttributeData marshalUsingData, ImmutableHashS } } } - else if (_contextSymbol is INamedTypeSymbol _) + else if (_contextSymbol is INamedTypeSymbol) { // TODO: Handle when we create a struct marshalling generator // Do we want to support CountElementName pointing to only fields, or properties as well? diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Android.AndroidKeyStore.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Android.AndroidKeyStore.cs index 4a1abe1bd9a2b1..6952881cd4dfc2 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Android.AndroidKeyStore.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Android.AndroidKeyStore.cs @@ -56,9 +56,9 @@ public void Add(ICertificatePal cert) // The AndroidKeyStore doesn't support adding DSA private key entries in newer versions (API 23+) // Our minimum supported version (API 21) does support it, but for simplicity, we simply block adding // certificates with DSA private keys on all versions instead of trying to support it on two versions. - SafeDsaHandle _ => throw new PlatformNotSupportedException(SR.Cryptography_X509_StoreDSAPrivateKeyNotSupported), - SafeEcKeyHandle _ => Interop.AndroidCrypto.PAL_KeyAlgorithm.EC, - SafeRsaHandle _ => Interop.AndroidCrypto.PAL_KeyAlgorithm.RSA, + SafeDsaHandle => throw new PlatformNotSupportedException(SR.Cryptography_X509_StoreDSAPrivateKeyNotSupported), + SafeEcKeyHandle => Interop.AndroidCrypto.PAL_KeyAlgorithm.EC, + SafeRsaHandle => Interop.AndroidCrypto.PAL_KeyAlgorithm.RSA, _ => throw new NotSupportedException(SR.NotSupported_KeyAlgorithm) }; From 61ddecc28c021f07bbbe17728e8f4c20ce4e57c6 Mon Sep 17 00:00:00 2001 From: Steve Harter Date: Thu, 9 Jun 2022 15:45:24 -0500 Subject: [PATCH 016/337] Modify tests to distinguish between emit- and interpreted-based invoke (#70114) --- .../Reflection/MethodInvoker.CoreCLR.cs | 17 +++--- .../System/Reflection/InvokeEmitTests.cs | 56 +++++++++++++++++++ .../Reflection/InvokeInterpretedTests.cs | 53 ++++++++++++++++++ .../src/System/LocalAppContextSwitches.cs | 14 +++++ .../System/Reflection/ConstructorInvoker.cs | 17 ++++-- .../System.Reflection/System.Reflection.sln | 42 ++++++++++++++ .../System.Reflection.InvokeEmit.Tests.csproj | 22 ++++++++ .../InvokeEmit/runtimeconfig.template.json | 5 ++ ....Reflection.InvokeInterpreted.Tests.csproj | 22 ++++++++ .../runtimeconfig.template.json | 5 ++ .../System.Runtime/System.Runtime.sln | 42 ++++++++++++++ ....Runtime.ReflectionInvokeEmit.Tests.csproj | 18 ++++++ .../InvokeEmit/runtimeconfig.template.json | 5 ++ ...e.ReflectionInvokeInterpreted.Tests.csproj | 18 ++++++ .../runtimeconfig.template.json | 5 ++ .../tests/System/Reflection/PointerTests.cs | 1 - 16 files changed, 328 insertions(+), 14 deletions(-) create mode 100644 src/libraries/Common/tests/System/Reflection/InvokeEmitTests.cs create mode 100644 src/libraries/Common/tests/System/Reflection/InvokeInterpretedTests.cs create mode 100644 src/libraries/System.Reflection/tests/InvokeEmit/System.Reflection.InvokeEmit.Tests.csproj create mode 100644 src/libraries/System.Reflection/tests/InvokeEmit/runtimeconfig.template.json create mode 100644 src/libraries/System.Reflection/tests/InvokeInterpreted/System.Reflection.InvokeInterpreted.Tests.csproj create mode 100644 src/libraries/System.Reflection/tests/InvokeInterpreted/runtimeconfig.template.json create mode 100644 src/libraries/System.Runtime/tests/System/Reflection/InvokeEmit/System.Runtime.ReflectionInvokeEmit.Tests.csproj create mode 100644 src/libraries/System.Runtime/tests/System/Reflection/InvokeEmit/runtimeconfig.template.json create mode 100644 src/libraries/System.Runtime/tests/System/Reflection/InvokeInterpreted/System.Runtime.ReflectionInvokeInterpreted.Tests.csproj create mode 100644 src/libraries/System.Runtime/tests/System/Reflection/InvokeInterpreted/runtimeconfig.template.json diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/MethodInvoker.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/MethodInvoker.CoreCLR.cs index 6acf77be549c01..8468e8f9529e80 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/MethodInvoker.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/MethodInvoker.CoreCLR.cs @@ -15,13 +15,16 @@ public MethodInvoker(MethodBase method, Signature signature) _method = method; _signature = signature; -#if USE_NATIVE_INVOKE - // Always use the native invoke; useful for testing. - _strategyDetermined = true; -#elif USE_EMIT_INVOKE - // Always use emit invoke (if IsDynamicCodeCompiled == true); useful for testing. - _invoked = true; -#endif + if (LocalAppContextSwitches.ForceInterpretedInvoke && !LocalAppContextSwitches.ForceEmitInvoke) + { + // Always use the native invoke; useful for testing. + _strategyDetermined = true; + } + else if (LocalAppContextSwitches.ForceEmitInvoke && !LocalAppContextSwitches.ForceInterpretedInvoke) + { + // Always use emit invoke (if IsDynamicCodeCompiled == true); useful for testing. + _invoked = true; + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/libraries/Common/tests/System/Reflection/InvokeEmitTests.cs b/src/libraries/Common/tests/System/Reflection/InvokeEmitTests.cs new file mode 100644 index 00000000000000..c81da708294f13 --- /dev/null +++ b/src/libraries/Common/tests/System/Reflection/InvokeEmitTests.cs @@ -0,0 +1,56 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; +using Xunit; + +namespace System.Reflection.Tests +{ + public class InvokeEmitTests + { + [ConditionalFact(typeof(InvokeEmitTests), nameof(InvokeEmitTests.IsEmitInvokeSupported))] + public static void VerifyInvokeIsUsingEmit_Method() + { + MethodInfo method = typeof(TestClassThatThrows).GetMethod(nameof(TestClassThatThrows.Throw))!; + TargetInvocationException ex = Assert.Throws(() => method.Invoke(null, null)); + Exception exInner = ex.InnerException; + + Assert.Contains("Here", exInner.ToString()); + Assert.Contains("InvokeStub_TestClassThatThrows", exInner.ToString()); + Assert.DoesNotContain(InterpretedMethodName, exInner.ToString()); + } + + [ConditionalFact(typeof(InvokeEmitTests), nameof(InvokeEmitTests.IsEmitInvokeSupported))] + public static void VerifyInvokeIsUsingEmit_Constructor() + { + ConstructorInfo ctor = typeof(TestClassThatThrows).GetConstructor(Type.EmptyTypes)!; + TargetInvocationException ex = Assert.Throws(() => ctor.Invoke(null)); + Exception exInner = ex.InnerException; + + Assert.Contains("Here", exInner.ToString()); + Assert.Contains("InvokeStub_TestClassThatThrows", exInner.ToString()); + Assert.DoesNotContain(InterpretedMethodName, exInner.ToString()); + } + + private static bool IsEmitInvokeSupported() + { + // Emit is only used for Invoke when RuntimeFeature.IsDynamicCodeCompiled is true. + return RuntimeFeature.IsDynamicCodeCompiled + && !PlatformDetection.IsMonoRuntime; // Temporary until Mono is updated. + } + + private static string InterpretedMethodName => PlatformDetection.IsMonoRuntime ? + "System.Reflection.MethodInvoker.InterpretedInvoke" : + "System.RuntimeMethodHandle.InvokeMethod"; + + private class TestClassThatThrows + { + public TestClassThatThrows() + { + throw new Exception("Here"); + } + + public static void Throw() => throw new Exception("Here"); + } + } +} diff --git a/src/libraries/Common/tests/System/Reflection/InvokeInterpretedTests.cs b/src/libraries/Common/tests/System/Reflection/InvokeInterpretedTests.cs new file mode 100644 index 00000000000000..5d4347e82d8852 --- /dev/null +++ b/src/libraries/Common/tests/System/Reflection/InvokeInterpretedTests.cs @@ -0,0 +1,53 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Xunit; + +namespace System.Reflection.Tests +{ + public class InvokeInterpretedTests + { + [Fact] + public static void VerifyInvokeIsUsingEmit_Method() + { + MethodInfo method = typeof(TestClassThatThrows).GetMethod(nameof(TestClassThatThrows.Throw))!; + TargetInvocationException ex = Assert.Throws(() => method.Invoke(null, null)); + Exception exInner = ex.InnerException; + + Assert.Contains("Here", exInner.ToString()); + Assert.Contains(InterpretedMethodName(), exInner.ToString()); + Assert.DoesNotContain("InvokeStub_TestClassThatThrows", exInner.ToString()); + + string InterpretedMethodName() => PlatformDetection.IsMonoRuntime ? + "System.Reflection.MethodInvoker.InterpretedInvoke" : + "System.RuntimeMethodHandle.InvokeMethod"; + } + + [Fact] + public static void VerifyInvokeIsUsingEmit_Constructor() + { + ConstructorInfo ctor = typeof(TestClassThatThrows).GetConstructor(Type.EmptyTypes)!; + TargetInvocationException ex = Assert.Throws(() => ctor.Invoke(null)); + Exception exInner = ex.InnerException; + + Assert.Contains("Here", exInner.ToString()); + Assert.Contains(InterpretedMethodName(), exInner.ToString()); + Assert.DoesNotContain("InvokeStub_TestClassThatThrows", exInner.ToString()); + + string InterpretedMethodName() => PlatformDetection.IsMonoRuntime ? + "System.Reflection.ConstructorInvoker.InterpretedInvoke" : + "System.RuntimeMethodHandle.InvokeMethod"; + } + + private class TestClassThatThrows + { + public TestClassThatThrows() + { + throw new Exception("Here"); + } + + public static void Throw() => throw new Exception("Here"); + } + } +} + diff --git a/src/libraries/System.Private.CoreLib/src/System/LocalAppContextSwitches.cs b/src/libraries/System.Private.CoreLib/src/System/LocalAppContextSwitches.cs index 37e2265f5f8f93..044e1fc59ae40b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/LocalAppContextSwitches.cs +++ b/src/libraries/System.Private.CoreLib/src/System/LocalAppContextSwitches.cs @@ -41,6 +41,20 @@ public static bool PreserveEventListnerObjectIdentity get => GetCachedSwitchValue("Switch.System.Diagnostics.EventSource.PreserveEventListnerObjectIdentity", ref s_preserveEventListnerObjectIdentity); } + private static int s_forceEmitInvoke; + public static bool ForceEmitInvoke + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => GetCachedSwitchValue("Switch.System.Reflection.ForceEmitInvoke", ref s_forceEmitInvoke); + } + + private static int s_forceInterpretedInvoke; + public static bool ForceInterpretedInvoke + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => GetCachedSwitchValue("Switch.System.Reflection.ForceInterpretedInvoke", ref s_forceInterpretedInvoke); + } + private static int s_serializationGuard; public static bool SerializationGuard { diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInvoker.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInvoker.cs index c79036380b8e78..d5f173eac18708 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInvoker.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/ConstructorInvoker.cs @@ -20,12 +20,17 @@ public ConstructorInvoker(RuntimeConstructorInfo constructorInfo) { _method = constructorInfo; -#if USE_NATIVE_INVOKE - // Always use the native invoke; useful for testing. - _strategyDetermined = true; -#elif USE_EMIT_INVOKE - // Always use emit invoke (if IsDynamicCodeCompiled == true); useful for testing. - _invoked = true; +#if !MONO // Temporary until Mono is updated. + if (LocalAppContextSwitches.ForceInterpretedInvoke && !LocalAppContextSwitches.ForceEmitInvoke) + { + // Always use the native invoke; useful for testing. + _strategyDetermined = true; + } + else if (LocalAppContextSwitches.ForceEmitInvoke && !LocalAppContextSwitches.ForceInterpretedInvoke) + { + // Always use emit invoke (if IsDynamicCodeCompiled == true); useful for testing. + _invoked = true; + } #endif } diff --git a/src/libraries/System.Reflection/System.Reflection.sln b/src/libraries/System.Reflection/System.Reflection.sln index 2d594baedc69d7..86fae905a07f36 100644 --- a/src/libraries/System.Reflection/System.Reflection.sln +++ b/src/libraries/System.Reflection/System.Reflection.sln @@ -37,6 +37,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ForwardedTypesAssembly", "t EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Reflection.Tests", "tests\System.Reflection.Tests.csproj", "{F2E5F428-418B-41B9-BF14-36EB67486A71}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Reflection.InvokeInterpreted.Tests", "tests\InvokeInterpreted\System.Reflection.InvokeInterpreted.Tests.csproj", "{CB2060E9-094A-4E8A-851B-84EF56491F5D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Reflection.InvokeEmit.Tests", "tests\InvokeEmit\System.Reflection.InvokeEmit.Tests.csproj", "{EE38FA51-BA38-4FC9-9655-C8EBB768969D}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestAssembly", "tests\TestAssembly\TestAssembly.csproj", "{E6F16442-FB0F-4666-8309-F8B1EBA5B860}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Reflection.TestExe", "tests\TestExe\System.Reflection.TestExe.csproj", "{42BEE4BD-C378-41C5-A94F-4EA01F8D6E88}" @@ -520,6 +524,42 @@ Global {95C7E01D-B35D-431C-A50E-D52956ABBFB3}.Checked|x64.Build.0 = Debug|Any CPU {95C7E01D-B35D-431C-A50E-D52956ABBFB3}.Checked|x86.ActiveCfg = Debug|Any CPU {95C7E01D-B35D-431C-A50E-D52956ABBFB3}.Checked|x86.Build.0 = Debug|Any CPU + {CB2060E9-094A-4E8A-851B-84EF56491F5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CB2060E9-094A-4E8A-851B-84EF56491F5D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CB2060E9-094A-4E8A-851B-84EF56491F5D}.Debug|x64.ActiveCfg = Debug|Any CPU + {CB2060E9-094A-4E8A-851B-84EF56491F5D}.Debug|x64.Build.0 = Debug|Any CPU + {CB2060E9-094A-4E8A-851B-84EF56491F5D}.Debug|x86.ActiveCfg = Debug|Any CPU + {CB2060E9-094A-4E8A-851B-84EF56491F5D}.Debug|x86.Build.0 = Debug|Any CPU + {CB2060E9-094A-4E8A-851B-84EF56491F5D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CB2060E9-094A-4E8A-851B-84EF56491F5D}.Release|Any CPU.Build.0 = Release|Any CPU + {CB2060E9-094A-4E8A-851B-84EF56491F5D}.Release|x64.ActiveCfg = Release|Any CPU + {CB2060E9-094A-4E8A-851B-84EF56491F5D}.Release|x64.Build.0 = Release|Any CPU + {CB2060E9-094A-4E8A-851B-84EF56491F5D}.Release|x86.ActiveCfg = Release|Any CPU + {CB2060E9-094A-4E8A-851B-84EF56491F5D}.Release|x86.Build.0 = Release|Any CPU + {CB2060E9-094A-4E8A-851B-84EF56491F5D}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {CB2060E9-094A-4E8A-851B-84EF56491F5D}.Checked|Any CPU.Build.0 = Debug|Any CPU + {CB2060E9-094A-4E8A-851B-84EF56491F5D}.Checked|x64.ActiveCfg = Debug|Any CPU + {CB2060E9-094A-4E8A-851B-84EF56491F5D}.Checked|x64.Build.0 = Debug|Any CPU + {CB2060E9-094A-4E8A-851B-84EF56491F5D}.Checked|x86.ActiveCfg = Debug|Any CPU + {CB2060E9-094A-4E8A-851B-84EF56491F5D}.Checked|x86.Build.0 = Debug|Any CPU + {EE38FA51-BA38-4FC9-9655-C8EBB768969D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EE38FA51-BA38-4FC9-9655-C8EBB768969D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EE38FA51-BA38-4FC9-9655-C8EBB768969D}.Debug|x64.ActiveCfg = Debug|Any CPU + {EE38FA51-BA38-4FC9-9655-C8EBB768969D}.Debug|x64.Build.0 = Debug|Any CPU + {EE38FA51-BA38-4FC9-9655-C8EBB768969D}.Debug|x86.ActiveCfg = Debug|Any CPU + {EE38FA51-BA38-4FC9-9655-C8EBB768969D}.Debug|x86.Build.0 = Debug|Any CPU + {EE38FA51-BA38-4FC9-9655-C8EBB768969D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EE38FA51-BA38-4FC9-9655-C8EBB768969D}.Release|Any CPU.Build.0 = Release|Any CPU + {EE38FA51-BA38-4FC9-9655-C8EBB768969D}.Release|x64.ActiveCfg = Release|Any CPU + {EE38FA51-BA38-4FC9-9655-C8EBB768969D}.Release|x64.Build.0 = Release|Any CPU + {EE38FA51-BA38-4FC9-9655-C8EBB768969D}.Release|x86.ActiveCfg = Release|Any CPU + {EE38FA51-BA38-4FC9-9655-C8EBB768969D}.Release|x86.Build.0 = Release|Any CPU + {EE38FA51-BA38-4FC9-9655-C8EBB768969D}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {EE38FA51-BA38-4FC9-9655-C8EBB768969D}.Checked|Any CPU.Build.0 = Debug|Any CPU + {EE38FA51-BA38-4FC9-9655-C8EBB768969D}.Checked|x64.ActiveCfg = Debug|Any CPU + {EE38FA51-BA38-4FC9-9655-C8EBB768969D}.Checked|x64.Build.0 = Debug|Any CPU + {EE38FA51-BA38-4FC9-9655-C8EBB768969D}.Checked|x86.ActiveCfg = Debug|Any CPU + {EE38FA51-BA38-4FC9-9655-C8EBB768969D}.Checked|x86.Build.0 = Debug|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -545,6 +585,8 @@ Global {E6F16442-FB0F-4666-8309-F8B1EBA5B860} = {64590D3A-D464-4764-ABE3-EF62722D8FA7} {42BEE4BD-C378-41C5-A94F-4EA01F8D6E88} = {64590D3A-D464-4764-ABE3-EF62722D8FA7} {C4AF78A8-28D7-434B-8F85-0B0E902AF8E0} = {64590D3A-D464-4764-ABE3-EF62722D8FA7} + {CB2060E9-094A-4E8A-851B-84EF56491F5D} = {64590D3A-D464-4764-ABE3-EF62722D8FA7} + {EE38FA51-BA38-4FC9-9655-C8EBB768969D} = {64590D3A-D464-4764-ABE3-EF62722D8FA7} {1F5C28EE-FA69-4A3A-934C-88FEBBDE2489} = {5BEA3DA5-3D9A-4642-B049-C04392B78D4B} {A2B3A339-4792-4561-A973-11FE5EEEB54A} = {5BEA3DA5-3D9A-4642-B049-C04392B78D4B} {7625A3EB-C76C-41FE-85DC-C8B792062F9C} = {5BEA3DA5-3D9A-4642-B049-C04392B78D4B} diff --git a/src/libraries/System.Reflection/tests/InvokeEmit/System.Reflection.InvokeEmit.Tests.csproj b/src/libraries/System.Reflection/tests/InvokeEmit/System.Reflection.InvokeEmit.Tests.csproj new file mode 100644 index 00000000000000..7b1e61038ccb5d --- /dev/null +++ b/src/libraries/System.Reflection/tests/InvokeEmit/System.Reflection.InvokeEmit.Tests.csproj @@ -0,0 +1,22 @@ + + + true + true + true + $(NetCoreAppCurrent) + + + + + + + + + + + + + + <__ExcludeFromBundle Include="TestAssembly.dll" /> + + diff --git a/src/libraries/System.Reflection/tests/InvokeEmit/runtimeconfig.template.json b/src/libraries/System.Reflection/tests/InvokeEmit/runtimeconfig.template.json new file mode 100644 index 00000000000000..4c7cde83ee5855 --- /dev/null +++ b/src/libraries/System.Reflection/tests/InvokeEmit/runtimeconfig.template.json @@ -0,0 +1,5 @@ +{ + "configProperties": { + "Switch.System.Reflection.ForceEmitInvoke": true + } +} diff --git a/src/libraries/System.Reflection/tests/InvokeInterpreted/System.Reflection.InvokeInterpreted.Tests.csproj b/src/libraries/System.Reflection/tests/InvokeInterpreted/System.Reflection.InvokeInterpreted.Tests.csproj new file mode 100644 index 00000000000000..64dc87d71c0864 --- /dev/null +++ b/src/libraries/System.Reflection/tests/InvokeInterpreted/System.Reflection.InvokeInterpreted.Tests.csproj @@ -0,0 +1,22 @@ + + + true + true + true + $(NetCoreAppCurrent) + + + + + + + + + + + + + + <__ExcludeFromBundle Include="TestAssembly.dll" /> + + diff --git a/src/libraries/System.Reflection/tests/InvokeInterpreted/runtimeconfig.template.json b/src/libraries/System.Reflection/tests/InvokeInterpreted/runtimeconfig.template.json new file mode 100644 index 00000000000000..0b155f90b7ab41 --- /dev/null +++ b/src/libraries/System.Reflection/tests/InvokeInterpreted/runtimeconfig.template.json @@ -0,0 +1,5 @@ +{ + "configProperties": { + "Switch.System.Reflection.ForceInterpretedInvoke": true + } +} diff --git a/src/libraries/System.Runtime/System.Runtime.sln b/src/libraries/System.Runtime/System.Runtime.sln index fd4222160d00d5..ac278789e353e4 100644 --- a/src/libraries/System.Runtime/System.Runtime.sln +++ b/src/libraries/System.Runtime/System.Runtime.sln @@ -21,6 +21,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibraryImportGenerator", ". EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Interop.SourceGeneration", "..\System.Runtime.InteropServices\gen\Microsoft.Interop.SourceGeneration\Microsoft.Interop.SourceGeneration.csproj", "{A7B7DE04-7261-4D4C-AA78-9F2D9B5A1C37}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.ReflectionInvokeInterpreted.Tests", "tests\System\Reflection\InvokeInterpreted\System.Runtime.ReflectionInvokeInterpreted.Tests.csproj", "{47E26787-7C27-4572-AD8B-868DE44E2C48}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime.ReflectionInvokeEmit.Tests", "tests\System\Reflection\InvokeEmit\System.Runtime.ReflectionInvokeEmit.Tests.csproj", "{C3F25EEF-04B4-407A-960B-0C1CE9C04430}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime", "ref\System.Runtime.csproj", "{F39E2C7E-5FE1-460C-AC2C-7E2B50955F2C}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Runtime", "src\System.Runtime.csproj", "{A83A8520-F5E2-49B4-83BC-0F82A412951D}" @@ -324,6 +328,24 @@ Global {3B79DD71-8C2F-41BC-A1A7-86A490D6C726}.Checked|x64.Build.0 = Debug|Any CPU {3B79DD71-8C2F-41BC-A1A7-86A490D6C726}.Checked|x86.ActiveCfg = Debug|Any CPU {3B79DD71-8C2F-41BC-A1A7-86A490D6C726}.Checked|x86.Build.0 = Debug|Any CPU + {47E26787-7C27-4572-AD8B-868DE44E2C48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {47E26787-7C27-4572-AD8B-868DE44E2C48}.Debug|Any CPU.Build.0 = Debug|Any CPU + {47E26787-7C27-4572-AD8B-868DE44E2C48}.Debug|x64.ActiveCfg = Debug|Any CPU + {47E26787-7C27-4572-AD8B-868DE44E2C48}.Debug|x64.Build.0 = Debug|Any CPU + {47E26787-7C27-4572-AD8B-868DE44E2C48}.Debug|x86.ActiveCfg = Debug|Any CPU + {47E26787-7C27-4572-AD8B-868DE44E2C48}.Debug|x86.Build.0 = Debug|Any CPU + {47E26787-7C27-4572-AD8B-868DE44E2C48}.Release|Any CPU.ActiveCfg = Release|Any CPU + {47E26787-7C27-4572-AD8B-868DE44E2C48}.Release|Any CPU.Build.0 = Release|Any CPU + {47E26787-7C27-4572-AD8B-868DE44E2C48}.Release|x64.ActiveCfg = Release|Any CPU + {47E26787-7C27-4572-AD8B-868DE44E2C48}.Release|x64.Build.0 = Release|Any CPU + {47E26787-7C27-4572-AD8B-868DE44E2C48}.Release|x86.ActiveCfg = Release|Any CPU + {47E26787-7C27-4572-AD8B-868DE44E2C48}.Release|x86.Build.0 = Release|Any CPU + {47E26787-7C27-4572-AD8B-868DE44E2C48}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {47E26787-7C27-4572-AD8B-868DE44E2C48}.Checked|Any CPU.Build.0 = Debug|Any CPU + {47E26787-7C27-4572-AD8B-868DE44E2C48}.Checked|x64.ActiveCfg = Debug|Any CPU + {47E26787-7C27-4572-AD8B-868DE44E2C48}.Checked|x64.Build.0 = Debug|Any CPU + {47E26787-7C27-4572-AD8B-868DE44E2C48}.Checked|x86.ActiveCfg = Debug|Any CPU + {47E26787-7C27-4572-AD8B-868DE44E2C48}.Checked|x86.Build.0 = Debug|Any CPU {4EE36055-AD7C-4779-B3F6-08687960DCC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4EE36055-AD7C-4779-B3F6-08687960DCC3}.Debug|Any CPU.Build.0 = Debug|Any CPU {4EE36055-AD7C-4779-B3F6-08687960DCC3}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -360,6 +382,24 @@ Global {C230AC88-A377-4BEB-824F-AB174C14DC86}.Checked|x64.Build.0 = Debug|Any CPU {C230AC88-A377-4BEB-824F-AB174C14DC86}.Checked|x86.ActiveCfg = Debug|Any CPU {C230AC88-A377-4BEB-824F-AB174C14DC86}.Checked|x86.Build.0 = Debug|Any CPU + {C3F25EEF-04B4-407A-960B-0C1CE9C04430}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C3F25EEF-04B4-407A-960B-0C1CE9C04430}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C3F25EEF-04B4-407A-960B-0C1CE9C04430}.Debug|x64.ActiveCfg = Debug|Any CPU + {C3F25EEF-04B4-407A-960B-0C1CE9C04430}.Debug|x64.Build.0 = Debug|Any CPU + {C3F25EEF-04B4-407A-960B-0C1CE9C04430}.Debug|x86.ActiveCfg = Debug|Any CPU + {C3F25EEF-04B4-407A-960B-0C1CE9C04430}.Debug|x86.Build.0 = Debug|Any CPU + {C3F25EEF-04B4-407A-960B-0C1CE9C04430}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C3F25EEF-04B4-407A-960B-0C1CE9C04430}.Release|Any CPU.Build.0 = Release|Any CPU + {C3F25EEF-04B4-407A-960B-0C1CE9C04430}.Release|x64.ActiveCfg = Release|Any CPU + {C3F25EEF-04B4-407A-960B-0C1CE9C04430}.Release|x64.Build.0 = Release|Any CPU + {C3F25EEF-04B4-407A-960B-0C1CE9C04430}.Release|x86.ActiveCfg = Release|Any CPU + {C3F25EEF-04B4-407A-960B-0C1CE9C04430}.Release|x86.Build.0 = Release|Any CPU + {C3F25EEF-04B4-407A-960B-0C1CE9C04430}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {C3F25EEF-04B4-407A-960B-0C1CE9C04430}.Checked|Any CPU.Build.0 = Debug|Any CPU + {C3F25EEF-04B4-407A-960B-0C1CE9C04430}.Checked|x64.ActiveCfg = Debug|Any CPU + {C3F25EEF-04B4-407A-960B-0C1CE9C04430}.Checked|x64.Build.0 = Debug|Any CPU + {C3F25EEF-04B4-407A-960B-0C1CE9C04430}.Checked|x86.ActiveCfg = Debug|Any CPU + {C3F25EEF-04B4-407A-960B-0C1CE9C04430}.Checked|x86.Build.0 = Debug|Any CPU {1BCCD2F5-A561-4641-8A0B-51F3EDCA35DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1BCCD2F5-A561-4641-8A0B-51F3EDCA35DC}.Debug|Any CPU.Build.0 = Debug|Any CPU {1BCCD2F5-A561-4641-8A0B-51F3EDCA35DC}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -561,6 +601,8 @@ Global {1BCCD2F5-A561-4641-8A0B-51F3EDCA35DC} = {FD72C125-C10D-457B-8AFC-6B4E5237AF6A} {0F83B07B-2E3F-4708-BE6D-7A8DA8168803} = {FD72C125-C10D-457B-8AFC-6B4E5237AF6A} {833C1D45-9BBB-4A92-93B7-4EFFD9E945AD} = {FD72C125-C10D-457B-8AFC-6B4E5237AF6A} + {47E26787-7C27-4572-AD8B-868DE44E2C48} = {FD72C125-C10D-457B-8AFC-6B4E5237AF6A} + {C3F25EEF-04B4-407A-960B-0C1CE9C04430} = {FD72C125-C10D-457B-8AFC-6B4E5237AF6A} {62C2AC8A-7410-4E06-B94E-43BF2DCFBDE9} = {5B2B5E7E-A2FB-4095-9E79-404BF53E0133} {9C41B325-1225-43CA-9436-549AFF6D90A1} = {5B2B5E7E-A2FB-4095-9E79-404BF53E0133} {F39E2C7E-5FE1-460C-AC2C-7E2B50955F2C} = {5B2B5E7E-A2FB-4095-9E79-404BF53E0133} diff --git a/src/libraries/System.Runtime/tests/System/Reflection/InvokeEmit/System.Runtime.ReflectionInvokeEmit.Tests.csproj b/src/libraries/System.Runtime/tests/System/Reflection/InvokeEmit/System.Runtime.ReflectionInvokeEmit.Tests.csproj new file mode 100644 index 00000000000000..80685872245900 --- /dev/null +++ b/src/libraries/System.Runtime/tests/System/Reflection/InvokeEmit/System.Runtime.ReflectionInvokeEmit.Tests.csproj @@ -0,0 +1,18 @@ + + + true + true + true + $(NetCoreAppCurrent) + + + + + + + + + + + + diff --git a/src/libraries/System.Runtime/tests/System/Reflection/InvokeEmit/runtimeconfig.template.json b/src/libraries/System.Runtime/tests/System/Reflection/InvokeEmit/runtimeconfig.template.json new file mode 100644 index 00000000000000..4c7cde83ee5855 --- /dev/null +++ b/src/libraries/System.Runtime/tests/System/Reflection/InvokeEmit/runtimeconfig.template.json @@ -0,0 +1,5 @@ +{ + "configProperties": { + "Switch.System.Reflection.ForceEmitInvoke": true + } +} diff --git a/src/libraries/System.Runtime/tests/System/Reflection/InvokeInterpreted/System.Runtime.ReflectionInvokeInterpreted.Tests.csproj b/src/libraries/System.Runtime/tests/System/Reflection/InvokeInterpreted/System.Runtime.ReflectionInvokeInterpreted.Tests.csproj new file mode 100644 index 00000000000000..3d7bd524b35010 --- /dev/null +++ b/src/libraries/System.Runtime/tests/System/Reflection/InvokeInterpreted/System.Runtime.ReflectionInvokeInterpreted.Tests.csproj @@ -0,0 +1,18 @@ + + + true + true + true + $(NetCoreAppCurrent) + + + + + + + + + + + + diff --git a/src/libraries/System.Runtime/tests/System/Reflection/InvokeInterpreted/runtimeconfig.template.json b/src/libraries/System.Runtime/tests/System/Reflection/InvokeInterpreted/runtimeconfig.template.json new file mode 100644 index 00000000000000..0b155f90b7ab41 --- /dev/null +++ b/src/libraries/System.Runtime/tests/System/Reflection/InvokeInterpreted/runtimeconfig.template.json @@ -0,0 +1,5 @@ +{ + "configProperties": { + "Switch.System.Reflection.ForceInterpretedInvoke": true + } +} diff --git a/src/libraries/System.Runtime/tests/System/Reflection/PointerTests.cs b/src/libraries/System.Runtime/tests/System/Reflection/PointerTests.cs index f89f19ec5d19ef..d99c99872e5aec 100644 --- a/src/libraries/System.Runtime/tests/System/Reflection/PointerTests.cs +++ b/src/libraries/System.Runtime/tests/System/Reflection/PointerTests.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; -using System.Runtime.Serialization.Formatters.Tests; using Xunit; namespace System.Reflection.Tests From 1adda4ec26c2a55ca00a015bb5ab679e7a490f31 Mon Sep 17 00:00:00 2001 From: Koundinya Veluri Date: Thu, 9 Jun 2022 14:20:22 -0700 Subject: [PATCH 017/337] Modify thread pool thread counting to be a bit more defensive (#70478) * Modify thread pool thread counting to be a bit more defensive - An unexpected underflow in one or more thread counts can lead to a large number of threads to be created continually - Prevented underflows in changes to thread counts, such that following an unexpected underflow, subsequent paired increments and decrements would avoid repeating the underflow - Verified by creating an unexpected underflow in the debugger --- .../PortableThreadPool.ThreadCounts.cs | 51 ++++++++----------- .../PortableThreadPool.WorkerThread.cs | 30 ++++++++--- 2 files changed, 43 insertions(+), 38 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.ThreadCounts.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.ThreadCounts.cs index 3242f165aff9a7..26b6ab0cf0ac48 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.ThreadCounts.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.ThreadCounts.cs @@ -31,61 +31,52 @@ private void SetInt16Value(short value, byte shift) => /// public short NumProcessingWork { - get => GetInt16Value(NumProcessingWorkShift); + get + { + short value = GetInt16Value(NumProcessingWorkShift); + Debug.Assert(value >= 0); + return value; + } set { Debug.Assert(value >= 0); - SetInt16Value(value, NumProcessingWorkShift); + SetInt16Value(Math.Max((short)0, value), NumProcessingWorkShift); } } - public void SubtractNumProcessingWork(short value) - { - Debug.Assert(value >= 0); - Debug.Assert(value <= NumProcessingWork); - - _data -= (ulong)(ushort)value << NumProcessingWorkShift; - } - - public void InterlockedDecrementNumProcessingWork() - { - Debug.Assert(NumProcessingWorkShift == 0); - - ThreadCounts counts = new ThreadCounts(Interlocked.Decrement(ref _data)); - Debug.Assert(counts.NumProcessingWork >= 0); - } - /// /// Number of thread pool threads that currently exist. /// public short NumExistingThreads { - get => GetInt16Value(NumExistingThreadsShift); + get + { + short value = GetInt16Value(NumExistingThreadsShift); + Debug.Assert(value >= 0); + return value; + } set { Debug.Assert(value >= 0); - SetInt16Value(value, NumExistingThreadsShift); + SetInt16Value(Math.Max((short)0, value), NumExistingThreadsShift); } } - public void SubtractNumExistingThreads(short value) - { - Debug.Assert(value >= 0); - Debug.Assert(value <= NumExistingThreads); - - _data -= (ulong)(ushort)value << NumExistingThreadsShift; - } - /// /// Max possible thread pool threads we want to have. /// public short NumThreadsGoal { - get => GetInt16Value(NumThreadsGoalShift); + get + { + short value = GetInt16Value(NumThreadsGoalShift); + Debug.Assert(value > 0); + return value; + } set { Debug.Assert(value > 0); - SetInt16Value(value, NumThreadsGoalShift); + SetInt16Value(Math.Max((short)1, value), NumThreadsGoalShift); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.WorkerThread.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.WorkerThread.cs index 7a79c9980447c8..3d2dee0e495fa5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.WorkerThread.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.WorkerThread.cs @@ -128,16 +128,14 @@ private static void WorkerThreadStart() // Since this thread is currently registered as an existing thread, if more work comes in meanwhile, // this thread would be expected to satisfy the new work. Ensure that NumExistingThreads is not // decreased below NumProcessingWork, as that would be indicative of such a case. - short numExistingThreads = counts.NumExistingThreads; - if (numExistingThreads <= counts.NumProcessingWork) + if (counts.NumExistingThreads <= counts.NumProcessingWork) { // In this case, enough work came in that this thread should not time out and should go back to work. break; } ThreadCounts newCounts = counts; - newCounts.SubtractNumExistingThreads(1); - short newNumExistingThreads = (short)(numExistingThreads - 1); + short newNumExistingThreads = --newCounts.NumExistingThreads; short newNumThreadsGoal = Math.Max( threadPoolInstance.MinThreadsGoal, @@ -173,7 +171,23 @@ private static void WorkerThreadStart() /// private static void RemoveWorkingWorker(PortableThreadPool threadPoolInstance) { - threadPoolInstance._separated.counts.InterlockedDecrementNumProcessingWork(); + // A compare-exchange loop is used instead of Interlocked.Decrement or Interlocked.Add to defensively prevent + // NumProcessingWork from underflowing. See the setter for NumProcessingWork. + ThreadCounts counts = threadPoolInstance._separated.counts; + while (true) + { + ThreadCounts newCounts = counts; + newCounts.NumProcessingWork--; + + ThreadCounts countsBeforeUpdate = + threadPoolInstance._separated.counts.InterlockedCompareExchange(newCounts, counts); + if (countsBeforeUpdate == counts) + { + break; + } + + counts = countsBeforeUpdate; + } // It's possible that we decided we had thread requests just before a request came in, // but reduced the worker count *after* the request came in. In this case, we might @@ -235,8 +249,8 @@ internal static void MaybeAddWorkingWorker(PortableThreadPool threadPoolInstance while (true) { ThreadCounts newCounts = counts; - newCounts.SubtractNumProcessingWork((short)toCreate); - newCounts.SubtractNumExistingThreads((short)toCreate); + newCounts.NumProcessingWork -= (short)toCreate; + newCounts.NumExistingThreads -= (short)toCreate; ThreadCounts oldCounts = threadPoolInstance._separated.counts.InterlockedCompareExchange(newCounts, counts); if (oldCounts == counts) @@ -273,7 +287,7 @@ internal static bool ShouldStopProcessingWorkNow(PortableThreadPool threadPoolIn } ThreadCounts newCounts = counts; - newCounts.SubtractNumProcessingWork(1); + newCounts.NumProcessingWork--; ThreadCounts oldCounts = threadPoolInstance._separated.counts.InterlockedCompareExchange(newCounts, counts); From 1bebb1479baf2de0ad41a9b186bb23bd3173dd86 Mon Sep 17 00:00:00 2001 From: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> Date: Fri, 10 Jun 2022 00:21:38 +0300 Subject: [PATCH 018/337] Set `UnusedValue` correctly for the operands of `ARR_ADDR`/`BOX` (#70498) * Add a test * Fix the issue --- src/coreclr/jit/rationalize.cpp | 15 +++----- .../JitBlue/Runtime_70466/Runtime_70466.cs | 38 +++++++++++++++++++ .../Runtime_70466/Runtime_70466.csproj | 9 +++++ 3 files changed, 52 insertions(+), 10 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_70466/Runtime_70466.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_70466/Runtime_70466.csproj diff --git a/src/coreclr/jit/rationalize.cpp b/src/coreclr/jit/rationalize.cpp index e6b7e1a4d9234d..faa90cc61ad8ba 100644 --- a/src/coreclr/jit/rationalize.cpp +++ b/src/coreclr/jit/rationalize.cpp @@ -556,13 +556,6 @@ Compiler::fgWalkResult Rationalizer::RewriteNode(GenTree** useEdge, Compiler::Ge RewriteAssignment(use); break; - case GT_BOX: - case GT_ARR_ADDR: - // BOX/ARR_ADDR at this level are just NOPs. - use.ReplaceWith(node->gtGetOp1()); - BlockRange().Remove(node); - break; - case GT_ADDR: RewriteAddress(use); break; @@ -594,9 +587,11 @@ Compiler::fgWalkResult Rationalizer::RewriteNode(GenTree** useEdge, Compiler::Ge break; case GT_NOP: - // fgMorph sometimes inserts NOP nodes between defs and uses - // supposedly 'to prevent constant folding'. In this case, remove the - // NOP. + case GT_BOX: + case GT_ARR_ADDR: + // "optNarrowTree" sometimes inserts NOP nodes between defs and uses. + // In this case, remove the NOP. BOX/ARR_ADDR are such "passthrough" + // nodes by design, and at this point we no longer need them. if (node->gtGetOp1() != nullptr) { use.ReplaceWith(node->gtGetOp1()); diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_70466/Runtime_70466.cs b/src/tests/JIT/Regression/JitBlue/Runtime_70466/Runtime_70466.cs new file mode 100644 index 00000000000000..d4a5b9d3014922 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_70466/Runtime_70466.cs @@ -0,0 +1,38 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; + +public class Runtime_70466 +{ + public static int Main() + { + Problem(1, 0); + return 100; + } + + // This method is carefully crafted such that we end up with an unused ARR_ADDR node by rationalization + // time, of which the child operand will need to be explicitly marked "unused value" for LIR purposes. + // + [MethodImpl(MethodImplOptions.NoInlining)] + private static void Problem(byte b, int idx) + { + var a = new byte[] { b }; + var a1 = new byte[] { b, b }; + var a2 = new byte[] { b, b, b }; + + if (idx == 0) + { + if (a[idx] == 1) + { + Use(1); + } + JitUse(a1[idx] + a2[idx]); + } + } + + public static void Use(T arg) { } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void JitUse(T arg) { } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_70466/Runtime_70466.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_70466/Runtime_70466.csproj new file mode 100644 index 00000000000000..f492aeac9d056b --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_70466/Runtime_70466.csproj @@ -0,0 +1,9 @@ + + + Exe + True + + + + + \ No newline at end of file From a0662e38ff5e0682a8c315bc465591658c3cd9fe Mon Sep 17 00:00:00 2001 From: Ivan Povazan <55002338+ivanpovazan@users.noreply.github.com> Date: Fri, 10 Jun 2022 00:09:41 +0200 Subject: [PATCH 019/337] Update disabled tests details with newly created issues (#70493) --- src/tests/issues.targets | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tests/issues.targets b/src/tests/issues.targets index b38cf417e9db3e..19201279814a68 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -2822,22 +2822,22 @@ expected failure: unsupported type with ByRefLike parameters currently fails at AOT compile time, not runtime - https://github.com/dotnet/runtime/issues/57361 + https://github.com/dotnet/runtime/issues/70490 https://github.com/dotnet/runtime/issues/57362 - https://github.com/dotnet/runtime/issues/57361 + https://github.com/dotnet/runtime/issues/70492 - https://github.com/dotnet/runtime/issues/57361 + https://github.com/dotnet/runtime/issues/70492 - https://github.com/dotnet/runtime/issues/57361 + https://github.com/dotnet/runtime/issues/70492 - https://github.com/dotnet/runtime/issues/57361 + https://github.com/dotnet/runtime/issues/70492 https://github.com/dotnet/runtime/issues/57369 From 61ca87cb48435239d662b75636629c432e5fc8f8 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Thu, 9 Jun 2022 15:25:37 -0700 Subject: [PATCH 020/337] Update analyzer version and fix new findings (#70157) --- eng/CodeAnalysis.src.globalconfig | 3 +++ eng/CodeAnalysis.test.globalconfig | 3 +++ .../Microsoft.NET.HostModel/ComHost/ClsidMap.cs | 4 ++-- .../src/Microsoft/Win32/SystemEvents.cs | 8 ++------ .../Microsoft.XmlSerializer.Generator/src/Sgen.cs | 4 +--- .../AttributedModel/AttributedExportDefinition.cs | 4 ++-- .../System/Configuration/ConfigurationElement.cs | 4 ++-- .../System.Data.Common/src/System/Data/XMLSchema.cs | 8 ++++---- .../System/Data/Common/DbConnectionOptions.cs | 9 ++++----- .../AccountManagement/AD/ADStoreCtx_Query.cs | 7 +++---- .../src/System/IO/Packaging/Package.cs | 8 ++++---- .../src/System/IO/Packaging/ZipPackage.cs | 13 ++++++------- .../src/System/Xml/Dom/XmlNodeReader.cs | 2 +- .../src/Internal/SrgsCompiler/BackEnd.cs | 2 +- 14 files changed, 38 insertions(+), 41 deletions(-) diff --git a/eng/CodeAnalysis.src.globalconfig b/eng/CodeAnalysis.src.globalconfig index f246a7b6af4dbf..8104f96e9b3a03 100644 --- a/eng/CodeAnalysis.src.globalconfig +++ b/eng/CodeAnalysis.src.globalconfig @@ -411,6 +411,9 @@ dotnet_diagnostic.CA1852.severity = warning # CA1853: Unnecessary call to 'Dictionary.ContainsKey(key)' dotnet_diagnostic.CA1853.severity = warning +# CA1854: Prefer the 'IDictionary.TryGetValue(TKey, out TValue)' method +dotnet_diagnostic.CA1854.severity = warning + # CA2000: Dispose objects before losing scope dotnet_diagnostic.CA2000.severity = none diff --git a/eng/CodeAnalysis.test.globalconfig b/eng/CodeAnalysis.test.globalconfig index 97bf6113e88e76..59fc4e0022deba 100644 --- a/eng/CodeAnalysis.test.globalconfig +++ b/eng/CodeAnalysis.test.globalconfig @@ -408,6 +408,9 @@ dotnet_diagnostic.CA1852.severity = none # CA1853: Unnecessary call to 'Dictionary.ContainsKey(key)' dotnet_diagnostic.CA1853.severity = none +# CA1854: Prefer the 'IDictionary.TryGetValue(TKey, out TValue)' method +dotnet_diagnostic.CA1854.severity = none + # CA2000: Dispose objects before losing scope dotnet_diagnostic.CA2000.severity = none diff --git a/src/installer/managed/Microsoft.NET.HostModel/ComHost/ClsidMap.cs b/src/installer/managed/Microsoft.NET.HostModel/ComHost/ClsidMap.cs index 9864f8f599f30a..a8cbb02294ea23 100644 --- a/src/installer/managed/Microsoft.NET.HostModel/ComHost/ClsidMap.cs +++ b/src/installer/managed/Microsoft.NET.HostModel/ComHost/ClsidMap.cs @@ -46,9 +46,9 @@ public static void Create(MetadataReader metadataReader, string clsidMapPath) Guid guid = GetTypeGuid(metadataReader, definition); string guidString = GetTypeGuid(metadataReader, definition).ToString("B"); - if (clsidMap.ContainsKey(guidString)) + if (clsidMap.TryGetValue(guidString, out ClsidEntry value)) { - throw new ConflictingGuidException(clsidMap[guidString].Type, GetTypeName(metadataReader, definition), guid); + throw new ConflictingGuidException(value.Type, GetTypeName(metadataReader, definition), guid); } string progId = GetProgId(metadataReader, definition); diff --git a/src/libraries/Microsoft.Win32.SystemEvents/src/Microsoft/Win32/SystemEvents.cs b/src/libraries/Microsoft.Win32.SystemEvents/src/Microsoft/Win32/SystemEvents.cs index da1131ca12dc48..3cccd9a40c19ed 100644 --- a/src/libraries/Microsoft.Win32.SystemEvents/src/Microsoft/Win32/SystemEvents.cs +++ b/src/libraries/Microsoft.Win32.SystemEvents/src/Microsoft/Win32/SystemEvents.cs @@ -1004,10 +1004,8 @@ private static void RaiseEvent(bool checkFinalization, object key, params object lock (s_eventLockObject) { - if (s_handlers != null && s_handlers.ContainsKey(key)) + if (s_handlers != null && s_handlers.TryGetValue(key, out List? invokeItems)) { - List invokeItems = s_handlers[key]; - // clone the list so we don't have this type locked and cause // a deadlock if someone tries to modify handlers during an invoke. if (invokeItems != null) @@ -1068,10 +1066,8 @@ private static void RemoveEventHandler(object key, Delegate? value) lock (s_eventLockObject) { - if (s_handlers != null && s_handlers.ContainsKey(key)) + if (s_handlers != null && s_handlers.TryGetValue(key, out List? invokeItems)) { - List invokeItems = s_handlers[key]; - invokeItems.Remove(new SystemEventInvokeInfo(value)); } } diff --git a/src/libraries/Microsoft.XmlSerializer.Generator/src/Sgen.cs b/src/libraries/Microsoft.XmlSerializer.Generator/src/Sgen.cs index bcd40f574478fb..4f4865753a1b4d 100644 --- a/src/libraries/Microsoft.XmlSerializer.Generator/src/Sgen.cs +++ b/src/libraries/Microsoft.XmlSerializer.Generator/src/Sgen.cs @@ -618,10 +618,8 @@ private static Assembly SgenAssemblyResolver(object source, ResolveEventArgs e) return null; } - if (s_referencedic.ContainsKey(assemblyname)) + if (s_referencedic.TryGetValue(assemblyname, out string reference)) { - string reference = s_referencedic[assemblyname]; - // For System.ServiceModel.Primitives, we need to load its runtime assembly rather than reference assembly if (assemblyname.Equals("System.ServiceModel.Primitives")) { diff --git a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/AttributedModel/AttributedExportDefinition.cs b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/AttributedModel/AttributedExportDefinition.cs index d5e1c3ef3b2239..b7c23cc6e85117 100644 --- a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/AttributedModel/AttributedExportDefinition.cs +++ b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/AttributedModel/AttributedExportDefinition.cs @@ -46,9 +46,9 @@ public AttributedExportDefinition(AttributedPartCreationInfo partCreationInfo, M metadata.Add(CompositionConstants.ExportTypeIdentityMetadataName, typeIdentity); var partMetadata = _partCreationInfo.GetMetadata(); - if (partMetadata != null && partMetadata.ContainsKey(CompositionConstants.PartCreationPolicyMetadataName)) + if (partMetadata != null && partMetadata.TryGetValue(CompositionConstants.PartCreationPolicyMetadataName, out object? value)) { - metadata.Add(CompositionConstants.PartCreationPolicyMetadataName, partMetadata[CompositionConstants.PartCreationPolicyMetadataName]); + metadata.Add(CompositionConstants.PartCreationPolicyMetadataName, value); } if ((_typeIdentityType != null) && (_member.MemberType != MemberTypes.Method) && _typeIdentityType.ContainsGenericParameters) diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationElement.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationElement.cs index 50f4dc7e3d1ca7..c1a2aadea4b5a5 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationElement.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationElement.cs @@ -831,8 +831,8 @@ private static void ApplyValidator(ConfigurationElement elem) { Debug.Assert(elem != null); - if ((s_perTypeValidators != null) && s_perTypeValidators.ContainsKey(elem.GetType())) - elem._elementProperty = new ConfigurationElementProperty(s_perTypeValidators[elem.GetType()]); + if ((s_perTypeValidators != null) && s_perTypeValidators.TryGetValue(elem.GetType(), out ConfigurationValidatorBase value)) + elem._elementProperty = new ConfigurationElementProperty(value); } protected void SetPropertyValue(ConfigurationProperty prop, object value, bool ignoreLocks) diff --git a/src/libraries/System.Data.Common/src/System/Data/XMLSchema.cs b/src/libraries/System.Data.Common/src/System/Data/XMLSchema.cs index 30cb3539bf8ffd..83434330b1a44e 100644 --- a/src/libraries/System.Data.Common/src/System/Data/XMLSchema.cs +++ b/src/libraries/System.Data.Common/src/System/Data/XMLSchema.cs @@ -1349,9 +1349,9 @@ internal void HandleKeyref(XmlSchemaKeyref keyref) if (FromInference && relation.Nested) { - if (_tableDictionary!.ContainsKey(relation.ParentTable)) + if (_tableDictionary!.TryGetValue(relation.ParentTable, out List? value)) { - _tableDictionary[relation.ParentTable].Add(relation.ChildTable); + value.Add(relation.ChildTable); } } @@ -1762,9 +1762,9 @@ internal DataTable InstantiateTable(XmlSchemaElement node, XmlSchemaComplexType _tableChild.DataSet!.Relations.Add(relation); if (FromInference && relation.Nested) { - if (_tableDictionary!.ContainsKey(relation.ParentTable)) + if (_tableDictionary!.TryGetValue(relation.ParentTable, out List? value)) { - _tableDictionary[relation.ParentTable].Add(relation.ChildTable); + value.Add(relation.ChildTable); } } } diff --git a/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/DbConnectionOptions.cs b/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/DbConnectionOptions.cs index e36c0d89ab2f51..3aa0aa56b7f1b8 100644 --- a/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/DbConnectionOptions.cs +++ b/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/DbConnectionOptions.cs @@ -77,14 +77,13 @@ internal bool HasBlankPassword { if (!ConvertValueToIntegratedSecurity()) { - if (_parsetable.ContainsKey(KEY.Password)) + if (_parsetable.TryGetValue(KEY.Password, out string? value)) { - return string.IsNullOrEmpty(_parsetable[KEY.Password]); + return string.IsNullOrEmpty(value); } - else - if (_parsetable.ContainsKey(SYNONYM.Pwd)) + else if (_parsetable.TryGetValue(SYNONYM.Pwd, out string? val)) { - return string.IsNullOrEmpty(_parsetable[SYNONYM.Pwd]); // MDAC 83097 + return string.IsNullOrEmpty(val); // MDAC 83097 } else { diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADStoreCtx_Query.cs b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADStoreCtx_Query.cs index 1561394861ffd1..25f3bb87f26923 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADStoreCtx_Query.cs +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADStoreCtx_Query.cs @@ -44,11 +44,10 @@ private void BuildExtensionPropertyList(Hashtable propertyList, Type p) protected void BuildPropertySet(Type p, StringCollection propertySet) { - if (TypeToLdapPropListMap[this.MappingTableIndex].ContainsKey(p)) + if (TypeToLdapPropListMap[this.MappingTableIndex].TryGetValue(p, out StringCollection value)) { - Debug.Assert(TypeToLdapPropListMap[this.MappingTableIndex].ContainsKey(p)); - string[] props = new string[TypeToLdapPropListMap[this.MappingTableIndex][p].Count]; - TypeToLdapPropListMap[this.MappingTableIndex][p].CopyTo(props, 0); + string[] props = new string[value.Count]; + value.CopyTo(props, 0); propertySet.AddRange(props); } else diff --git a/src/libraries/System.IO.Packaging/src/System/IO/Packaging/Package.cs b/src/libraries/System.IO.Packaging/src/System/IO/Packaging/Package.cs index d1d3f031a3b900..1d33e5493e81f3 100644 --- a/src/libraries/System.IO.Packaging/src/System/IO/Packaging/Package.cs +++ b/src/libraries/System.IO.Packaging/src/System/IO/Packaging/Package.cs @@ -316,12 +316,12 @@ public void DeletePart(Uri partUri) PackUriHelper.ValidatedPartUri validatedPartUri = (PackUriHelper.ValidatedPartUri)PackUriHelper.ValidatePartUri(partUri); - if (_partList.ContainsKey(validatedPartUri)) + if (_partList.TryGetValue(validatedPartUri, out PackagePart? value)) { //This will get the actual casing of the part that //is stored in the partList which is equivalent to the //partUri provided by the user - validatedPartUri = (PackUriHelper.ValidatedPartUri)_partList[validatedPartUri].Uri; + validatedPartUri = (PackUriHelper.ValidatedPartUri)value.Uri; _partList[validatedPartUri].IsDeleted = true; _partList[validatedPartUri].Close(); @@ -1125,9 +1125,9 @@ private bool DoCloseRelationshipsXml(PackagePart p) PackUriHelper.ValidatedPartUri validatePartUri = PackUriHelper.ValidatePartUri(partUri); - if (_partList.ContainsKey(validatePartUri)) + if (_partList.TryGetValue(validatePartUri, out PackagePart? value)) { - return _partList[validatePartUri]; + return value; } else { diff --git a/src/libraries/System.IO.Packaging/src/System/IO/Packaging/ZipPackage.cs b/src/libraries/System.IO.Packaging/src/System/IO/Packaging/ZipPackage.cs index d8b6a25a462b23..0427879d014994 100644 --- a/src/libraries/System.IO.Packaging/src/System/IO/Packaging/ZipPackage.cs +++ b/src/libraries/System.IO.Packaging/src/System/IO/Packaging/ZipPackage.cs @@ -606,9 +606,8 @@ internal void AddContentType(PackUriHelper.ValidatedPartUri partUri, ContentType // Need to create an override entry? if (extension.Length == 0 - || (_defaultDictionary.ContainsKey(extension) - && !(foundMatchingDefault = - _defaultDictionary[extension].AreTypeAndSubTypeEqual(contentType)))) + || (_defaultDictionary.TryGetValue(extension, out ContentType? value) + && !(foundMatchingDefault = value.AreTypeAndSubTypeEqual(contentType)))) { AddOverrideElement(partUri, contentType); } @@ -629,16 +628,16 @@ internal void AddContentType(PackUriHelper.ValidatedPartUri partUri, ContentType //partUri provided. Override takes precedence over the default entries if (_overrideDictionary != null) { - if (_overrideDictionary.ContainsKey(partUri)) - return _overrideDictionary[partUri]; + if (_overrideDictionary.TryGetValue(partUri, out ContentType? val)) + return val; } //Step 2: Check if there is a default entry corresponding to the //extension of the partUri provided. string extension = partUri.PartUriExtension; - if (_defaultDictionary.ContainsKey(extension)) - return _defaultDictionary[extension]; + if (_defaultDictionary.TryGetValue(extension, out ContentType? value)) + return value; //Step 3: If we did not find an entry in the override and the default //dictionaries, this is an error condition diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeReader.cs index 8c660bc7d0c84e..15de351a67742e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeReader.cs @@ -1027,7 +1027,7 @@ internal IDictionary GetNamespacesInScope(XmlNamespaceScope scop if (scope != XmlNamespaceScope.Local) { - if (dict.ContainsKey(string.Empty) && dict[string.Empty] == string.Empty) + if (dict.TryGetValue(string.Empty, out string? value) && value == string.Empty) { dict.Remove(string.Empty); } diff --git a/src/libraries/System.Speech/src/Internal/SrgsCompiler/BackEnd.cs b/src/libraries/System.Speech/src/Internal/SrgsCompiler/BackEnd.cs index 0f678c5c0f209c..6d0c8d94f487ce 100644 --- a/src/libraries/System.Speech/src/Internal/SrgsCompiler/BackEnd.cs +++ b/src/libraries/System.Speech/src/Internal/SrgsCompiler/BackEnd.cs @@ -342,7 +342,7 @@ internal Rule FindRule(string sRule) System.Diagnostics.Debug.Assert(dwSymbolOffset == 0 || _symbols[iWord] == sRule); - rule = dwSymbolOffset > 0 && _nameOffsetRules.ContainsKey(dwSymbolOffset) ? _nameOffsetRules[dwSymbolOffset] : null; + rule = dwSymbolOffset > 0 && _nameOffsetRules.TryGetValue(dwSymbolOffset, out Rule value) ? value : null; } } From ed1595e2b10c32ed076d345567407ba1c081e1dd Mon Sep 17 00:00:00 2001 From: Tlakaelel Axayakatl Ceja Date: Thu, 9 Jun 2022 17:07:05 -0700 Subject: [PATCH 021/337] Add basic testing infrastructure in NativeAOT (port from dotnet/linker) (#70408) Add basic testing infrastructure in NativeAOT (port from dotnet/linker) - Port the Mono.Linker.Tests* projects from dotnet/linker - Add the new projects to .editorconfig so they remain under the dotnet/linker format instead of dotnet/runtime - clr.toolstests subset now runs the Mono.Linker.Tests infrastructure - Make DisplayNameHelpers a public class so it can be used by the test infrastructure - Add a couple of simple test cases (Dataflow and Requires) along with a Repro test, just like the repro project the repro test serves prototyping purposes - Adds ProducedBy.NativeAOT to be able to represent differences between dotnet/linker and NativeAOT (either because of a bug or because NativeAOT correctly produces additional warnings) - Use MSBuild properties instead of trying to figure out with linker paths --- eng/Subsets.props | 2 + eng/pipelines/coreclr/templates/build-job.yml | 2 + .../Common/Compiler/DisplayNameHelpers.cs | 2 +- src/coreclr/tools/aot/.editorconfig | 81 ++ .../AddedPseudoAttributeAttribute.cs | 15 + .../BaseExpectedLinkedBehaviorAttribute.cs | 16 + .../Assertions/BaseInAssemblyAttribute.cs | 9 + .../BaseMemberAssertionAttribute.cs | 15 + .../Assertions/CreatedMemberAttribute.cs | 18 + .../Assertions/DependencyRecordedAttribute.cs | 20 + .../Assertions/DisplayNameAttribute.cs | 12 + .../Assertions/EnableLoggerAttribute.cs | 9 + .../Assertions/ExpectBodyModifiedAttribute.cs | 12 + ...ResolvedDocumentationSignatureAttribute.cs | 14 + ...xpectExceptionHandlersModifiedAttribute.cs | 12 + ...eneratedDocumentationSignatureAttribute.cs | 14 + .../ExpectLocalsModifiedAttribute.cs | 12 + ...ResolvedDocumentationSignatureAttribute.cs | 14 + ...resolvedDocumentationSignatureAttribute.cs | 14 + .../ExpectedInstructionSequenceAttribute.cs | 17 + ...tionSequenceOnMemberInAssemblyAttribute.cs | 35 + .../ExpectedLocalsSequenceAttribute.cs | 23 + .../Assertions/ExpectedNoWarningsAttribute.cs | 17 + .../Assertions/ExpectedWarningAttribute.cs | 30 + .../Assertions/IgnoreTestCaseAttribute.cs | 18 + ...ptAllTypesAndMembersInAssemblyAttribute.cs | 17 + .../Assertions/KeptAssemblyAttribute.cs | 21 + .../Assertions/KeptAttribute.cs | 12 + .../Assertions/KeptAttributeAttribute.cs | 24 + .../KeptAttributeInAssemblyAttribute.cs | 71 ++ ...KeptAttributeOnFixedBufferTypeAttribute.cs | 23 + .../Assertions/KeptBackingFieldAttribute.cs | 12 + .../KeptBaseOnTypeInAssemblyAttribute.cs | 37 + .../Assertions/KeptBaseTypeAttribute.cs | 25 + .../KeptDelegateCacheFieldAttribute.cs | 17 + .../Assertions/KeptEventAddMethodAttribute.cs | 12 + .../KeptEventRemoveMethodAttribute.cs | 12 + .../Assertions/KeptExportedTypeAttribute.cs | 20 + .../Assertions/KeptFixedBufferAttribute.cs | 12 + .../Assertions/KeptInitializerData.cs | 22 + .../Assertions/KeptInterfaceAttribute.cs | 26 + .../KeptInterfaceOnTypeInAssemblyAttribute.cs | 37 + .../Assertions/KeptMemberAttribute.cs | 18 + .../KeptMemberInAssemblyAttribute.cs | 34 + .../KeptModuleReferenceAttribute.cs | 20 + .../Assertions/KeptReferenceAttribute.cs | 20 + .../KeptReferencesInAssemblyAttribute.cs | 20 + .../Assertions/KeptResourceAttribute.cs | 20 + .../KeptResourceInAssemblyAttribute.cs | 23 + .../Assertions/KeptSecurityAttribute.cs | 23 + .../Assertions/KeptSymbolsAttribute.cs | 17 + .../Assertions/KeptTypeInAssemblyAttribute.cs | 27 + .../Assertions/LogContainsAttribute.cs | 26 + .../Assertions/LogDoesNotContainAttribute.cs | 26 + .../Assertions/NoLinkedOutputAttribute.cs | 13 + .../Assertions/ProducedBy.cs | 21 + .../Assertions/RemovedAssemblyAttribute.cs | 21 + .../Assertions/RemovedAssemblyReference.cs | 18 + .../Assertions/RemovedAttributeInAssembly.cs | 71 ++ .../Assertions/RemovedForwarderAttribute.cs | 18 + ...movedInterfaceOnTypeInAssemblyAttribute.cs | 37 + .../RemovedMemberInAssemblyAttribute.cs | 32 + .../Assertions/RemovedNameValueAttribute.cs | 15 + .../RemovedPseudoAttributeAttribute.cs | 15 + .../RemovedResourceInAssemblyAttribute.cs | 23 + .../Assertions/RemovedSymbolsAttribute.cs | 17 + .../RemovedTypeInAssemblyAttribute.cs | 27 + .../SkipKeptItemsValidationAttribute.cs | 13 + .../Assertions/SkipPeVerifyAttribute.cs | 29 + .../SkipRemainingErrorsValidationAttribute.cs | 13 + .../TestCaseRequirementsAttribute.cs | 17 + .../Assertions/TestRunCharacteristics.cs | 17 + .../VerifyMetadataNamesAttribute.cs | 15 + .../Helpers/DataFlowStringExtensions.cs | 42 + .../Helpers/DataFlowTypeExtensions.cs | 43 + .../Helpers/PlatformAssemblies.cs | 14 + .../Metadata/BaseMetadataAttribute.cs | 13 + .../Metadata/DefineAttribute.cs | 17 + .../Metadata/IgnoreDescriptorsAttribute.cs | 15 + .../Metadata/IgnoreLinkAttributesAttribute.cs | 15 + .../Metadata/IgnoreSubstitutionsAttribute.cs | 15 + .../Metadata/Il8nAttribute.cs | 18 + ...eepTypeForwarderOnlyAssembliesAttribute.cs | 17 + .../Metadata/NotATestCaseAttribute.cs | 12 + .../Metadata/ReferenceAttribute.cs | 18 + .../Metadata/ReferenceDependencyAttribute.cs | 17 + .../Metadata/SandboxDependencyAttribute.cs | 24 + .../SetupCSharpCompilerToUseAttribute.cs | 17 + .../Metadata/SetupCompileAfterAttribute.cs | 36 + .../Metadata/SetupCompileArgumentAttribute.cs | 17 + .../SetupCompileAsLibraryAttribute.cs | 12 + .../SetupCompileAssemblyNameAttribute.cs | 17 + .../Metadata/SetupCompileBeforeAttribute.cs | 58 ++ .../Metadata/SetupCompileResourceAttribute.cs | 17 + .../Metadata/SetupLinkAttributesFile.cs | 15 + .../Metadata/SetupLinkerActionAttribute.cs | 17 + .../Metadata/SetupLinkerArgumentAttribute.cs | 24 + .../SetupLinkerDefaultActionAttribute.cs | 17 + .../Metadata/SetupLinkerDescriptorFile.cs | 15 + .../SetupLinkerKeepDebugMembersAttribute.cs | 17 + ...SetupLinkerLinkPublicAndFamilyAttribute.cs | 12 + .../SetupLinkerLinkSymbolsAttribute.cs | 17 + .../SetupLinkerResponseFileAttribute.cs | 17 + .../SetupLinkerSubstitutionFileAttribute.cs | 17 + .../Metadata/SetupLinkerTrimModeAttribute.cs | 17 + .../Metadata/SkipUnresolvedAttribute.cs | 15 + .../Metadata/StripDescriptorsAttribute.cs | 15 + .../Metadata/StripLinkAttributesAttribute.cs | 15 + .../Metadata/StripSubstitutionsAttribute.cs | 15 + ...ono.Linker.Tests.Cases.Expectations.csproj | 10 + .../Support/IntrinsicAttribute.cs | 12 + .../RemoveAttributeInstancesAttribute.cs | 17 + .../DataFlow/AssemblyQualifiedNameDataflow.cs | 163 +++ .../DataFlow/EmptyArrayIntrinsicsDataFlow.cs | 60 ++ .../DataFlow/GetInterfaceDataFlow.cs | 198 ++++ .../GetNestedTypeOnAllAnnotatedType.cs | 141 +++ .../DataFlow/GetTypeDataFlow.cs | 220 ++++ .../DataFlow/GetTypeInfoDataFlow.cs | 54 + .../DataFlow/MemberTypesRelationships.cs | 275 +++++ .../DataFlow/TypeInfoAsTypeDataFlow.cs | 55 + .../DataFlow/UnsafeDataFlow.cs | 68 ++ .../Mono.Linker.Tests.Cases.csproj | 17 + .../Mono.Linker.Tests.Cases/Repro/Program.cs | 30 + .../RequiresCapability/BasicRequires.cs | 215 ++++ .../Extensions/CecilExtensions.cs | 368 +++++++ .../Mono.Linker.Tests/Extensions/NiceIO.cs | 864 ++++++++++++++++ .../Mono.Linker.Tests.csproj | 51 + .../Mono.Linker.Tests/TestCases/TestCase.cs | 59 ++ .../TestCases/TestDatabase.cs | 76 ++ .../Mono.Linker.Tests/TestCases/TestSuites.cs | 45 + .../TestCasesRunner/AssemblyChecker.cs | 960 ++++++++++++++++++ .../TestCasesRunner/BaseMetadataProvider.cs | 96 ++ .../TestCasesRunner/CompilerOptions.cs | 20 + .../TestCasesRunner/ExpectationsProvider.cs | 26 + .../TestCasesRunner/FormattingUtils.cs | 64 ++ .../TestCasesRunner/ILCompilerDriver.cs | 137 +++ .../TestCasesRunner/ILCompilerOptions.cs | 16 + .../ILCompilerOptionsBuilder.cs | 253 +++++ .../ILCompilerTestCaseResult.cs | 31 + .../TestCasesRunner/ILInputCompiler.cs | 93 ++ .../TestCasesRunner/IgnoreTestException.cs | 12 + .../ManagedCompilationResult.cs | 20 + .../TestCasesRunner/ObjectFactory.cs | 41 + .../TestCasesRunner/PathUtilities.cs | 35 + .../TestCasesRunner/ResultChecker.cs | 405 ++++++++ .../TestCasesRunner/SetupCompileInfo.cs | 23 + .../SourceAndDestinationPair.cs | 15 + .../TestCaseAssemblyResolver.cs | 43 + .../TestCasesRunner/TestCaseCollector.cs | 165 +++ .../TestCaseCompilationMetadataProvider.cs | 242 +++++ .../TestCasesRunner/TestCaseCompiler.cs | 411 ++++++++ .../TestCasesRunner/TestCaseLinkerOptions.cs | 36 + .../TestCaseMetadataProvider.cs | 141 +++ .../TestCasesRunner/TestCaseSandbox.cs | 195 ++++ .../TestCasesRunner/TestLogWriter.cs | 57 ++ .../TestCasesRunner/TestRunner.cs | 165 +++ src/coreclr/tools/aot/ilc.sln | 68 +- 157 files changed, 9001 insertions(+), 5 deletions(-) create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/AddedPseudoAttributeAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/BaseExpectedLinkedBehaviorAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/BaseInAssemblyAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/BaseMemberAssertionAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/CreatedMemberAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/DependencyRecordedAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/DisplayNameAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/EnableLoggerAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectBodyModifiedAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectExactlyResolvedDocumentationSignatureAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectExceptionHandlersModifiedAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectGeneratedDocumentationSignatureAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectLocalsModifiedAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectResolvedDocumentationSignatureAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectUnresolvedDocumentationSignatureAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedInstructionSequenceAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedInstructionSequenceOnMemberInAssemblyAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedLocalsSequenceAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedNoWarningsAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedWarningAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/IgnoreTestCaseAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAllTypesAndMembersInAssemblyAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAssemblyAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttributeAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttributeInAssemblyAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttributeOnFixedBufferTypeAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptBackingFieldAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptBaseOnTypeInAssemblyAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptBaseTypeAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptDelegateCacheFieldAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptEventAddMethodAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptEventRemoveMethodAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptExportedTypeAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptFixedBufferAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptInitializerData.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptInterfaceAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptInterfaceOnTypeInAssemblyAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptMemberAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptMemberInAssemblyAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptModuleReferenceAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptReferenceAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptReferencesInAssemblyAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptResourceAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptResourceInAssemblyAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptSecurityAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptSymbolsAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptTypeInAssemblyAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/LogContainsAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/LogDoesNotContainAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/NoLinkedOutputAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ProducedBy.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedAssemblyAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedAssemblyReference.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedAttributeInAssembly.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedForwarderAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedInterfaceOnTypeInAssemblyAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedMemberInAssemblyAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedNameValueAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedPseudoAttributeAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedResourceInAssemblyAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedSymbolsAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedTypeInAssemblyAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipKeptItemsValidationAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipPeVerifyAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipRemainingErrorsValidationAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/TestCaseRequirementsAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/TestRunCharacteristics.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/VerifyMetadataNamesAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Helpers/DataFlowStringExtensions.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Helpers/DataFlowTypeExtensions.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Helpers/PlatformAssemblies.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/BaseMetadataAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/DefineAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/IgnoreDescriptorsAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/IgnoreLinkAttributesAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/IgnoreSubstitutionsAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/Il8nAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/KeepTypeForwarderOnlyAssembliesAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/NotATestCaseAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/ReferenceAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/ReferenceDependencyAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SandboxDependencyAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCSharpCompilerToUseAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileAfterAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileArgumentAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileAsLibraryAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileAssemblyNameAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileBeforeAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileResourceAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkAttributesFile.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerActionAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerArgumentAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerDefaultActionAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerDescriptorFile.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerKeepDebugMembersAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerLinkPublicAndFamilyAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerLinkSymbolsAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerResponseFileAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerSubstitutionFileAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerTrimModeAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SkipUnresolvedAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/StripDescriptorsAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/StripLinkAttributesAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/StripSubstitutionsAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Mono.Linker.Tests.Cases.Expectations.csproj create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Support/IntrinsicAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Support/RemoveAttributeInstancesAttribute.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/AssemblyQualifiedNameDataflow.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/EmptyArrayIntrinsicsDataFlow.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/GetInterfaceDataFlow.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/GetNestedTypeOnAllAnnotatedType.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/GetTypeDataFlow.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/GetTypeInfoDataFlow.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/MemberTypesRelationships.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/TypeInfoAsTypeDataFlow.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/UnsafeDataFlow.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases/Mono.Linker.Tests.Cases.csproj create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases/Repro/Program.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests.Cases/RequiresCapability/BasicRequires.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/Extensions/CecilExtensions.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/Extensions/NiceIO.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/Mono.Linker.Tests.csproj create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestCase.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestDatabase.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestSuites.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/AssemblyChecker.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/BaseMetadataProvider.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/CompilerOptions.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ExpectationsProvider.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/FormattingUtils.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILCompilerDriver.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILCompilerOptions.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILCompilerOptionsBuilder.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILCompilerTestCaseResult.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILInputCompiler.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/IgnoreTestException.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ManagedCompilationResult.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ObjectFactory.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/PathUtilities.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/SetupCompileInfo.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/SourceAndDestinationPair.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseAssemblyResolver.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseCollector.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseCompilationMetadataProvider.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseCompiler.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseLinkerOptions.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseMetadataProvider.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseSandbox.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestLogWriter.cs create mode 100644 src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestRunner.cs diff --git a/eng/Subsets.props b/eng/Subsets.props index 4fbd6b5e3fbf66..7d6bfc86825cc7 100644 --- a/eng/Subsets.props +++ b/eng/Subsets.props @@ -312,6 +312,8 @@ Test="true" Category="clr" Condition="'$(DotNetBuildFromSource)' != 'true'"/> + diff --git a/eng/pipelines/coreclr/templates/build-job.yml b/eng/pipelines/coreclr/templates/build-job.yml index 74e6b3cfaf0f01..fd077f2e85558b 100644 --- a/eng/pipelines/coreclr/templates/build-job.yml +++ b/eng/pipelines/coreclr/templates/build-job.yml @@ -224,6 +224,8 @@ jobs: # Run CoreCLR Tools unit tests - ${{ if eq(parameters.testGroup, 'clrTools') }}: + - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -subset libs $(crossArg) -arch $(archType) $(osArg) -c $(buildConfig) $(officialBuildIdArg) -ci + displayName: Build libs - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -subset clr.toolstests $(crossArg) -arch $(archType) $(osArg) -c $(buildConfig) $(officialBuildIdArg) -ci -test displayName: Run CoreCLR Tools unit tests diff --git a/src/coreclr/tools/Common/Compiler/DisplayNameHelpers.cs b/src/coreclr/tools/Common/Compiler/DisplayNameHelpers.cs index 0c4b0e16844731..549d8fbd290b2d 100644 --- a/src/coreclr/tools/Common/Compiler/DisplayNameHelpers.cs +++ b/src/coreclr/tools/Common/Compiler/DisplayNameHelpers.cs @@ -12,7 +12,7 @@ namespace ILCompiler { - internal static class DisplayNameHelpers + public static class DisplayNameHelpers { public static string GetDisplayName(this TypeSystemEntity entity) { diff --git a/src/coreclr/tools/aot/.editorconfig b/src/coreclr/tools/aot/.editorconfig index 5f1bbfd2429970..f5e97a5d50a0d6 100644 --- a/src/coreclr/tools/aot/.editorconfig +++ b/src/coreclr/tools/aot/.editorconfig @@ -27,3 +27,84 @@ dotnet_sort_system_directives_first = true csharp_style_expression_bodied_properties = true:none csharp_style_expression_bodied_indexers = true:none csharp_style_expression_bodied_accessors = true:none + +[Mono.Linker.Tests/**.cs] +indent_style = tab +indent_size = 4 +csharp_new_line_before_open_brace = types,methods +csharp_new_line_before_else = false +csharp_new_line_before_catch = false +csharp_new_line_before_finally = false +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_between_query_expression_clauses = true + +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_between_method_declaration_name_and_open_parenthesis = true +csharp_space_between_method_call_name_and_opening_parenthesis = true +csharp_space_before_open_square_brackets = false +csharp_space_after_cast = true + +csharp_indent_switch_labels = false + +# Sort using and Import directives with System.* appearing first +dotnet_sort_system_directives_first = true + +# Prefer property-like constructs to have an expression-body +csharp_style_expression_bodied_properties = true:none +csharp_style_expression_bodied_indexers = true:none +csharp_style_expression_bodied_accessors = true:none + +[Mono.Linker.Tests.Cases/**.cs] +indent_style = tab +indent_size = 4 +csharp_new_line_before_open_brace = types,methods +csharp_new_line_before_else = false +csharp_new_line_before_catch = false +csharp_new_line_before_finally = false +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_between_query_expression_clauses = true + +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_between_method_declaration_name_and_open_parenthesis = true +csharp_space_between_method_call_name_and_opening_parenthesis = true +csharp_space_before_open_square_brackets = false +csharp_space_after_cast = true + +csharp_indent_switch_labels = false + +# Sort using and Import directives with System.* appearing first +dotnet_sort_system_directives_first = true + +# Prefer property-like constructs to have an expression-body +csharp_style_expression_bodied_properties = true:none +csharp_style_expression_bodied_indexers = true:none +csharp_style_expression_bodied_accessors = true:none + +[Mono.Linker.Tests.Cases.Expectations/**.cs] +indent_style = tab +indent_size = 4 +csharp_new_line_before_open_brace = types,methods +csharp_new_line_before_else = false +csharp_new_line_before_catch = false +csharp_new_line_before_finally = false +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_between_query_expression_clauses = true + +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_between_method_declaration_name_and_open_parenthesis = true +csharp_space_between_method_call_name_and_opening_parenthesis = true +csharp_space_before_open_square_brackets = false +csharp_space_after_cast = true + +csharp_indent_switch_labels = false + +# Sort using and Import directives with System.* appearing first +dotnet_sort_system_directives_first = true + +# Prefer property-like constructs to have an expression-body +csharp_style_expression_bodied_properties = true:none +csharp_style_expression_bodied_indexers = true:none +csharp_style_expression_bodied_accessors = true:none diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/AddedPseudoAttributeAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/AddedPseudoAttributeAttribute.cs new file mode 100644 index 00000000000000..92c4b044ba93f3 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/AddedPseudoAttributeAttribute.cs @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Delegate | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event, AllowMultiple = true, Inherited = false)] + public class AddedPseudoAttributeAttribute : BaseExpectedLinkedBehaviorAttribute + { + public AddedPseudoAttributeAttribute (uint value) + { + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/BaseExpectedLinkedBehaviorAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/BaseExpectedLinkedBehaviorAttribute.cs new file mode 100644 index 00000000000000..9a963f61055715 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/BaseExpectedLinkedBehaviorAttribute.cs @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Diagnostics; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + /// + /// Base attribute for attributes that mark up the expected behavior of the linker on a member + /// + [Conditional ("INCLUDE_EXPECTATIONS")] + public abstract class BaseExpectedLinkedBehaviorAttribute : Attribute + { + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/BaseInAssemblyAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/BaseInAssemblyAttribute.cs new file mode 100644 index 00000000000000..1d8ed24b3645c1 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/BaseInAssemblyAttribute.cs @@ -0,0 +1,9 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + public abstract class BaseInAssemblyAttribute : BaseExpectedLinkedBehaviorAttribute + { + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/BaseMemberAssertionAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/BaseMemberAssertionAttribute.cs new file mode 100644 index 00000000000000..5afd16cfd6d9e1 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/BaseMemberAssertionAttribute.cs @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + /// A base class for attributes that make assertions about a particular member. + // The test infrastructure is expected to check the assertion on the member to which + // the attribute is applied. + [AttributeUsage (AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Delegate, AllowMultiple = true)] + public abstract class BaseMemberAssertionAttribute : Attribute + { + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/CreatedMemberAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/CreatedMemberAttribute.cs new file mode 100644 index 00000000000000..9fdbb1938776e5 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/CreatedMemberAttribute.cs @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class | AttributeTargets.Delegate | AttributeTargets.Struct | AttributeTargets.Enum, AllowMultiple = true, Inherited = false)] + public sealed class CreatedMemberAttribute : BaseExpectedLinkedBehaviorAttribute + { + + public CreatedMemberAttribute (string name) + { + if (string.IsNullOrEmpty (name)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (name)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/DependencyRecordedAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/DependencyRecordedAttribute.cs new file mode 100644 index 00000000000000..72202346725667 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/DependencyRecordedAttribute.cs @@ -0,0 +1,20 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true, Inherited = false)] + public class DependencyRecordedAttribute : BaseExpectedLinkedBehaviorAttribute + { + public DependencyRecordedAttribute (string source, string target, string marked = null) + { + if (string.IsNullOrEmpty (source)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (source)); + + if (string.IsNullOrEmpty (target)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (target)); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/DisplayNameAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/DisplayNameAttribute.cs new file mode 100644 index 00000000000000..3e369a539e630a --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/DisplayNameAttribute.cs @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + public class DisplayNameAttribute : BaseMemberAssertionAttribute + { + public DisplayNameAttribute (string expectedDisplayName) + { + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/EnableLoggerAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/EnableLoggerAttribute.cs new file mode 100644 index 00000000000000..436281610fbebd --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/EnableLoggerAttribute.cs @@ -0,0 +1,9 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + public abstract class EnableLoggerAttribute : BaseExpectedLinkedBehaviorAttribute + { + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectBodyModifiedAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectBodyModifiedAttribute.cs new file mode 100644 index 00000000000000..dbe07219cf015c --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectBodyModifiedAttribute.cs @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Method | AttributeTargets.Constructor, Inherited = false, AllowMultiple = false)] + public class ExpectBodyModifiedAttribute : BaseInAssemblyAttribute + { + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectExactlyResolvedDocumentationSignatureAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectExactlyResolvedDocumentationSignatureAttribute.cs new file mode 100644 index 00000000000000..b618ed7a354867 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectExactlyResolvedDocumentationSignatureAttribute.cs @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + /// Asserts that the given documentation signature string resolves to the + // member with this attribute, and only that member. + public class ExpectExactlyResolvedDocumentationSignatureAttribute : BaseMemberAssertionAttribute + { + public ExpectExactlyResolvedDocumentationSignatureAttribute (string input) + { + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectExceptionHandlersModifiedAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectExceptionHandlersModifiedAttribute.cs new file mode 100644 index 00000000000000..a76e4b64897779 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectExceptionHandlersModifiedAttribute.cs @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Method | AttributeTargets.Constructor, Inherited = false, AllowMultiple = false)] + public class ExpectExceptionHandlersModifiedAttribute : BaseInAssemblyAttribute + { + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectGeneratedDocumentationSignatureAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectGeneratedDocumentationSignatureAttribute.cs new file mode 100644 index 00000000000000..c25b2ff3d02624 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectGeneratedDocumentationSignatureAttribute.cs @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + /// Asserts that the member to which this attribute is applied has the given + /// documentation signature. + public class ExpectGeneratedDocumentationSignatureAttribute : BaseMemberAssertionAttribute + { + public ExpectGeneratedDocumentationSignatureAttribute (string expected) + { + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectLocalsModifiedAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectLocalsModifiedAttribute.cs new file mode 100644 index 00000000000000..56a30bd52d20cf --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectLocalsModifiedAttribute.cs @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Method | AttributeTargets.Constructor, Inherited = false, AllowMultiple = false)] + public class ExpectLocalsModifiedAttribute : BaseInAssemblyAttribute + { + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectResolvedDocumentationSignatureAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectResolvedDocumentationSignatureAttribute.cs new file mode 100644 index 00000000000000..5a3c16fe9bcc2d --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectResolvedDocumentationSignatureAttribute.cs @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + /// Asserts that the given documentation signature string resolves to the + // member with this attribute. + public class ExpectResolvedDocumentationSignatureAttribute : BaseMemberAssertionAttribute + { + public ExpectResolvedDocumentationSignatureAttribute (string input) + { + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectUnresolvedDocumentationSignatureAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectUnresolvedDocumentationSignatureAttribute.cs new file mode 100644 index 00000000000000..aea9068451bcc1 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectUnresolvedDocumentationSignatureAttribute.cs @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + /// Asserts that the given documentation signature string does not resolve + /// to the member with this attribute. + public class ExpectUnresolvedDocumentationSignatureAttribute : BaseMemberAssertionAttribute + { + public ExpectUnresolvedDocumentationSignatureAttribute (string expected) + { + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedInstructionSequenceAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedInstructionSequenceAttribute.cs new file mode 100644 index 00000000000000..35ead6966a4f62 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedInstructionSequenceAttribute.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Method | AttributeTargets.Constructor, Inherited = false, AllowMultiple = false)] + public class ExpectedInstructionSequenceAttribute : BaseInAssemblyAttribute + { + public ExpectedInstructionSequenceAttribute (string[] opCodes) + { + if (opCodes == null) + throw new ArgumentNullException (nameof (opCodes)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedInstructionSequenceOnMemberInAssemblyAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedInstructionSequenceOnMemberInAssemblyAttribute.cs new file mode 100644 index 00000000000000..899b979c5211e8 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedInstructionSequenceOnMemberInAssemblyAttribute.cs @@ -0,0 +1,35 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class, Inherited = false, AllowMultiple = true)] + public class ExpectedInstructionSequenceOnMemberInAssemblyAttribute : BaseInAssemblyAttribute + { + public ExpectedInstructionSequenceOnMemberInAssemblyAttribute (string assemblyFileName, Type type, string memberName, string[] opCodes) + { + if (string.IsNullOrEmpty (assemblyFileName)) + throw new ArgumentNullException (nameof (assemblyFileName)); + if (type == null) + throw new ArgumentNullException (nameof (type)); + if (string.IsNullOrEmpty (memberName)) + throw new ArgumentNullException (nameof (memberName)); + if (opCodes == null) + throw new ArgumentNullException (nameof (opCodes)); + } + + public ExpectedInstructionSequenceOnMemberInAssemblyAttribute (string assemblyFileName, string typeName, string memberName, string[] opCodes) + { + if (string.IsNullOrEmpty (assemblyFileName)) + throw new ArgumentNullException (nameof (assemblyFileName)); + if (string.IsNullOrEmpty (typeName)) + throw new ArgumentNullException (nameof (typeName)); + if (string.IsNullOrEmpty (memberName)) + throw new ArgumentNullException (nameof (memberName)); + if (opCodes == null) + throw new ArgumentNullException (nameof (opCodes)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedLocalsSequenceAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedLocalsSequenceAttribute.cs new file mode 100644 index 00000000000000..fdd3441b71f44f --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedLocalsSequenceAttribute.cs @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Method | AttributeTargets.Constructor, Inherited = false, AllowMultiple = false)] + public class ExpectedLocalsSequenceAttribute : BaseInAssemblyAttribute + { + public ExpectedLocalsSequenceAttribute (string[] types) + { + if (types == null) + throw new ArgumentNullException (nameof (types)); + } + + public ExpectedLocalsSequenceAttribute (Type[] types) + { + if (types == null) + throw new ArgumentNullException (nameof (types)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedNoWarningsAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedNoWarningsAttribute.cs new file mode 100644 index 00000000000000..cd6e8f38667b25 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedNoWarningsAttribute.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage ( + AttributeTargets.Struct | AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Constructor | AttributeTargets.Field, + AllowMultiple = false, + Inherited = false)] + public class ExpectedNoWarningsAttribute : EnableLoggerAttribute + { + public ExpectedNoWarningsAttribute () { } + public ExpectedNoWarningsAttribute (string warningCode) { } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedWarningAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedWarningAttribute.cs new file mode 100644 index 00000000000000..94d9f1c2cf725c --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ExpectedWarningAttribute.cs @@ -0,0 +1,30 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage ( + AttributeTargets.Assembly | AttributeTargets.Struct | AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Event, + AllowMultiple = true, + Inherited = false)] + public class ExpectedWarningAttribute : EnableLoggerAttribute + { + public ExpectedWarningAttribute (string warningCode, params string[] messageContains) + { + } + + public string FileName { get; set; } + public int SourceLine { get; set; } + public int SourceColumn { get; set; } + + /// + /// Property used by the result checkers of trimmer and analyzers to determine whether + /// the tool should have produced the specified warning on the annotated member. + /// + public ProducedBy ProducedBy { get; set; } = ProducedBy.TrimmerAnalyzerAndNativeAot; + + public bool CompilerGeneratedCode { get; set; } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/IgnoreTestCaseAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/IgnoreTestCaseAttribute.cs new file mode 100644 index 00000000000000..78fd0e45374232 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/IgnoreTestCaseAttribute.cs @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class)] + public class IgnoreTestCaseAttribute : Attribute + { + + public IgnoreTestCaseAttribute (string reason) + { + if (reason == null) + throw new ArgumentNullException (nameof (reason)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAllTypesAndMembersInAssemblyAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAllTypesAndMembersInAssemblyAttribute.cs new file mode 100644 index 00000000000000..ffdb9d07c2e0a5 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAllTypesAndMembersInAssemblyAttribute.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class | AttributeTargets.Delegate, AllowMultiple = true, Inherited = false)] + public class KeptAllTypesAndMembersInAssemblyAttribute : BaseInAssemblyAttribute + { + public KeptAllTypesAndMembersInAssemblyAttribute (string assemblyFileName) + { + if (string.IsNullOrEmpty (assemblyFileName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (assemblyFileName)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAssemblyAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAssemblyAttribute.cs new file mode 100644 index 00000000000000..9103fa1c31763e --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAssemblyAttribute.cs @@ -0,0 +1,21 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + /// + /// Verifies that an assembly does exist in the output directory + /// + [AttributeUsage (AttributeTargets.Class | AttributeTargets.Delegate, AllowMultiple = true, Inherited = false)] + public class KeptAssemblyAttribute : KeptAttribute + { + + public KeptAssemblyAttribute (string fileName) + { + if (string.IsNullOrEmpty (fileName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (fileName)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttribute.cs new file mode 100644 index 00000000000000..922123f7d11bd0 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttribute.cs @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.All, Inherited = false)] + public class KeptAttribute : BaseExpectedLinkedBehaviorAttribute + { + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttributeAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttributeAttribute.cs new file mode 100644 index 00000000000000..0b5943a5a1a5e8 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttributeAttribute.cs @@ -0,0 +1,24 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.All, AllowMultiple = true, Inherited = false)] + public class KeptAttributeAttribute : KeptAttribute + { + + public KeptAttributeAttribute (string attributeName) + { + if (string.IsNullOrEmpty (attributeName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (attributeName)); + } + + public KeptAttributeAttribute (Type type) + { + if (type == null) + throw new ArgumentNullException (nameof (type)); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttributeInAssemblyAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttributeInAssemblyAttribute.cs new file mode 100644 index 00000000000000..91081f68a1416b --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttributeInAssemblyAttribute.cs @@ -0,0 +1,71 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true, Inherited = false)] + public class KeptAttributeInAssemblyAttribute : BaseInAssemblyAttribute + { + /// + /// Asserts a CustomAttribute was kept on an assembly + /// + /// + /// + public KeptAttributeInAssemblyAttribute (string assemblyName, string attributeTypeName) + { + } + + /// + /// Asserts a CustomAttribute was kept on an assembly + /// + /// + /// + public KeptAttributeInAssemblyAttribute (string assemblyName, Type attributeType) + { + } + + /// + /// Asserts a CustomAttribute was kept on a specific type + /// + /// + /// + /// + public KeptAttributeInAssemblyAttribute (string assemblyName, string attributeTypeName, string onType) + { + } + + /// + /// Asserts a CustomAttribute was kept on a specific type + /// + /// + /// + /// + public KeptAttributeInAssemblyAttribute (string assemblyName, Type attributeType, Type onType) + { + } + + /// + /// Asserts a CustomAttribute was kept on a member in a specific type + /// + /// + /// + /// + /// + public KeptAttributeInAssemblyAttribute (string assemblyName, string attributeTypeName, string onType, string member) + { + } + + /// + /// Asserts a CustomAttribute was kept on a member in a specific type + /// + /// + /// + /// + /// + public KeptAttributeInAssemblyAttribute (string assemblyName, Type attributeType, Type onType, string member) + { + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttributeOnFixedBufferTypeAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttributeOnFixedBufferTypeAttribute.cs new file mode 100644 index 00000000000000..0fc56741a8ca42 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptAttributeOnFixedBufferTypeAttribute.cs @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Field, Inherited = false, AllowMultiple = true)] + public class KeptAttributeOnFixedBufferTypeAttribute : KeptAttribute + { + public KeptAttributeOnFixedBufferTypeAttribute (string attributeName) + { + if (string.IsNullOrEmpty (attributeName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (attributeName)); + } + + public KeptAttributeOnFixedBufferTypeAttribute (Type type) + { + if (type == null) + throw new ArgumentNullException (nameof (type)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptBackingFieldAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptBackingFieldAttribute.cs new file mode 100644 index 00000000000000..6994e1201f16e8 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptBackingFieldAttribute.cs @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Property | AttributeTargets.Event, AllowMultiple = false, Inherited = false)] + public sealed class KeptBackingFieldAttribute : KeptAttribute + { + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptBaseOnTypeInAssemblyAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptBaseOnTypeInAssemblyAttribute.cs new file mode 100644 index 00000000000000..acac5d575bbcea --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptBaseOnTypeInAssemblyAttribute.cs @@ -0,0 +1,37 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true, Inherited = false)] + public class KeptBaseOnTypeInAssemblyAttribute : BaseInAssemblyAttribute + { + public KeptBaseOnTypeInAssemblyAttribute (string assemblyFileName, Type type, string baseAssemblyFileName, Type baseType) + { + if (type == null) + throw new ArgumentNullException (nameof (type)); + if (string.IsNullOrEmpty (assemblyFileName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (assemblyFileName)); + + if (string.IsNullOrEmpty (baseAssemblyFileName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (baseAssemblyFileName)); + if (baseType == null) + throw new ArgumentException ("Value cannot be null or empty.", nameof (baseType)); + } + + public KeptBaseOnTypeInAssemblyAttribute (string assemblyFileName, string typeName, string baseAssemblyFileName, string baseTypeName) + { + if (string.IsNullOrEmpty (assemblyFileName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (assemblyFileName)); + if (string.IsNullOrEmpty (typeName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (typeName)); + + if (string.IsNullOrEmpty (baseAssemblyFileName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (baseAssemblyFileName)); + if (string.IsNullOrEmpty (baseTypeName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (baseTypeName)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptBaseTypeAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptBaseTypeAttribute.cs new file mode 100644 index 00000000000000..c4e4a24889542c --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptBaseTypeAttribute.cs @@ -0,0 +1,25 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class | AttributeTargets.Delegate | AttributeTargets.Enum, AllowMultiple = false, Inherited = false)] + public sealed class KeptBaseTypeAttribute : KeptAttribute + { + public KeptBaseTypeAttribute (Type baseType) + { + if (baseType == null) + throw new ArgumentNullException (nameof (baseType)); + } + + public KeptBaseTypeAttribute (Type baseType, params object[] typeArguments) + { + if (baseType == null) + throw new ArgumentNullException (nameof (baseType)); + if (typeArguments == null) + throw new ArgumentNullException (nameof (typeArguments)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptDelegateCacheFieldAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptDelegateCacheFieldAttribute.cs new file mode 100644 index 00000000000000..52fe496182f8ba --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptDelegateCacheFieldAttribute.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = true)] + public class KeptDelegateCacheFieldAttribute : KeptAttribute + { + public KeptDelegateCacheFieldAttribute (string uniquePartOfName) + { + if (string.IsNullOrEmpty (uniquePartOfName)) + throw new ArgumentNullException (nameof (uniquePartOfName)); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptEventAddMethodAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptEventAddMethodAttribute.cs new file mode 100644 index 00000000000000..2b745838c96666 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptEventAddMethodAttribute.cs @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Event, Inherited = false, AllowMultiple = false)] + public class KeptEventAddMethodAttribute : KeptAttribute + { + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptEventRemoveMethodAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptEventRemoveMethodAttribute.cs new file mode 100644 index 00000000000000..0cbcdd171a91e4 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptEventRemoveMethodAttribute.cs @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Event, Inherited = false, AllowMultiple = false)] + public class KeptEventRemoveMethodAttribute : KeptAttribute + { + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptExportedTypeAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptExportedTypeAttribute.cs new file mode 100644 index 00000000000000..76dbe921c94572 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptExportedTypeAttribute.cs @@ -0,0 +1,20 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + /// + /// Verifies that a module reference exists in the test case assembly + /// + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true, Inherited = false)] + public class KeptExportedTypeAttribute : KeptAttribute + { + public KeptExportedTypeAttribute (Type type) + { + if (type is null) + throw new ArgumentNullException (nameof (type)); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptFixedBufferAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptFixedBufferAttribute.cs new file mode 100644 index 00000000000000..d0067544ad7609 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptFixedBufferAttribute.cs @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Field, Inherited = false, AllowMultiple = false)] + public class KeptFixedBufferAttribute : KeptAttribute + { + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptInitializerData.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptInitializerData.cs new file mode 100644 index 00000000000000..25b8c8261f16ce --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptInitializerData.cs @@ -0,0 +1,22 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Method, AllowMultiple = true, Inherited = false)] + public class KeptInitializerData : KeptAttribute + { + + public KeptInitializerData () + { + } + + public KeptInitializerData (int occurrenceIndexInBody) + { + if (occurrenceIndexInBody < 0) + throw new ArgumentOutOfRangeException (nameof (occurrenceIndexInBody)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptInterfaceAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptInterfaceAttribute.cs new file mode 100644 index 00000000000000..85279abcd83f6d --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptInterfaceAttribute.cs @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = true, Inherited = false)] + public class KeptInterfaceAttribute : KeptAttribute + { + + public KeptInterfaceAttribute (Type interfaceType) + { + if (interfaceType == null) + throw new ArgumentNullException (nameof (interfaceType)); + } + + public KeptInterfaceAttribute (Type interfaceType, params object[] typeArguments) + { + if (interfaceType == null) + throw new ArgumentNullException (nameof (interfaceType)); + if (typeArguments == null) + throw new ArgumentNullException (nameof (typeArguments)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptInterfaceOnTypeInAssemblyAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptInterfaceOnTypeInAssemblyAttribute.cs new file mode 100644 index 00000000000000..2741439facc88d --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptInterfaceOnTypeInAssemblyAttribute.cs @@ -0,0 +1,37 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true, Inherited = false)] + public class KeptInterfaceOnTypeInAssemblyAttribute : BaseInAssemblyAttribute + { + public KeptInterfaceOnTypeInAssemblyAttribute (string assemblyFileName, Type type, string interfaceAssemblyFileName, Type interfaceType) + { + if (type == null) + throw new ArgumentNullException (nameof (type)); + if (string.IsNullOrEmpty (assemblyFileName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (assemblyFileName)); + + if (string.IsNullOrEmpty (interfaceAssemblyFileName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (interfaceAssemblyFileName)); + if (interfaceType == null) + throw new ArgumentException ("Value cannot be null or empty.", nameof (interfaceType)); + } + + public KeptInterfaceOnTypeInAssemblyAttribute (string assemblyFileName, string typeName, string interfaceAssemblyFileName, string interfaceTypeName) + { + if (string.IsNullOrEmpty (assemblyFileName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (assemblyFileName)); + if (string.IsNullOrEmpty (typeName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (typeName)); + + if (string.IsNullOrEmpty (interfaceAssemblyFileName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (interfaceAssemblyFileName)); + if (string.IsNullOrEmpty (interfaceTypeName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (interfaceTypeName)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptMemberAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptMemberAttribute.cs new file mode 100644 index 00000000000000..6f7adcf30bedba --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptMemberAttribute.cs @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class | AttributeTargets.Delegate | AttributeTargets.Struct | AttributeTargets.Enum, AllowMultiple = true, Inherited = false)] + public sealed class KeptMemberAttribute : KeptAttribute + { + + public KeptMemberAttribute (string name) + { + if (string.IsNullOrEmpty (name)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (name)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptMemberInAssemblyAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptMemberInAssemblyAttribute.cs new file mode 100644 index 00000000000000..b8e38f5788c051 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptMemberInAssemblyAttribute.cs @@ -0,0 +1,34 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class | AttributeTargets.Delegate, AllowMultiple = true, Inherited = false)] + public class KeptMemberInAssemblyAttribute : BaseInAssemblyAttribute + { + public KeptMemberInAssemblyAttribute (string assemblyFileName, Type type, params string[] memberNames) + { + if (string.IsNullOrEmpty (assemblyFileName)) + throw new ArgumentNullException (nameof (assemblyFileName)); + if (type == null) + throw new ArgumentNullException (nameof (type)); + if (memberNames == null) + throw new ArgumentNullException (nameof (memberNames)); + } + + public KeptMemberInAssemblyAttribute (string assemblyFileName, string typeName, params string[] memberNames) + { + if (string.IsNullOrEmpty (assemblyFileName)) + throw new ArgumentNullException (nameof (assemblyFileName)); + if (typeName == null) + throw new ArgumentNullException (nameof (typeName)); + if (memberNames == null) + throw new ArgumentNullException (nameof (memberNames)); + } + + public string ExpectationAssemblyName { get; set; } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptModuleReferenceAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptModuleReferenceAttribute.cs new file mode 100644 index 00000000000000..4ebab7d9716083 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptModuleReferenceAttribute.cs @@ -0,0 +1,20 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + /// + /// Verifies that a module reference exists in the test case assembly + /// + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true, Inherited = false)] + public class KeptModuleReferenceAttribute : KeptAttribute + { + public KeptModuleReferenceAttribute (string name) + { + if (string.IsNullOrEmpty (name)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (name)); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptReferenceAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptReferenceAttribute.cs new file mode 100644 index 00000000000000..f4bb464260dba8 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptReferenceAttribute.cs @@ -0,0 +1,20 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + /// + /// Verifies that a reference exists in the test case assembly + /// + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true, Inherited = false)] + public class KeptReferenceAttribute : KeptAttribute + { + public KeptReferenceAttribute (string name) + { + if (string.IsNullOrEmpty (name)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (name)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptReferencesInAssemblyAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptReferencesInAssemblyAttribute.cs new file mode 100644 index 00000000000000..0265b9f3a40d9f --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptReferencesInAssemblyAttribute.cs @@ -0,0 +1,20 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true, Inherited = false)] + public class KeptReferencesInAssemblyAttribute : BaseInAssemblyAttribute + { + public KeptReferencesInAssemblyAttribute (string assemblyFileName, string[] expectedReferenceAssemblyNames) + { + if (string.IsNullOrEmpty (assemblyFileName)) + throw new ArgumentNullException (nameof (assemblyFileName)); + + if (expectedReferenceAssemblyNames == null) + throw new ArgumentNullException (nameof (expectedReferenceAssemblyNames)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptResourceAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptResourceAttribute.cs new file mode 100644 index 00000000000000..bcbbd20fb72531 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptResourceAttribute.cs @@ -0,0 +1,20 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + /// + /// Verifies that a resource exists in the test case assembly + /// + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true, Inherited = false)] + public class KeptResourceAttribute : KeptAttribute + { + public KeptResourceAttribute (string name) + { + if (string.IsNullOrEmpty (name)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (name)); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptResourceInAssemblyAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptResourceInAssemblyAttribute.cs new file mode 100644 index 00000000000000..fa95216e3e3b50 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptResourceInAssemblyAttribute.cs @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + /// + /// Verifies that an embedded resource exists in an assembly + /// + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true, Inherited = false)] + public class KeptResourceInAssemblyAttribute : BaseInAssemblyAttribute + { + public KeptResourceInAssemblyAttribute (string assemblyFileName, string resourceName) + { + if (string.IsNullOrEmpty (assemblyFileName)) + throw new ArgumentNullException (nameof (assemblyFileName)); + + if (string.IsNullOrEmpty (resourceName)) + throw new ArgumentNullException (nameof (resourceName)); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptSecurityAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptSecurityAttribute.cs new file mode 100644 index 00000000000000..05519377252dc6 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptSecurityAttribute.cs @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly | AttributeTargets.Method, AllowMultiple = true, Inherited = false)] + public class KeptSecurityAttribute : KeptAttribute + { + public KeptSecurityAttribute (string attributeName) + { + if (string.IsNullOrEmpty (attributeName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (attributeName)); + } + + public KeptSecurityAttribute (Type type) + { + if (type == null) + throw new ArgumentNullException (nameof (type)); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptSymbolsAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptSymbolsAttribute.cs new file mode 100644 index 00000000000000..3e435017b8b57b --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptSymbolsAttribute.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true, Inherited = false)] + public class KeptSymbolsAttribute : KeptAttribute + { + public KeptSymbolsAttribute (string assemblyFileName) + { + if (string.IsNullOrEmpty (assemblyFileName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (assemblyFileName)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptTypeInAssemblyAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptTypeInAssemblyAttribute.cs new file mode 100644 index 00000000000000..5be0adc4aa1089 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/KeptTypeInAssemblyAttribute.cs @@ -0,0 +1,27 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class | AttributeTargets.Delegate, AllowMultiple = true, Inherited = false)] + public class KeptTypeInAssemblyAttribute : BaseInAssemblyAttribute + { + public KeptTypeInAssemblyAttribute (string assemblyFileName, Type type) + { + if (type == null) + throw new ArgumentNullException (nameof (type)); + if (string.IsNullOrEmpty (assemblyFileName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (assemblyFileName)); + } + + public KeptTypeInAssemblyAttribute (string assemblyFileName, string typeName) + { + if (string.IsNullOrEmpty (assemblyFileName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (assemblyFileName)); + if (string.IsNullOrEmpty (typeName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (typeName)); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/LogContainsAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/LogContainsAttribute.cs new file mode 100644 index 00000000000000..de9b8478bfd131 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/LogContainsAttribute.cs @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage ( + AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Constructor | AttributeTargets.Field, + AllowMultiple = true, + Inherited = false)] + public class LogContainsAttribute : EnableLoggerAttribute + { + public LogContainsAttribute (string message, bool regexMatch = false) + { + if (string.IsNullOrEmpty (message)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (message)); + } + + /// + /// Property used by the result checkers of trimmer and analyzers to determine whether + /// the tool should have produced the specified warning on the annotated member. + /// + public ProducedBy ProducedBy { get; set; } = ProducedBy.TrimmerAnalyzerAndNativeAot; + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/LogDoesNotContainAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/LogDoesNotContainAttribute.cs new file mode 100644 index 00000000000000..c5b47210ed8462 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/LogDoesNotContainAttribute.cs @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage ( + AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Constructor | AttributeTargets.Field, + AllowMultiple = true, + Inherited = false)] + public class LogDoesNotContainAttribute : EnableLoggerAttribute + { + public LogDoesNotContainAttribute (string message, bool regexMatch = false) + { + if (string.IsNullOrEmpty (message)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (message)); + } + + /// + /// Property used by the result checkers of trimmer and analyzers to determine whether + /// the tool should have produced the specified warning on the annotated member. + /// + public ProducedBy ProducedBy { get; set; } = ProducedBy.TrimmerAnalyzerAndNativeAot; + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/NoLinkedOutputAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/NoLinkedOutputAttribute.cs new file mode 100644 index 00000000000000..85334c97da7ca2 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/NoLinkedOutputAttribute.cs @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class)] + public class NoLinkedOutputAttribute : Attribute + { + public NoLinkedOutputAttribute () { } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ProducedBy.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ProducedBy.cs new file mode 100644 index 00000000000000..7840516cc242aa --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/ProducedBy.cs @@ -0,0 +1,21 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + /// + /// Used to specify which tool produces a warning. This can either be the trimmer, a specific analyzer, or both. + /// Currently we have all existing diagnostic analyzers listed in here so that we can leave out some expected warnings + /// when testing analyzers which do not produce them. + /// + [Flags] + public enum ProducedBy + { + Trimmer = 1, + Analyzer = 2, + NativeAot = 4, + TrimmerAnalyzerAndNativeAot = Trimmer | Analyzer | NativeAot + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedAssemblyAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedAssemblyAttribute.cs new file mode 100644 index 00000000000000..e1dc4c0e1e36a2 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedAssemblyAttribute.cs @@ -0,0 +1,21 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + /// + /// Verifies that an assembly does not exist in the output directory + /// + [AttributeUsage (AttributeTargets.Class | AttributeTargets.Delegate, AllowMultiple = true, Inherited = false)] + public class RemovedAssemblyAttribute : BaseExpectedLinkedBehaviorAttribute + { + + public RemovedAssemblyAttribute (string fileName) + { + if (string.IsNullOrEmpty (fileName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (fileName)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedAssemblyReference.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedAssemblyReference.cs new file mode 100644 index 00000000000000..4bb914493a45df --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedAssemblyReference.cs @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true, Inherited = false)] + public class RemovedAssemblyReferenceAttribute : BaseInAssemblyAttribute + { + public RemovedAssemblyReferenceAttribute (string assemblyFileName, string assemblyReferenceName) + { + if (string.IsNullOrEmpty (assemblyFileName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (assemblyFileName)); + if (string.IsNullOrEmpty (assemblyReferenceName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (assemblyReferenceName)); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedAttributeInAssembly.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedAttributeInAssembly.cs new file mode 100644 index 00000000000000..591aa81b40f0ea --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedAttributeInAssembly.cs @@ -0,0 +1,71 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true, Inherited = false)] + public class RemovedAttributeInAssembly : BaseInAssemblyAttribute + { + /// + /// Asserts a CustomAttribute was kept on an assembly + /// + /// + /// + public RemovedAttributeInAssembly (string assemblyName, string attributeTypeName) + { + } + + /// + /// Asserts a CustomAttribute was kept on an assembly + /// + /// + /// + public RemovedAttributeInAssembly (string assemblyName, Type attributeType) + { + } + + /// + /// Asserts a CustomAttribute was kept on a specific type + /// + /// + /// + /// + public RemovedAttributeInAssembly (string assemblyName, string attributeTypeName, string onType) + { + } + + /// + /// Asserts a CustomAttribute was kept on a specific type + /// + /// + /// + /// + public RemovedAttributeInAssembly (string assemblyName, Type attributeType, Type onType) + { + } + + /// + /// Asserts a CustomAttribute was kept on a member in a specific type + /// + /// + /// + /// + /// + public RemovedAttributeInAssembly (string assemblyName, string attributeTypeName, string onType, string member) + { + } + + /// + /// Asserts a CustomAttribute was kept on a member in a specific type + /// + /// + /// + /// + /// + public RemovedAttributeInAssembly (string assemblyName, Type attributeType, Type onType, string member) + { + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedForwarderAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedForwarderAttribute.cs new file mode 100644 index 00000000000000..eb9a3944736239 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedForwarderAttribute.cs @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true, Inherited = false)] + public class RemovedForwarderAttribute : BaseInAssemblyAttribute + { + public RemovedForwarderAttribute (string assemblyFileName, string typeName) + { + if (string.IsNullOrEmpty (assemblyFileName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (assemblyFileName)); + if (string.IsNullOrEmpty (typeName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (typeName)); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedInterfaceOnTypeInAssemblyAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedInterfaceOnTypeInAssemblyAttribute.cs new file mode 100644 index 00000000000000..70465fc3d6035f --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedInterfaceOnTypeInAssemblyAttribute.cs @@ -0,0 +1,37 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true, Inherited = false)] + public class RemovedInterfaceOnTypeInAssemblyAttribute : BaseInAssemblyAttribute + { + public RemovedInterfaceOnTypeInAssemblyAttribute (string assemblyFileName, Type type, string interfaceAssemblyFileName, Type interfaceType) + { + if (type == null) + throw new ArgumentNullException (nameof (type)); + if (string.IsNullOrEmpty (assemblyFileName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (assemblyFileName)); + + if (string.IsNullOrEmpty (interfaceAssemblyFileName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (interfaceAssemblyFileName)); + if (interfaceType == null) + throw new ArgumentException ("Value cannot be null or empty.", nameof (interfaceType)); + } + + public RemovedInterfaceOnTypeInAssemblyAttribute (string assemblyFileName, string typeName, string interfaceAssemblyFileName, string interfaceTypeName) + { + if (string.IsNullOrEmpty (assemblyFileName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (assemblyFileName)); + if (string.IsNullOrEmpty (typeName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (typeName)); + + if (string.IsNullOrEmpty (interfaceAssemblyFileName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (interfaceAssemblyFileName)); + if (string.IsNullOrEmpty (interfaceTypeName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (interfaceTypeName)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedMemberInAssemblyAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedMemberInAssemblyAttribute.cs new file mode 100644 index 00000000000000..fe0deb6374aaf2 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedMemberInAssemblyAttribute.cs @@ -0,0 +1,32 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class | AttributeTargets.Delegate, AllowMultiple = true, Inherited = false)] + public class RemovedMemberInAssemblyAttribute : BaseInAssemblyAttribute + { + + public RemovedMemberInAssemblyAttribute (string assemblyFileName, Type type, params string[] memberNames) + { + if (string.IsNullOrEmpty (assemblyFileName)) + throw new ArgumentNullException (nameof (assemblyFileName)); + if (type == null) + throw new ArgumentNullException (nameof (type)); + if (memberNames == null) + throw new ArgumentNullException (nameof (memberNames)); + } + + public RemovedMemberInAssemblyAttribute (string assemblyFileName, string typeName, params string[] memberNames) + { + if (string.IsNullOrEmpty (assemblyFileName)) + throw new ArgumentNullException (nameof (assemblyFileName)); + if (typeName == null) + throw new ArgumentNullException (nameof (typeName)); + if (memberNames == null) + throw new ArgumentNullException (nameof (memberNames)); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedNameValueAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedNameValueAttribute.cs new file mode 100644 index 00000000000000..027bd35955801d --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedNameValueAttribute.cs @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + /// + /// Verifies that name of the member is removed + /// + [AttributeUsage (AttributeTargets.All, AllowMultiple = false, Inherited = false)] + public class RemovedNameValueAttribute : BaseExpectedLinkedBehaviorAttribute + { + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedPseudoAttributeAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedPseudoAttributeAttribute.cs new file mode 100644 index 00000000000000..00b4eb588eaf70 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedPseudoAttributeAttribute.cs @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Delegate | AttributeTargets.Interface | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event, AllowMultiple = true, Inherited = false)] + public class RemovedPseudoAttributeAttribute : BaseExpectedLinkedBehaviorAttribute + { + public RemovedPseudoAttributeAttribute (uint value) + { + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedResourceInAssemblyAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedResourceInAssemblyAttribute.cs new file mode 100644 index 00000000000000..5b793a034964d5 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedResourceInAssemblyAttribute.cs @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + /// + /// Verifies that an embedded resource was removed from an assembly + /// + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true, Inherited = false)] + public class RemovedResourceInAssemblyAttribute : BaseInAssemblyAttribute + { + public RemovedResourceInAssemblyAttribute (string assemblyFileName, string resourceName) + { + if (string.IsNullOrEmpty (assemblyFileName)) + throw new ArgumentNullException (nameof (assemblyFileName)); + + if (string.IsNullOrEmpty (resourceName)) + throw new ArgumentNullException (nameof (resourceName)); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedSymbolsAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedSymbolsAttribute.cs new file mode 100644 index 00000000000000..1549b8a03c9f17 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedSymbolsAttribute.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true, Inherited = false)] + public class RemovedSymbolsAttribute : BaseExpectedLinkedBehaviorAttribute + { + public RemovedSymbolsAttribute (string assemblyFileName) + { + if (string.IsNullOrEmpty (assemblyFileName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (assemblyFileName)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedTypeInAssemblyAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedTypeInAssemblyAttribute.cs new file mode 100644 index 00000000000000..079ba5d1f0b7d2 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/RemovedTypeInAssemblyAttribute.cs @@ -0,0 +1,27 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class | AttributeTargets.Delegate, AllowMultiple = true, Inherited = false)] + public class RemovedTypeInAssemblyAttribute : BaseInAssemblyAttribute + { + public RemovedTypeInAssemblyAttribute (string assemblyFileName, Type type) + { + if (type == null) + throw new ArgumentNullException (nameof (type)); + if (string.IsNullOrEmpty (assemblyFileName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (assemblyFileName)); + } + + public RemovedTypeInAssemblyAttribute (string assemblyFileName, string typeName) + { + if (string.IsNullOrEmpty (assemblyFileName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (assemblyFileName)); + if (string.IsNullOrEmpty (typeName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (typeName)); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipKeptItemsValidationAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipKeptItemsValidationAttribute.cs new file mode 100644 index 00000000000000..deb54564a8d0a5 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipKeptItemsValidationAttribute.cs @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = false)] + public class SkipKeptItemsValidationAttribute : BaseExpectedLinkedBehaviorAttribute + { + public SkipKeptItemsValidationAttribute () { } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipPeVerifyAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipPeVerifyAttribute.cs new file mode 100644 index 00000000000000..5b293eacdd349d --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipPeVerifyAttribute.cs @@ -0,0 +1,29 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + + public enum SkipPeVerifyForToolchian + { + Pedump + } + + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true)] + public class SkipPeVerifyAttribute : BaseExpectedLinkedBehaviorAttribute + { + public SkipPeVerifyAttribute () + { + } + + public SkipPeVerifyAttribute (SkipPeVerifyForToolchian toolchain) + { + } + + public SkipPeVerifyAttribute (string assemblyName) + { + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipRemainingErrorsValidationAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipRemainingErrorsValidationAttribute.cs new file mode 100644 index 00000000000000..09174ab0577d06 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/SkipRemainingErrorsValidationAttribute.cs @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = false)] + public class SkipRemainingErrorsValidationAttribute : BaseExpectedLinkedBehaviorAttribute + { + public SkipRemainingErrorsValidationAttribute () { } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/TestCaseRequirementsAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/TestCaseRequirementsAttribute.cs new file mode 100644 index 00000000000000..9e766c9ce05c67 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/TestCaseRequirementsAttribute.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class)] + public class TestCaseRequirementsAttribute : BaseExpectedLinkedBehaviorAttribute + { + public TestCaseRequirementsAttribute (TestRunCharacteristics targetFrameworkCharacteristics, string reason) + { + if (reason == null) + throw new ArgumentNullException (nameof (reason)); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/TestRunCharacteristics.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/TestRunCharacteristics.cs new file mode 100644 index 00000000000000..1e35a3dda0042d --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/TestRunCharacteristics.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [Flags] + public enum TestRunCharacteristics + { + TargetingNetFramework = 1, + TargetingNetCore = 2, + SupportsDefaultInterfaceMethods = 8, + SupportsStaticInterfaceMethods = 16, + TestFrameworkSupportsMcs = 32 + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/VerifyMetadataNamesAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/VerifyMetadataNamesAttribute.cs new file mode 100644 index 00000000000000..bf42f4da0545f4 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Assertions/VerifyMetadataNamesAttribute.cs @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Assertions +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = false, Inherited = false)] + public class VerifyMetadataNamesAttribute : BaseExpectedLinkedBehaviorAttribute + { + public VerifyMetadataNamesAttribute () + { + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Helpers/DataFlowStringExtensions.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Helpers/DataFlowStringExtensions.cs new file mode 100644 index 00000000000000..aa9c0b081f50a8 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Helpers/DataFlowStringExtensions.cs @@ -0,0 +1,42 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Diagnostics.CodeAnalysis; + +namespace Mono.Linker.Tests.Cases.Expectations.Helpers +{ + public static class DataFlowStringExtensions + { + public static void RequiresAll ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] this string str) { } + + public static void RequiresPublicConstructors ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] this string str) { } + + public static void RequiresPublicEvents ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)] this string str) { } + + public static void RequiresPublicFields ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] this string str) { } + + public static void RequiresPublicMethods ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] this string str) { } + + public static void RequiresPublicNestedTypes ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicNestedTypes)] this string str) { } + + public static void RequiresPublicParameterlessConstructor ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] this string str) { } + + public static void RequiresPublicProperties ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] this string str) { } + + public static void RequiresNonPublicEvents ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicEvents)] this string str) { } + + public static void RequiresNonPublicFields ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicFields)] this string str) { } + + public static void RequiresNonPublicMethods ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods)] this string str) { } + + public static void RequiresNonPublicNestedTypes ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] this string str) { } + + public static void RequiresNonPublicConstructors ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)] this string str) { } + + public static void RequiresNonPublicProperties ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicProperties)] this string str) { } + + public static void RequiresInterfaces ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.Interfaces)] this string str) { } + + public static void RequiresNone (this string str) { } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Helpers/DataFlowTypeExtensions.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Helpers/DataFlowTypeExtensions.cs new file mode 100644 index 00000000000000..e11f78abe89ad5 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Helpers/DataFlowTypeExtensions.cs @@ -0,0 +1,43 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Diagnostics.CodeAnalysis; + +namespace Mono.Linker.Tests.Cases.Expectations.Helpers +{ + public static class DataFlowTypeExtensions + { + public static void RequiresAll ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] this Type type) { } + + public static void RequiresPublicConstructors ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] this Type type) { } + + public static void RequiresPublicEvents ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)] this Type type) { } + + public static void RequiresPublicFields ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] this Type type) { } + + public static void RequiresPublicMethods ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] this Type type) { } + + public static void RequiresPublicNestedTypes ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicNestedTypes)] this Type type) { } + + public static void RequiresPublicParameterlessConstructor ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] this Type type) { } + + public static void RequiresPublicProperties ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] this Type type) { } + + public static void RequiresNonPublicEvents ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicEvents)] this Type type) { } + + public static void RequiresNonPublicFields ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicFields)] this Type type) { } + + public static void RequiresNonPublicMethods ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods)] this Type type) { } + + public static void RequiresNonPublicNestedTypes ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] this Type type) { } + + public static void RequiresNonPublicConstructors ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)] this Type type) { } + + public static void RequiresNonPublicProperties ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicProperties)] this Type type) { } + + public static void RequiresInterfaces ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.Interfaces)] this Type type) { } + + public static void RequiresNone (this Type type) { } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Helpers/PlatformAssemblies.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Helpers/PlatformAssemblies.cs new file mode 100644 index 00000000000000..c2e77e98f8d445 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Helpers/PlatformAssemblies.cs @@ -0,0 +1,14 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Mono.Linker.Tests.Cases.Expectations.Helpers +{ + public static class PlatformAssemblies + { +#if NETCOREAPP + public const string CoreLib = "System.Private.CoreLib.dll"; +#else + public const string CoreLib = "mscorlib.dll"; +#endif + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/BaseMetadataAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/BaseMetadataAttribute.cs new file mode 100644 index 00000000000000..d29e0a0ec6fadf --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/BaseMetadataAttribute.cs @@ -0,0 +1,13 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Diagnostics; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + [Conditional ("INCLUDE_EXPECTATIONS")] + public abstract class BaseMetadataAttribute : Attribute + { + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/DefineAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/DefineAttribute.cs new file mode 100644 index 00000000000000..f0e34d1e68b4a9 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/DefineAttribute.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true)] + public class DefineAttribute : BaseMetadataAttribute + { + public DefineAttribute (string name) + { + if (string.IsNullOrEmpty (name)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (name)); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/IgnoreDescriptorsAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/IgnoreDescriptorsAttribute.cs new file mode 100644 index 00000000000000..ef1656e564c008 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/IgnoreDescriptorsAttribute.cs @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + public sealed class IgnoreDescriptorsAttribute : BaseMetadataAttribute + { + public readonly bool Value; + + public IgnoreDescriptorsAttribute (bool value) + { + Value = value; + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/IgnoreLinkAttributesAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/IgnoreLinkAttributesAttribute.cs new file mode 100644 index 00000000000000..0679c0f52d868e --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/IgnoreLinkAttributesAttribute.cs @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + public sealed class IgnoreLinkAttributesAttribute : BaseMetadataAttribute + { + public readonly bool Value; + + public IgnoreLinkAttributesAttribute (bool value) + { + Value = value; + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/IgnoreSubstitutionsAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/IgnoreSubstitutionsAttribute.cs new file mode 100644 index 00000000000000..613e9d8a908f7e --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/IgnoreSubstitutionsAttribute.cs @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + public sealed class IgnoreSubstitutionsAttribute : BaseMetadataAttribute + { + public readonly bool Value; + + public IgnoreSubstitutionsAttribute (bool value) + { + Value = value; + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/Il8nAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/Il8nAttribute.cs new file mode 100644 index 00000000000000..d79cdb37f1c2f8 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/Il8nAttribute.cs @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + [AttributeUsage (AttributeTargets.Class)] + public sealed class Il8nAttribute : BaseMetadataAttribute + { + public readonly string Value; + + public Il8nAttribute (string value) + { + Value = value; + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/KeepTypeForwarderOnlyAssembliesAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/KeepTypeForwarderOnlyAssembliesAttribute.cs new file mode 100644 index 00000000000000..e386d350248254 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/KeepTypeForwarderOnlyAssembliesAttribute.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + [AttributeUsage (AttributeTargets.Class)] + public sealed class KeepTypeForwarderOnlyAssembliesAttribute : BaseMetadataAttribute + { + public KeepTypeForwarderOnlyAssembliesAttribute (string value) + { + if (string.IsNullOrEmpty (value)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (value)); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/NotATestCaseAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/NotATestCaseAttribute.cs new file mode 100644 index 00000000000000..a099ee6301a4b5 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/NotATestCaseAttribute.cs @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + [AttributeUsage (AttributeTargets.Class | AttributeTargets.Struct)] + public class NotATestCaseAttribute : BaseMetadataAttribute + { + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/ReferenceAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/ReferenceAttribute.cs new file mode 100644 index 00000000000000..a704ea414e8231 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/ReferenceAttribute.cs @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true)] + public class ReferenceAttribute : BaseMetadataAttribute + { + + public ReferenceAttribute (string value) + { + if (string.IsNullOrEmpty (value)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (value)); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/ReferenceDependencyAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/ReferenceDependencyAttribute.cs new file mode 100644 index 00000000000000..c038fe43f75048 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/ReferenceDependencyAttribute.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true)] + public class ReferenceDependencyAttribute : BaseMetadataAttribute + { + public ReferenceDependencyAttribute (string value) + { + if (string.IsNullOrEmpty (value)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (value)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SandboxDependencyAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SandboxDependencyAttribute.cs new file mode 100644 index 00000000000000..dce29bd3170bbc --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SandboxDependencyAttribute.cs @@ -0,0 +1,24 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true)] + public class SandboxDependencyAttribute : BaseMetadataAttribute + { + + public SandboxDependencyAttribute (string relativePathToFile, string destinationFileName = null) + { + if (string.IsNullOrEmpty (relativePathToFile)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (relativePathToFile)); + } + + public SandboxDependencyAttribute (Type typeOfSourceFileToInclude, string destinationFileName = null) + { + if (typeOfSourceFileToInclude == null) + throw new ArgumentException ("Value cannot be null or empty.", nameof (typeOfSourceFileToInclude)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCSharpCompilerToUseAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCSharpCompilerToUseAttribute.cs new file mode 100644 index 00000000000000..277834153aaf9b --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCSharpCompilerToUseAttribute.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = false)] + public class SetupCSharpCompilerToUseAttribute : BaseMetadataAttribute + { + public SetupCSharpCompilerToUseAttribute (string name) + { + if (string.IsNullOrEmpty (name)) + throw new ArgumentNullException (nameof (name)); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileAfterAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileAfterAttribute.cs new file mode 100644 index 00000000000000..71f9f7a3854bb5 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileAfterAttribute.cs @@ -0,0 +1,36 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + /// + /// Use to compile an assembly after compiling the main test case executabe + /// + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true)] + public class SetupCompileAfterAttribute : BaseMetadataAttribute + { + public SetupCompileAfterAttribute (string outputName, string[] sourceFiles, string[] references = null, string[] defines = null, object[] resources = null, string additionalArguments = null, string compilerToUse = null, bool addAsReference = true, bool removeFromLinkerInput = false) + { + if (sourceFiles == null) + throw new ArgumentNullException (nameof (sourceFiles)); + + if (string.IsNullOrEmpty (outputName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (outputName)); + + if (resources != null) { + foreach (var res in resources) { + if (res is string) + continue; + if (res is string[] stringArray) { + if (stringArray.Length != 2) + throw new ArgumentException ("Entry in object[] cannot be a string[] unless it has exactly two elements, for the resource path and name", nameof (resources)); + continue; + } + throw new ArgumentException ("Each value in the object[] must be a string or a string[], either a resource path, or a path and name", nameof (resources)); + } + } + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileArgumentAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileArgumentAttribute.cs new file mode 100644 index 00000000000000..67020707d814de --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileArgumentAttribute.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true)] + public class SetupCompileArgumentAttribute : BaseMetadataAttribute + { + public SetupCompileArgumentAttribute (string value) + { + if (string.IsNullOrEmpty (value)) + throw new ArgumentNullException (nameof (value)); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileAsLibraryAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileAsLibraryAttribute.cs new file mode 100644 index 00000000000000..e78aaa089bcc3c --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileAsLibraryAttribute.cs @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = false)] + public class SetupCompileAsLibraryAttribute : BaseMetadataAttribute + { + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileAssemblyNameAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileAssemblyNameAttribute.cs new file mode 100644 index 00000000000000..7fad90431149d6 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileAssemblyNameAttribute.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = false)] + public class SetupCompileAssemblyNameAttribute : BaseMetadataAttribute + { + public SetupCompileAssemblyNameAttribute (string outputName) + { + if (string.IsNullOrEmpty (outputName)) + throw new ArgumentNullException (nameof (outputName)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileBeforeAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileBeforeAttribute.cs new file mode 100644 index 00000000000000..0021300c8403ec --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileBeforeAttribute.cs @@ -0,0 +1,58 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + /// + /// Use to compile an assembly before compiling the main test case executabe + /// + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true)] + public class SetupCompileBeforeAttribute : BaseMetadataAttribute + { + public SetupCompileBeforeAttribute (string outputName, string[] sourceFiles, string[] references = null, string[] defines = null, object[] resources = null, string additionalArguments = null, string compilerToUse = null, bool addAsReference = true, bool removeFromLinkerInput = false, string outputSubFolder = null) + { + if (sourceFiles == null) + throw new ArgumentNullException (nameof (sourceFiles)); + + if (string.IsNullOrEmpty (outputName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (outputName)); + + if (resources != null) { + foreach (var res in resources) { + if (res is string) + continue; + if (res is string[] stringArray) { + if (stringArray.Length != 2) + throw new ArgumentException ("Entry in object[] cannot be a string[] unless it has exactly two elements, for the resource path and name", nameof (resources)); + continue; + } + throw new ArgumentException ("Each value in the object[] must be a string or a string[], either a resource path, or a path and name", nameof (resources)); + } + } + } + + public SetupCompileBeforeAttribute (string outputName, Type[] typesToIncludeSourceFor, string[] references = null, string[] defines = null, object[] resources = null, string additionalArguments = null, string compilerToUse = null, bool addAsReference = true, bool removeFromLinkerInput = false) + { + if (typesToIncludeSourceFor == null) + throw new ArgumentNullException (nameof (typesToIncludeSourceFor)); + + if (string.IsNullOrEmpty (outputName)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (outputName)); + + if (resources != null) { + foreach (var res in resources) { + if (res is string) + continue; + if (res is string[] stringArray) { + if (stringArray.Length != 2) + throw new ArgumentException ("Entry in object[] cannot be a string[] unless it has exactly two elements, for the resource path and name", nameof (resources)); + continue; + } + throw new ArgumentException ("Each value in the object[] must be a string or a string[], either a resource path, or a path and name", nameof (resources)); + } + } + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileResourceAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileResourceAttribute.cs new file mode 100644 index 00000000000000..83a7f11c57e618 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupCompileResourceAttribute.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true)] + public class SetupCompileResourceAttribute : BaseMetadataAttribute + { + public SetupCompileResourceAttribute (string relativePathToFile, string destinationFileName = null) + { + if (string.IsNullOrEmpty (relativePathToFile)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (relativePathToFile)); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkAttributesFile.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkAttributesFile.cs new file mode 100644 index 00000000000000..1c55f9946e658e --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkAttributesFile.cs @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true)] + public class SetupLinkAttributesFile : BaseMetadataAttribute + { + public SetupLinkAttributesFile (string relativePathToFile, string destinationFileName = null) + { + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerActionAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerActionAttribute.cs new file mode 100644 index 00000000000000..bc78fc9346ff7f --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerActionAttribute.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true)] + public class SetupLinkerActionAttribute : BaseMetadataAttribute + { + public SetupLinkerActionAttribute (string action, string assembly) + { + if (string.IsNullOrEmpty (action)) + throw new ArgumentNullException (nameof (action)); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerArgumentAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerArgumentAttribute.cs new file mode 100644 index 00000000000000..6f2e55f24bba27 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerArgumentAttribute.cs @@ -0,0 +1,24 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + + /// + /// Used to define arguments to pass to the linker. + /// + /// Don't use this attribute to setup single character flags. These flags do a poor job of communicating their purpose + /// and although we need to continue to support the usages that exist today, that doesn't mean we need to make our tests harder to read + /// + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true)] + public class SetupLinkerArgumentAttribute : BaseMetadataAttribute + { + public SetupLinkerArgumentAttribute (string flag, params string[] values) + { + if (string.IsNullOrEmpty (flag)) + throw new ArgumentNullException (nameof (flag)); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerDefaultActionAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerDefaultActionAttribute.cs new file mode 100644 index 00000000000000..ee9794d495f98c --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerDefaultActionAttribute.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = false)] + public class SetupLinkerDefaultActionAttribute : BaseMetadataAttribute + { + public SetupLinkerDefaultActionAttribute (string action) + { + if (string.IsNullOrEmpty (action)) + throw new ArgumentNullException (nameof (action)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerDescriptorFile.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerDescriptorFile.cs new file mode 100644 index 00000000000000..e1c7c4501dc150 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerDescriptorFile.cs @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true)] + public class SetupLinkerDescriptorFile : BaseMetadataAttribute + { + public SetupLinkerDescriptorFile (string relativePathToFile, string destinationFileName = null) + { + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerKeepDebugMembersAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerKeepDebugMembersAttribute.cs new file mode 100644 index 00000000000000..2213b9cc551c79 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerKeepDebugMembersAttribute.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + [AttributeUsage (AttributeTargets.Class)] + public class SetupLinkerKeepDebugMembersAttribute : BaseMetadataAttribute + { + public SetupLinkerKeepDebugMembersAttribute (string value) + { + if (string.IsNullOrEmpty (value)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (value)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerLinkPublicAndFamilyAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerLinkPublicAndFamilyAttribute.cs new file mode 100644 index 00000000000000..c4250b82e231da --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerLinkPublicAndFamilyAttribute.cs @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = false)] + public class SetupLinkerLinkPublicAndFamilyAttribute : BaseMetadataAttribute + { + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerLinkSymbolsAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerLinkSymbolsAttribute.cs new file mode 100644 index 00000000000000..5aa97e2ca05e2f --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerLinkSymbolsAttribute.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + [AttributeUsage (AttributeTargets.Class)] + public class SetupLinkerLinkSymbolsAttribute : BaseMetadataAttribute + { + public SetupLinkerLinkSymbolsAttribute (string value) + { + if (string.IsNullOrEmpty (value)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (value)); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerResponseFileAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerResponseFileAttribute.cs new file mode 100644 index 00000000000000..28c30f868bcda3 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerResponseFileAttribute.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true)] + public class SetupLinkerResponseFileAttribute : BaseMetadataAttribute + { + public SetupLinkerResponseFileAttribute (string relativePathToFile, string destinationFileName = null) + { + if (string.IsNullOrEmpty (relativePathToFile)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (relativePathToFile)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerSubstitutionFileAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerSubstitutionFileAttribute.cs new file mode 100644 index 00000000000000..6a102a830fa163 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerSubstitutionFileAttribute.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = true)] + public class SetupLinkerSubstitutionFileAttribute : BaseMetadataAttribute + { + public SetupLinkerSubstitutionFileAttribute (string relativePathToFile, string destinationFileName = null) + { + if (string.IsNullOrEmpty (relativePathToFile)) + throw new ArgumentException ("Value cannot be null or empty.", nameof (relativePathToFile)); + } + } +} \ No newline at end of file diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerTrimModeAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerTrimModeAttribute.cs new file mode 100644 index 00000000000000..e303447291f566 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SetupLinkerTrimModeAttribute.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + [AttributeUsage (AttributeTargets.Class, AllowMultiple = false)] + public class SetupLinkerTrimModeAttribute : BaseMetadataAttribute + { + public SetupLinkerTrimModeAttribute (string action) + { + if (string.IsNullOrEmpty (action)) + throw new ArgumentNullException (nameof (action)); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SkipUnresolvedAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SkipUnresolvedAttribute.cs new file mode 100644 index 00000000000000..37fbce0e04cf13 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/SkipUnresolvedAttribute.cs @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + public sealed class SkipUnresolvedAttribute : BaseMetadataAttribute + { + public readonly bool Value; + + public SkipUnresolvedAttribute (bool value) + { + Value = value; + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/StripDescriptorsAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/StripDescriptorsAttribute.cs new file mode 100644 index 00000000000000..704d01971f3d58 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/StripDescriptorsAttribute.cs @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + public sealed class StripDescriptorsAttribute : BaseMetadataAttribute + { + public readonly bool Value; + + public StripDescriptorsAttribute (bool value) + { + Value = value; + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/StripLinkAttributesAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/StripLinkAttributesAttribute.cs new file mode 100644 index 00000000000000..4f2380fb938848 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/StripLinkAttributesAttribute.cs @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + public sealed class StripLinkAttributesAttribute : BaseMetadataAttribute + { + public readonly bool Value; + + public StripLinkAttributesAttribute (bool value) + { + Value = value; + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/StripSubstitutionsAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/StripSubstitutionsAttribute.cs new file mode 100644 index 00000000000000..1f0732216640f5 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Metadata/StripSubstitutionsAttribute.cs @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Mono.Linker.Tests.Cases.Expectations.Metadata +{ + public sealed class StripSubstitutionsAttribute : BaseMetadataAttribute + { + public readonly bool Value; + + public StripSubstitutionsAttribute (bool value) + { + Value = value; + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Mono.Linker.Tests.Cases.Expectations.csproj b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Mono.Linker.Tests.Cases.Expectations.csproj new file mode 100644 index 00000000000000..14a94ab30bf27c --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Mono.Linker.Tests.Cases.Expectations.csproj @@ -0,0 +1,10 @@ + + + + $(NetCoreAppToolCurrent) + disable + x64;x86 + AnyCPU + + + diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Support/IntrinsicAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Support/IntrinsicAttribute.cs new file mode 100644 index 00000000000000..4c2153dbff35e2 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Support/IntrinsicAttribute.cs @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace System.Runtime.CompilerServices +{ + // This attribute is normally implemented in CoreLib as internal, but in order to test + // linker behavior around it, we need to be able to use it in the tests. + [AttributeUsage (AttributeTargets.Method)] + public sealed class IntrinsicAttribute : Attribute + { + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Support/RemoveAttributeInstancesAttribute.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Support/RemoveAttributeInstancesAttribute.cs new file mode 100644 index 00000000000000..e2eb936d545f85 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases.Expectations/Support/RemoveAttributeInstancesAttribute.cs @@ -0,0 +1,17 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker +{ + /// + /// This attribute name will be the name hardcoded in linker which will remove all + /// attribute usages but not the attribute definition + /// + [AttributeUsage ( + AttributeTargets.Class, Inherited = false)] + public sealed class RemoveAttributeInstancesAttribute : Attribute + { + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/AssemblyQualifiedNameDataflow.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/AssemblyQualifiedNameDataflow.cs new file mode 100644 index 00000000000000..e2df9679801a43 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/AssemblyQualifiedNameDataflow.cs @@ -0,0 +1,163 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text; +using Mono.Linker.Tests.Cases.Expectations.Assertions; + +namespace Mono.Linker.Tests.Cases.DataFlow +{ + // Note: this test's goal is to validate that the product correctly reports unrecognized patterns + // - so the main validation is done by the ExpectedWarning attributes. + [SkipKeptItemsValidation] + [ExpectedNoWarnings] + class AssemblyQualifiedNameDataflow + { + static void Main () + { + TestPublicParameterlessConstructor (); + TestPublicConstructors (); + TestConstructors (); + TestUnqualifiedTypeNameWarns (); + TestNull (); + TestMultipleValues (); + TestUnknownValue (); + TestNoValue (); + TestObjectGetTypeValue (); + } + + [ExpectedWarning ("IL2072", nameof (RequirePublicConstructors))] + [ExpectedWarning ("IL2072", nameof (RequireNonPublicConstructors))] + static void TestPublicParameterlessConstructor () + { + string type = GetTypeWithPublicParameterlessConstructor ().AssemblyQualifiedName; + RequirePublicParameterlessConstructor (type); + RequirePublicConstructors (type); + RequireNonPublicConstructors (type); + RequireNothing (type); + } + + [ExpectedWarning ("IL2072", nameof (RequireNonPublicConstructors))] + static void TestPublicConstructors () + { + string type = GetTypeWithPublicConstructors ().AssemblyQualifiedName; + RequirePublicParameterlessConstructor (type); + RequirePublicConstructors (type); + RequireNonPublicConstructors (type); + RequireNothing (type); + } + + [ExpectedWarning ("IL2072", nameof (RequirePublicParameterlessConstructor))] + [ExpectedWarning ("IL2072", nameof (RequirePublicConstructors))] + static void TestConstructors () + { + string type = GetTypeWithNonPublicConstructors ().AssemblyQualifiedName; + RequirePublicParameterlessConstructor (type); + RequirePublicConstructors (type); + RequireNonPublicConstructors (type); + RequireNothing (type); + } + + [ExpectedWarning ("IL2105", + "Type 'System.Invalid.TypeName' was not found in the caller assembly nor in the base library. " + + "Type name strings used for dynamically accessing a type should be assembly qualified.", + ProducedBy = ProducedBy.Trimmer)] + static void TestUnqualifiedTypeNameWarns () + { + RequirePublicConstructors ("System.Invalid.TypeName"); + } + + static void TestNull () + { + Type type = null; + RequirePublicConstructors (type.AssemblyQualifiedName); // Null should not warn - we know it's going to fail at runtime + } + + [ExpectedWarning ("IL2072", nameof (RequirePublicConstructors), nameof (GetTypeWithNonPublicConstructors))] + [ExpectedWarning ("IL2062", nameof (RequirePublicConstructors))] + static void TestMultipleValues (int p = 0, object[] o = null) + { + Type type = p switch { + 0 => GetTypeWithPublicConstructors (), + 1 => GetTypeWithNonPublicConstructors (), // Should produce warning IL2072 due to mismatch annotation + 2 => null, // Should be ignored + _ => (Type) o[0] // This creates an unknown value - should produce warning IL2062 + }; + + RequirePublicConstructors (type.AssemblyQualifiedName); + } + + [ExpectedWarning ("IL2062", nameof (RequirePublicConstructors))] + static void TestUnknownValue (object[] o = null) + { + string unknown = ((Type) o[0]).AssemblyQualifiedName; + RequirePublicConstructors (unknown); + RequireNothing (unknown); // shouldn't warn + } + + static void TestNoValue () + { + Type t = null; + Type noValue = Type.GetTypeFromHandle (t.TypeHandle); + // t.TypeHandle throws at runtime so don't warn here. + RequirePublicConstructors (noValue.AssemblyQualifiedName); + } + + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] + class AnnotatedType + { + } + + static void TestObjectGetTypeValue (AnnotatedType instance = null) + { + string type = instance.GetType ().AssemblyQualifiedName; + // Currently Object.GetType is unimplemented in the analyzer, but + // this still shouldn't warn. + RequirePublicConstructors (type); + RequireNothing (type); + } + + private static void RequirePublicParameterlessConstructor ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + string type) + { + } + + private static void RequirePublicConstructors ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] + string type) + { + } + + private static void RequireNonPublicConstructors ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] + string type) + { + } + + private static void RequireNothing (string type) + { + } + + + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + private static Type GetTypeWithPublicParameterlessConstructor () + { + return null; + } + + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] + private static Type GetTypeWithPublicConstructors () + { + return null; + } + + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)] + private static Type GetTypeWithNonPublicConstructors () + { + return null; + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/EmptyArrayIntrinsicsDataFlow.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/EmptyArrayIntrinsicsDataFlow.cs new file mode 100644 index 00000000000000..268466a3b427d0 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/EmptyArrayIntrinsicsDataFlow.cs @@ -0,0 +1,60 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Reflection; +using System.Text; +using Mono.Linker.Tests.Cases.Expectations.Assertions; + +namespace Mono.Linker.Tests.Cases.DataFlow +{ + // Note: this test's goal is to validate that the product correctly reports unrecognized patterns + // - so the main validation is done by the ExpectedWarning attributes. + [SkipKeptItemsValidation] + [ExpectedNoWarnings] + class EmptyArrayIntrinsicsDataFlow + { + static void Main () + { + TestGetPublicParameterlessConstructorWithEmptyTypes (); + TestGetPublicParameterlessConstructorWithArrayEmpty (); + TestGetPublicParameterlessConstructorWithUnknownArray (); + TestGetConstructorOverloads (); + } + + [ExpectedWarning ("IL2080", nameof (Type.GetMethod))] + static void TestGetPublicParameterlessConstructorWithEmptyTypes () + { + s_typeWithKeptPublicParameterlessConstructor.GetConstructor (Type.EmptyTypes); + s_typeWithKeptPublicParameterlessConstructor.GetMethod ("Foo"); + } + + [ExpectedWarning ("IL2080", nameof (Type.GetMethod))] + static void TestGetPublicParameterlessConstructorWithArrayEmpty () + { + s_typeWithKeptPublicParameterlessConstructor.GetConstructor (Array.Empty ()); + s_typeWithKeptPublicParameterlessConstructor.GetMethod ("Foo"); + } + + [ExpectedWarning ("IL2080", nameof (Type.GetConstructor))] + static void TestGetPublicParameterlessConstructorWithUnknownArray () + { + s_typeWithKeptPublicParameterlessConstructor.GetConstructor (s_localEmptyArrayInvisibleToAnalysis); + } + + [ExpectedWarning ("IL2080", nameof (Type.GetMethod))] + static void TestGetConstructorOverloads () + { + s_typeWithKeptPublicParameterlessConstructor.GetConstructor (BindingFlags.Public, null, Type.EmptyTypes, null); + s_typeWithKeptPublicParameterlessConstructor.GetConstructor (BindingFlags.Public, null, CallingConventions.Any, Type.EmptyTypes, null); + s_typeWithKeptPublicParameterlessConstructor.GetMethod ("Foo"); + } + + static Type[] s_localEmptyArrayInvisibleToAnalysis = Type.EmptyTypes; + + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + static Type s_typeWithKeptPublicParameterlessConstructor = typeof (EmptyArrayIntrinsicsDataFlow); + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/GetInterfaceDataFlow.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/GetInterfaceDataFlow.cs new file mode 100644 index 00000000000000..a369157dbbc826 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/GetInterfaceDataFlow.cs @@ -0,0 +1,198 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; + +namespace Mono.Linker.Tests.Cases.DataFlow +{ + [SkipKeptItemsValidation] + [ExpectedNoWarnings] + public class GetInterfaceDataFlow + { + public static void Main () + { + GetInterface_Name.Test (); + GetInterface_Name_IgnoreCase.Test (); + } + + class GetInterface_Name + { + static void TestNullName (Type type) + { + type.GetInterface (null); + } + + static void TestEmptyName (Type type) + { + type.GetInterface (string.Empty); + } + + static void TestNoValueName (Type type) + { + Type t = null; + string noValue = t.AssemblyQualifiedName; + type.GetInterface (noValue); + } + + [ExpectedWarning ("IL2070", nameof (Type.GetInterface), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.Interfaces))] + static void TestNoAnnotation (Type type) + { + type.GetInterface ("ITestInterface"); + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestWithAnnotation ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.Interfaces)] Type type) + { + type.GetInterface ("ITestInterface").RequiresInterfaces (); + type.GetInterface ("ITestInterface").RequiresAll (); // Warns + } + + static void TestWithAll ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type type) + { + type.GetInterface ("ITestInterface").RequiresInterfaces (); + type.GetInterface ("ITestInterface").RequiresAll (); + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestKnownType () + { + // Interfaces marking is transitive - meaning that it marks all interfaces in the entire hierarchy + // so the return value of GetInterface always has all interfaces on it already. + typeof (TestType).GetInterface ("ITestInterface").RequiresInterfaces (); + typeof (TestType).GetInterface ("ITestInterface").RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestMultipleValues (int p, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type typeWithAll) + { + Type type; + if (p == 0) + type = typeof (TestType); + else + type = typeWithAll; + + type.GetInterface ("ITestInterface").RequiresInterfaces (); + type.GetInterface ("ITestInterface").RequiresAll (); // Warns since only one of the values is guaranteed All + } + + [ExpectedWarning ("IL2075", nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.Interfaces))] + static void TestMergedValues (int p, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type typeWithAll) + { + Type type = new TestType ().GetType (); + if (p == 0) { + type = typeWithAll; + } + + type.GetInterface ("ITestInterface").RequiresInterfaces (); + } + + static void TestNullValue () + { + Type t = null; + t.GetInterface ("ITestInterface").RequiresInterfaces (); + } + + static void TestNoValue () + { + Type t = null; + Type noValue = Type.GetTypeFromHandle (t.TypeHandle); + // t.TypeHandle throws at runtime so don't warn here. + noValue.GetInterface ("ITestInterface").RequiresInterfaces (); + } + + class GetInterfaceInCtor + { + public GetInterfaceInCtor ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.Interfaces)] Type type) + { + type.GetInterface ("ITestInterface").RequiresInterfaces (); + } + } + + public static void Test () + { + TestNullName (typeof (TestType)); + TestEmptyName (typeof (TestType)); + TestNoValueName (typeof (TestType)); + TestNoAnnotation (typeof (TestType)); + TestWithAnnotation (typeof (TestType)); + TestWithAnnotation (typeof (ITestInterface)); + TestWithAll (typeof (TestType)); + TestKnownType (); + TestMultipleValues (0, typeof (TestType)); + TestMergedValues (0, typeof (TestType)); + TestNullValue (); + TestNoValue (); + var _ = new GetInterfaceInCtor (typeof (TestType)); + } + } + + class GetInterface_Name_IgnoreCase + { + [ExpectedWarning ("IL2070", nameof (Type.GetInterface), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.Interfaces))] + static void TestNoAnnotation (Type type) + { + type.GetInterface ("ITestInterface", false); + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestWithAnnotation ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.Interfaces)] Type type) + { + type.GetInterface ("ITestInterface", false).RequiresInterfaces (); + type.GetInterface ("ITestInterface", false).RequiresAll (); // Warns + } + + static void TestWithAll ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type type) + { + type.GetInterface ("ITestInterface", false).RequiresInterfaces (); + type.GetInterface ("ITestInterface", false).RequiresAll (); + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestKnownType () + { + // Interfaces marking is transitive - meaning that it marks all interfaces in the entire hierarchy + // so the return value of GetInterface always has all interfaces on it already. + typeof (TestType).GetInterface ("ITestInterface", false).RequiresInterfaces (); + typeof (TestType).GetInterface ("ITestInterface", false).RequiresAll (); + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestMultipleValues (int p, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type typeWithAll) + { + Type type; + if (p == 0) + type = typeof (TestType); + else + type = typeWithAll; + + type.GetInterface ("ITestInterface", false).RequiresInterfaces (); + type.GetInterface ("ITestInterface", false).RequiresAll (); // Warns since only one of the values is guaranteed All + } + + public static void Test () + { + TestNoAnnotation (typeof (TestType)); + TestWithAnnotation (typeof (TestType)); + TestWithAnnotation (typeof (ITestInterface)); + TestWithAll (typeof (TestType)); + TestKnownType (); + TestMultipleValues (0, typeof (TestType)); + } + } + + interface ITestInterface + { + } + + class TestType : ITestInterface + { + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/GetNestedTypeOnAllAnnotatedType.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/GetNestedTypeOnAllAnnotatedType.cs new file mode 100644 index 00000000000000..d8f14b71eb70f0 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/GetNestedTypeOnAllAnnotatedType.cs @@ -0,0 +1,141 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; + +namespace Mono.Linker.Tests.Cases.DataFlow +{ + [ExpectedNoWarnings] + [SkipKeptItemsValidation] + class GetNestedTypeOnAllAnnotatedType + { + static void Main () + { + TestOnAllAnnotatedParameter (typeof (TestType)); + TestOnNonAllAnnotatedParameter (typeof (TestType)); + TestWithBindingFlags (typeof (TestType)); + TestWithUnknownBindingFlags (BindingFlags.Public, typeof (TestType)); + TestUnsupportedBindingFlags (typeof (TestType)); + TestWithNull (); + TestWithEmptyInput (); + TestIfElse (1, typeof (TestType), typeof (TestType)); + TestSwitchAllValid (1, typeof (TestType)); + TestOnKnownTypeOnly (); + TestOnKnownTypeWithNullName (); + TestOnKnownTypeWithUnknownName ("noname"); + TestWithKnownTypeAndNameWhichDoesntExist (); + } + + static void TestOnAllAnnotatedParameter ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type parentType) + { + var nestedType = parentType.GetNestedType (nameof (TestType.NestedType)); + nestedType.RequiresAll (); + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresAll))] + static void TestOnNonAllAnnotatedParameter ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicNestedTypes)] Type parentType) + { + var nestedType = parentType.GetNestedType (nameof (TestType.NestedType)); + nestedType.RequiresAll (); + } + + static void TestWithBindingFlags ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type parentType) + { + var nestedType = parentType.GetNestedType (nameof (TestType.NestedType), BindingFlags.Public); + nestedType.RequiresAll (); + } + + static void TestWithUnknownBindingFlags (BindingFlags bindingFlags, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type parentType) + { + var nestedType = parentType.GetNestedType (nameof (TestType.NestedType), bindingFlags); + nestedType.RequiresAll (); + } + + static void TestUnsupportedBindingFlags ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type parentType) + { + var nestedType = parentType.GetNestedType (nameof (TestType.NestedType), BindingFlags.IgnoreCase); + nestedType.RequiresAll (); + } + + static void TestWithNull () + { + Type parentType = null; + var nestedType = parentType.GetNestedType (nameof (TestType.NestedType)); + nestedType.RequiresAll (); + } + + static void TestWithEmptyInput () + { + Type t = null; + Type noValue = Type.GetTypeFromHandle (t.TypeHandle); // Throws at runtime -> tracked as empty value set + noValue.GetNestedType (nameof (TestType.NestedType)).RequiresAll (); // No warning - empty input + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresAll))] + static void TestIfElse (int number, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type parentWithAll, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicNestedTypes)] Type parentWithoutAll) + { + Type typeOfParent; + if (number == 1) { + typeOfParent = parentWithAll; + } else { + typeOfParent = parentWithoutAll; + } + var nestedType = typeOfParent.GetNestedType (nameof (TestType.NestedType)); + nestedType.RequiresAll (); + } + + static void TestSwitchAllValid (int number, [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type parentWithAll) + { + Type typeOfParent = number switch { + 1 => parentWithAll, + 2 => null, + 3 => typeof (TestType) + }; + + var nestedType = typeOfParent.GetNestedType (nameof (TestType.NestedType)); + nestedType.RequiresAll (); + } + + static void TestOnKnownTypeOnly () + { + typeof (TestType).GetNestedType (nameof (TestType.NestedType)).RequiresAll (); + } + + static void TestOnKnownTypeWithNullName () + { + typeof (TestType).GetNestedType (null).RequiresAll (); + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresAll))] + static void TestOnKnownTypeWithUnknownName (string name) + { + // WARN - we will preserve the nested type, but not as a whole, just the type itself, so it can't fullfil the All annotation + typeof (TestType).GetNestedType (name).RequiresAll (); + } + + static void TestWithKnownTypeAndNameWhichDoesntExist () + { + // Should not warn since we can statically determine that GetNestedType will return null so there's no problem with trimming + typeof (TestType).GetNestedType ("NonExisting").RequiresAll (); + } + + class TestType + { + public class NestedType + { + NestedType () { } + public static int PublicStaticInt; + public void Method () { } + int Prop { get; set; } + } + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/GetTypeDataFlow.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/GetTypeDataFlow.cs new file mode 100644 index 00000000000000..ef58eac310f4f5 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/GetTypeDataFlow.cs @@ -0,0 +1,220 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Text; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; + +namespace Mono.Linker.Tests.Cases.DataFlow +{ + // Note: this test's goal is to validate that the product correctly reports unrecognized patterns + // - so the main validation is done by the ExpectedWarning attributes. + [SkipKeptItemsValidation] + [ExpectedNoWarnings] + public class GetTypeDataFlow + { + public static void Main () + { + TestPublicParameterlessConstructor (); + TestPublicConstructors (); + TestConstructors (); + TestNull (); + TestNoValue (); + TestUnknownType (); + + TestTypeNameFromParameter (null); + TestTypeNameFromField (); + + TestMultipleConstantValues (); + TestMultipleMixedValues (); + + TestStringEmpty (); + + TypeWithWarnings.Test (); + OverConstTypeName.Test (); + + // TODO: + // Test multi-value returns + // Type.GetType over a constant and a param + // Type.GetType over two params + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors))] + static void TestPublicParameterlessConstructor () + { + Type type = Type.GetType (GetStringTypeWithPublicParameterlessConstructor ()); + type.RequiresPublicParameterlessConstructor (); + type.RequiresPublicConstructors (); + type.RequiresNonPublicConstructors (); + type.RequiresNone (); + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors))] + static void TestPublicConstructors () + { + Type type = Type.GetType (GetStringTypeWithPublicConstructors ()); + type.RequiresPublicParameterlessConstructor (); + type.RequiresPublicConstructors (); + type.RequiresNonPublicConstructors (); + type.RequiresNone (); + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresPublicParameterlessConstructor))] + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] + static void TestConstructors () + { + Type type = Type.GetType (GetStringTypeWithNonPublicConstructors ()); + type.RequiresPublicParameterlessConstructor (); + type.RequiresPublicConstructors (); + type.RequiresNonPublicConstructors (); + type.RequiresNone (); + } + + static void TestNull () + { + // GetType(null) throws at runtime, so we "give up" on analysis + Type.GetType (null).RequiresAll (); + } + + static void TestNoValue () + { + Type t = null; + // null.AssemblyQualifiedName throws at runtime, so we "give up" on analysis + string noValue = t.AssemblyQualifiedName; + Type.GetType (noValue).RequiresAll (); + } + + [ExpectedWarning ("IL2057", nameof (GetType))] + static void TestUnknownType () + { + Type type = Type.GetType (GetStringUnkownType ()); + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] + static void TestTypeNameFromParameter ( + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + string typeName) + { + Type.GetType (typeName).RequiresPublicConstructors (); + } + + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + static string _typeNameWithPublicParameterlessConstructor; + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresPublicConstructors))] + static void TestTypeNameFromField () + { + Type.GetType (_typeNameWithPublicParameterlessConstructor).RequiresPublicConstructors (); + } + + static int _switchOnField; + + static void TestMultipleConstantValues () + { + string typeName = null; + switch (_switchOnField) { + case 0: // valid + typeName = "Mono.Linker.Tests.Cases.DataFlow.GetTypeDataFlow"; + break; + case 1: // null + typeName = null; + break; + case 2: // invalid + typeName = "UnknownType"; + break; + case 3: // invalid second + typeName = "AnotherUnknownType"; + break; + } + + Type.GetType (typeName); + } + + static void TestStringEmpty () + { + Type.GetType (string.Empty); + } + + [ExpectedWarning ("IL2072", nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors), nameof (Type.GetType))] + [ExpectedWarning ("IL2057", "System.Type.GetType(String)")] + static void TestMultipleMixedValues () + { + string typeName = null; + switch (_switchOnField) { + case 0: + typeName = GetStringTypeWithPublicParameterlessConstructor (); + break; + case 1: + typeName = GetStringTypeWithNonPublicConstructors (); + break; + case 2: + typeName = "Mono.Linker.Tests.Cases.DataFlow.GetTypeDataFlow"; + break; + case 3: + typeName = GetStringUnkownType (); + break; + } + + Type.GetType (typeName).RequiresNonPublicConstructors (); + } + + class TypeWithWarnings + { + [RequiresUnreferencedCode ("--Method1--")] + public void Method1 () { } + + [RequiresUnreferencedCode ("--Method2--")] + public void Method2 () { } + + // https://github.com/dotnet/linker/issues/2273 + [ExpectedWarning ("IL2026", "--Method1--", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2026", "--Method2--", ProducedBy = ProducedBy.Trimmer)] + public static void Test () + { + Type.GetType ("Mono.Linker.Tests.Cases.DataFlow." + nameof (GetTypeDataFlow) + "+" + nameof (TypeWithWarnings)).RequiresPublicMethods (); + } + } + + class OverConstTypeName + { + private const string s_ConstTypeName = "Mono.Linker.Tests.Cases.DataFlow." + nameof (GetTypeDataFlow) + "+" + nameof (OverConstTypeName); + + [RequiresUnreferencedCode ("--Method1--")] + public void Method1 () { } + + // https://github.com/dotnet/linker/issues/2273 + [ExpectedWarning ("IL2026", "--Method1--", ProducedBy = ProducedBy.Trimmer)] + public static void Test () + { + Type.GetType (s_ConstTypeName).RequiresPublicMethods (); + } + } + + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] + private static string GetStringTypeWithPublicParameterlessConstructor () + { + return null; + } + + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] + private static string GetStringTypeWithPublicConstructors () + { + return null; + } + + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)] + private static string GetStringTypeWithNonPublicConstructors () + { + return null; + } + + private static string GetStringUnkownType () + { + return null; + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/GetTypeInfoDataFlow.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/GetTypeInfoDataFlow.cs new file mode 100644 index 00000000000000..29c25403e615b2 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/GetTypeInfoDataFlow.cs @@ -0,0 +1,54 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Reflection; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; + +namespace Mono.Linker.Tests.Cases.DataFlow +{ + [SkipKeptItemsValidation] + [ExpectedNoWarnings] + class GetTypeInfoDataFlow + { + public static void Main () + { + TestNoAnnotations (typeof (TestType)); + TestWithAnnotations (typeof (TestType)); + TestWithNull (); + TestWithNoValue (); + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicMethods))] + static void TestNoAnnotations (Type t) + { + t.GetTypeInfo ().RequiresPublicMethods (); + t.GetTypeInfo ().RequiresNone (); + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicFields))] + static void TestWithAnnotations ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type t) + { + t.GetTypeInfo ().RequiresPublicMethods (); + t.GetTypeInfo ().RequiresPublicFields (); + t.GetTypeInfo ().RequiresNone (); + } + + static void TestWithNull () + { + Type t = null; + t.GetTypeInfo ().RequiresPublicMethods (); + } + + static void TestWithNoValue () + { + Type t = null; + Type noValue = Type.GetTypeFromHandle (t.TypeHandle); + noValue.GetTypeInfo ().RequiresPublicMethods (); + } + + class TestType { } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/MemberTypesRelationships.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/MemberTypesRelationships.cs new file mode 100644 index 00000000000000..7ae4a6ac5e8dde --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/MemberTypesRelationships.cs @@ -0,0 +1,275 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; + +namespace Mono.Linker.Tests.Cases.DataFlow +{ + [SkipKeptItemsValidation] + [ExpectedNoWarnings] + public class MemberTypesRelationships + { + public static void Main () + { + TestPublicParameterlessConstructor (typeof (TestType)); + TestPublicConstructors (typeof (TestType)); + TestNonPublicConstructors (typeof (TestType)); + TestPublicMethods (typeof (TestType)); + TestNonPublicMethods (typeof (TestType)); + TestPublicFields (typeof (TestType)); + TestNonPublicFields (typeof (TestType)); + TestPublicNestedTypes (typeof (TestType)); + TestNonPublicNestedTypes (typeof (TestType)); + TestPublicProperties (typeof (TestType)); + TestNonPublicProperties (typeof (TestType)); + TestPublicEvents (typeof (TestType)); + TestNonPublicEvents (typeof (TestType)); + TestInterfaces (typeof (TestType)); + TestAll (typeof (TestType)); + TestMultiple (typeof (TestType)); + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicConstructors), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.PublicConstructors))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.NonPublicConstructors))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicMethods), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.PublicMethods))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestPublicParameterlessConstructor ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type type) + { + type.RequiresPublicParameterlessConstructor (); + type.RequiresPublicConstructors (); // Warns + type.RequiresNonPublicConstructors (); // Warns + type.RequiresNone (); + type.RequiresPublicMethods (); // Warns + type.RequiresAll (); // Warns + } + + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.NonPublicConstructors))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicMethods), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.PublicMethods))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestPublicConstructors ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors)] Type type) + { + type.RequiresPublicParameterlessConstructor (); + type.RequiresPublicConstructors (); + type.RequiresNonPublicConstructors (); // Warns + type.RequiresNone (); + type.RequiresPublicMethods (); // Warns + type.RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicParameterlessConstructor), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.PublicParameterlessConstructor))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicConstructors), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.PublicConstructors))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicMethods), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.PublicMethods))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestNonPublicConstructors ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type type) + { + type.RequiresPublicParameterlessConstructor (); // Warns + type.RequiresPublicConstructors (); // Warns + type.RequiresNonPublicConstructors (); + type.RequiresNone (); + type.RequiresPublicMethods (); // Warns + type.RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresNonPublicMethods), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.NonPublicMethods))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicConstructors), "y '" + nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.PublicConstructors) + "' i")] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestPublicMethods ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + type.RequiresPublicMethods (); + type.RequiresNonPublicMethods (); // Warns + type.RequiresNone (); + type.RequiresPublicConstructors (); // Warns + type.RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicMethods), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.PublicMethods))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.NonPublicConstructors))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestNonPublicMethods ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods)] Type type) + { + type.RequiresPublicMethods (); // Warns + type.RequiresNonPublicMethods (); + type.RequiresNone (); + type.RequiresNonPublicConstructors (); // Warns + type.RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresNonPublicFields), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.NonPublicFields))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicConstructors), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.PublicConstructors))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestPublicFields ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)] Type type) + { + type.RequiresPublicFields (); + type.RequiresNonPublicFields (); // Warns + type.RequiresNone (); + type.RequiresPublicConstructors (); // Warns + type.RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicFields), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.PublicFields))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresNonPublicConstructors), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.NonPublicConstructors))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestNonPublicFields ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicFields)] Type type) + { + type.RequiresPublicFields (); // Warns + type.RequiresNonPublicFields (); + type.RequiresNone (); + type.RequiresNonPublicConstructors (); // Warns + type.RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresNonPublicNestedTypes), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.NonPublicNestedTypes))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresInterfaces), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.Interfaces))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestPublicNestedTypes ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicNestedTypes)] Type type) + { + type.RequiresPublicNestedTypes (); + type.RequiresNonPublicNestedTypes (); // Warns + type.RequiresNone (); + type.RequiresInterfaces (); // Warns + type.RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicNestedTypes), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.PublicNestedTypes))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresInterfaces), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.Interfaces))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestNonPublicNestedTypes ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] Type type) + { + type.RequiresPublicNestedTypes (); // Warns + type.RequiresNonPublicNestedTypes (); + type.RequiresNone (); + type.RequiresInterfaces (); // Warns + type.RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresNonPublicProperties), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.NonPublicProperties))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicFields), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.PublicFields))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestPublicProperties ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] Type type) + { + type.RequiresPublicProperties (); + type.RequiresNonPublicProperties (); // Warns + type.RequiresNone (); + type.RequiresPublicFields (); // Warns + type.RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicProperties), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.PublicProperties))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresNonPublicFields), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.NonPublicFields))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestNonPublicProperties ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicProperties)] Type type) + { + type.RequiresPublicProperties (); // Warns + type.RequiresNonPublicProperties (); + type.RequiresNone (); + type.RequiresNonPublicFields (); // Warns + type.RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresNonPublicEvents), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.NonPublicEvents))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicFields), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.PublicFields))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestPublicEvents ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicEvents)] Type type) + { + type.RequiresPublicEvents (); + type.RequiresNonPublicEvents (); // Warns + type.RequiresNone (); + type.RequiresPublicFields (); // Warns + type.RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicEvents), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.PublicEvents))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresNonPublicFields), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.NonPublicFields))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestNonPublicEvents ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicEvents)] Type type) + { + type.RequiresPublicEvents (); // Warns + type.RequiresNonPublicEvents (); + type.RequiresNone (); + type.RequiresNonPublicFields (); // Warns + type.RequiresAll (); // Warns + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicNestedTypes), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.PublicNestedTypes))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresNonPublicNestedTypes), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.NonPublicNestedTypes))] + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresAll), nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.All))] + static void TestInterfaces ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.Interfaces)] Type type) + { + type.RequiresInterfaces (); + type.RequiresNone (); + type.RequiresPublicNestedTypes (); // Warns + type.RequiresNonPublicNestedTypes (); // Warns + type.RequiresAll (); // Warns + } + + static void TestAll ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.All)] Type type) + { + type.RequiresAll (); + type.RequiresNone (); + type.RequiresPublicParameterlessConstructor (); + type.RequiresPublicConstructors (); + type.RequiresNonPublicConstructors (); + type.RequiresPublicMethods (); + type.RequiresNonPublicMethods (); + type.RequiresPublicFields (); + type.RequiresNonPublicFields (); + type.RequiresPublicNestedTypes (); + type.RequiresNonPublicNestedTypes (); + type.RequiresPublicProperties (); + type.RequiresNonPublicProperties (); + type.RequiresPublicEvents (); + type.RequiresNonPublicEvents (); + type.RequiresInterfaces (); + } + + static void RequiresMultiplePrivates ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.NonPublicMethods | DynamicallyAccessedMemberTypes.NonPublicFields)] Type type) + { + } + + static void RequiresSomePublic ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.Interfaces | DynamicallyAccessedMemberTypes.PublicParameterlessConstructor | DynamicallyAccessedMemberTypes.NonPublicNestedTypes | DynamicallyAccessedMemberTypes.PublicMethods)] Type type) + { + } + + [ExpectedWarning ("IL2067", + nameof (RequiresMultiplePrivates), + nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.NonPublicMethods), + nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.NonPublicFields))] + [ExpectedWarning ("IL2067", + nameof (RequiresSomePublic), + nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.Interfaces), + nameof (DynamicallyAccessedMemberTypes) + "." + nameof (DynamicallyAccessedMemberTypes.NonPublicNestedTypes))] + static void TestMultiple ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicConstructors)] Type type) + { + RequiresMultiplePrivates (type); + RequiresSomePublic (type); + } + + class TestType { } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/TypeInfoAsTypeDataFlow.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/TypeInfoAsTypeDataFlow.cs new file mode 100644 index 00000000000000..d14b101a9285ca --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/TypeInfoAsTypeDataFlow.cs @@ -0,0 +1,55 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Reflection; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; + +namespace Mono.Linker.Tests.Cases.DataFlow +{ + [SkipKeptItemsValidation] + [ExpectedNoWarnings] + class TypeInfoAsTypeDataFlow + { + public static void Main () + { + TestNoAnnotations (typeof (TestType).GetTypeInfo ()); + TestWithAnnotations (typeof (TestType).GetTypeInfo ()); + TestWithNull (); + TestWithNoValue (); + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicMethods))] + static void TestNoAnnotations (TypeInfo t) + { + t.AsType ().RequiresPublicMethods (); + t.AsType ().RequiresNone (); + } + + [ExpectedWarning ("IL2067", nameof (DataFlowTypeExtensions.RequiresPublicFields))] + static void TestWithAnnotations ([DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] TypeInfo t) + { + t.AsType ().RequiresPublicMethods (); + t.AsType ().RequiresPublicFields (); + t.AsType ().RequiresNone (); + } + + static void TestWithNull () + { + TypeInfo t = null; + t.AsType ().RequiresPublicMethods (); + } + + static void TestWithNoValue () + { + Type t = null; + Type noValueType = Type.GetTypeFromHandle (t.TypeHandle); + TypeInfo noValue = noValueType.GetTypeInfo (); + noValue.AsType ().RequiresPublicMethods (); + } + + class TestType { } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/UnsafeDataFlow.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/UnsafeDataFlow.cs new file mode 100644 index 00000000000000..c4d9f98d584936 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/DataFlow/UnsafeDataFlow.cs @@ -0,0 +1,68 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Diagnostics.CodeAnalysis; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; +using Mono.Linker.Tests.Cases.Expectations.Metadata; + +namespace Mono.Linker.Tests.Cases.DataFlow +{ + [SetupCompileArgument ("/unsafe")] + [SkipKeptItemsValidation] + [ExpectedNoWarnings] + class UnsafeDataFlow + { + public static void Main () + { + TestReadFromPointer (); + TestWriteToPointer (); + TestWriteToStackAllocedStruct (); + } + + // We don't analyze the pointer manipulation, so it should produce a warning + // about reading an unknown type, without crashing the analyzer. + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll))] + static unsafe void TestReadFromPointer () + { + int i = 6; + int* pI = &i; + Type[] arr = new Type[] { GetWithPublicMethods () }; + arr[*pI].RequiresAll (); + } + + // We don't analyze the pointer manipulation, so it should produce a warning + // about reading an unknown type, without crashing the analyzer. + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll))] + static unsafe void TestWriteToPointer () + { + int i = 6; + int* pI = &i; + *pI = 0; + Type[] arr = new Type[] { GetWithPublicMethods () }; + arr[i].RequiresAll (); + } + + // We don't analyze the stackalloc'd struct member, so it should produce a warning + // about reading an unknown type, without crashing the analyzer. + [ExpectedWarning ("IL2062", nameof (DataFlowTypeExtensions.RequiresAll))] + static unsafe void TestWriteToStackAllocedStruct () + { + var stackArr = stackalloc S[1]; + stackArr[0] = new S { + I = 0 + }; + Type[] arr = new Type[] { GetWithPublicMethods () }; + arr[stackArr[0].I].RequiresAll (); + } + + struct S + { + public int I; + } + + [return: DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicMethods)] + static Type GetWithPublicMethods () => null; + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/Mono.Linker.Tests.Cases.csproj b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/Mono.Linker.Tests.Cases.csproj new file mode 100644 index 00000000000000..ec237817f2901f --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/Mono.Linker.Tests.Cases.csproj @@ -0,0 +1,17 @@ + + + + $(NetCoreAppToolCurrent) + x64;x86 + AnyCPU + true + $(DefineConstants);INCLUDE_EXPECTATIONS + 0 + 0 + + + + + + + diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/Repro/Program.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/Repro/Program.cs new file mode 100644 index 00000000000000..6aba1d869f9c11 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/Repro/Program.cs @@ -0,0 +1,30 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; +using Mono.Linker.Tests.Cases.Expectations.Metadata; + +namespace Mono.Linker.Tests.Cases.Repro +{ + [SkipKeptItemsValidation] + [ExpectedNoWarnings] + public class Program + { + + public static void Main () + { + Console.WriteLine ("HelloWorld"); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/RequiresCapability/BasicRequires.cs b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/RequiresCapability/BasicRequires.cs new file mode 100644 index 00000000000000..b89dfc61e8cf3c --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests.Cases/RequiresCapability/BasicRequires.cs @@ -0,0 +1,215 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Helpers; +using Mono.Linker.Tests.Cases.Expectations.Metadata; + +namespace Mono.Linker.Tests.Cases.RequiresCapability +{ + [SkipKeptItemsValidation] + [ExpectedNoWarnings] + public class BasicRequires + { + + public static void Main () + { + TestRequiresWithMessageOnlyOnMethod (); + TestRequiresWithMessageAndUrlOnMethod (); + TestRequiresOnConstructor (); + TestRequiresOnPropertyGetterAndSetter (); + TestThatTrailingPeriodIsAddedToMessage (); + TestThatTrailingPeriodIsNotDuplicatedInWarningMessage (); + TestRequiresFromNameOf (); + OnEventMethod.Test (); + RequiresOnGenerics.Test (); + } + + [ExpectedWarning ("IL2026", "Message for --RequiresWithMessageOnly--.")] + [ExpectedWarning ("IL3002", "Message for --RequiresWithMessageOnly--.", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)] + [ExpectedWarning ("IL3050", "Message for --RequiresWithMessageOnly--.", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)] + static void TestRequiresWithMessageOnlyOnMethod () + { + RequiresWithMessageOnly (); + } + + [RequiresUnreferencedCode ("Message for --RequiresWithMessageOnly--")] + [RequiresAssemblyFiles ("Message for --RequiresWithMessageOnly--")] + [RequiresDynamicCode ("Message for --RequiresWithMessageOnly--")] + static void RequiresWithMessageOnly () + { + } + + [ExpectedWarning ("IL2026", "Message for --RequiresWithMessageAndUrl--.", "https://helpurl")] + [ExpectedWarning ("IL3002", "Message for --RequiresWithMessageAndUrl--.", "https://helpurl", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)] + [ExpectedWarning ("IL3050", "Message for --RequiresWithMessageAndUrl--.", "https://helpurl", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)] + static void TestRequiresWithMessageAndUrlOnMethod () + { + RequiresWithMessageAndUrl (); + } + + [RequiresUnreferencedCode ("Message for --RequiresWithMessageAndUrl--", Url = "https://helpurl")] + [RequiresAssemblyFiles ("Message for --RequiresWithMessageAndUrl--", Url = "https://helpurl")] + [RequiresDynamicCode ("Message for --RequiresWithMessageAndUrl--", Url = "https://helpurl")] + static void RequiresWithMessageAndUrl () + { + } + + [ExpectedWarning ("IL2026", "Message for --ConstructorRequires--.")] + [ExpectedWarning ("IL3002", "Message for --ConstructorRequires--.", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)] + [ExpectedWarning ("IL3050", "Message for --ConstructorRequires--.", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)] + static void TestRequiresOnConstructor () + { + new ConstructorRequires (); + } + + class ConstructorRequires + { + [RequiresUnreferencedCode ("Message for --ConstructorRequires--")] + [RequiresAssemblyFiles ("Message for --ConstructorRequires--")] + [RequiresDynamicCode ("Message for --ConstructorRequires--")] + public ConstructorRequires () + { + } + } + + [ExpectedWarning ("IL2026", "Message for --getter PropertyRequires--.")] + [ExpectedWarning ("IL2026", "Message for --setter PropertyRequires--.")] + [ExpectedWarning ("IL3002", "Message for --getter PropertyRequires--.", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)] + [ExpectedWarning ("IL3002", "Message for --setter PropertyRequires--.", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)] + [ExpectedWarning ("IL3050", "Message for --getter PropertyRequires--.", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)] + [ExpectedWarning ("IL3050", "Message for --setter PropertyRequires--.", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)] + static void TestRequiresOnPropertyGetterAndSetter () + { + _ = PropertyRequires; + PropertyRequires = 0; + } + + static int PropertyRequires { + [RequiresUnreferencedCode ("Message for --getter PropertyRequires--")] + [RequiresAssemblyFiles ("Message for --getter PropertyRequires--")] + [RequiresDynamicCode ("Message for --getter PropertyRequires--")] + get { return 42; } + + [RequiresUnreferencedCode ("Message for --setter PropertyRequires--")] + [RequiresAssemblyFiles ("Message for --setter PropertyRequires--")] + [RequiresDynamicCode ("Message for --setter PropertyRequires--")] + set { } + } + + [RequiresUnreferencedCode ("Linker adds a trailing period to this message")] + [RequiresAssemblyFiles ("Linker adds a trailing period to this message")] + [RequiresDynamicCode ("Linker adds a trailing period to this message")] + static void WarningMessageWithoutEndingPeriod () + { + } + + [ExpectedWarning ("IL2026", "Linker adds a trailing period to this message.")] + [ExpectedWarning ("IL3002", "Linker adds a trailing period to this message.", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)] + [ExpectedWarning ("IL3050", "Linker adds a trailing period to this message.", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)] + static void TestThatTrailingPeriodIsAddedToMessage () + { + WarningMessageWithoutEndingPeriod (); + } + + [RequiresUnreferencedCode ("Linker does not add a period to this message.")] + [RequiresAssemblyFiles ("Linker does not add a period to this message.")] + [RequiresDynamicCode ("Linker does not add a period to this message.")] + static void WarningMessageEndsWithPeriod () + { + } + + [LogDoesNotContain ("Linker does not add a period to this message..")] + [ExpectedWarning ("IL2026", "Linker does not add a period to this message.")] + [ExpectedWarning ("IL3002", "Linker does not add a period to this message.", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)] + [ExpectedWarning ("IL3050", "Linker does not add a period to this message.", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)] + static void TestThatTrailingPeriodIsNotDuplicatedInWarningMessage () + { + WarningMessageEndsWithPeriod (); + } + + static void TestRequiresFromNameOf () + { + _ = nameof (BasicRequires.RequiresWithMessageOnly); + } + + class OnEventMethod + { + [ExpectedWarning ("IL2026", "--EventToTestRemove.remove--", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2026", "--EventToTestRemove.remove--", ProducedBy = ProducedBy.Trimmer)] + static event EventHandler EventToTestRemove { + add { } + [RequiresUnreferencedCode ("Message for --EventToTestRemove.remove--")] + [RequiresAssemblyFiles ("Message for --EventToTestRemove.remove--")] + [RequiresDynamicCode ("Message for --EventToTestRemove.remove--")] + remove { } + } + + [ExpectedWarning ("IL2026", "--EventToTestAdd.add--", ProducedBy = ProducedBy.Trimmer)] + [ExpectedWarning ("IL2026", "--EventToTestAdd.add--", ProducedBy = ProducedBy.Trimmer)] + static event EventHandler EventToTestAdd { + [RequiresUnreferencedCode ("Message for --EventToTestAdd.add--")] + [RequiresAssemblyFiles ("Message for --EventToTestAdd.add--")] + [RequiresDynamicCode ("Message for --EventToTestAdd.add--")] + add { } + remove { } + } + + [ExpectedWarning ("IL2026", "--EventToTestRemove.remove--")] + [ExpectedWarning ("IL3002", "--EventToTestRemove.remove--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)] + [ExpectedWarning ("IL3050", "--EventToTestRemove.remove--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)] + [ExpectedWarning ("IL2026", "--EventToTestAdd.add--")] + [ExpectedWarning ("IL3002", "--EventToTestAdd.add--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)] + [ExpectedWarning ("IL3050", "--EventToTestAdd.add--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)] + public static void Test () + { + EventToTestRemove -= (sender, e) => { }; + EventToTestAdd += (sender, e) => { }; + } + } + + class RequiresOnGenerics + { + class GenericWithStaticMethod + { + [RequiresUnreferencedCode ("Message for --GenericTypeWithStaticMethodWhichRequires--")] + [RequiresAssemblyFiles ("Message for --GenericTypeWithStaticMethodWhichRequires--")] + [RequiresDynamicCode ("Message for --GenericTypeWithStaticMethodWhichRequires--")] + public static void GenericTypeWithStaticMethodWhichRequires () { } + } + + // NativeAOT doesnt produce Requires warnings in Generics https://github.com/dotnet/runtime/issues/68688 + // [ExpectedWarning("IL2026", "--GenericTypeWithStaticMethodWhichRequires--"] + [ExpectedWarning ("IL2026", "--GenericTypeWithStaticMethodWhichRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.Trimmer)] + // [ExpectedWarning("IL3002", "--GenericTypeWithStaticMethodWhichRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)] + [ExpectedWarning ("IL3002", "--GenericTypeWithStaticMethodWhichRequires--", ProducedBy = ProducedBy.Analyzer)] + // [ExpectedWarning("IL3050", "--GenericTypeWithStaticMethodWhichRequires--", ProducedBy = ProducedBy.Analyzer | ProducedBy.NativeAot)] + [ExpectedWarning ("IL3050", "--GenericTypeWithStaticMethodWhichRequires--", ProducedBy = ProducedBy.Analyzer)] + public static void GenericTypeWithStaticMethodViaLdftn () + { + var _ = new Action (GenericWithStaticMethod.GenericTypeWithStaticMethodWhichRequires); + } + + class TestType { } + + static T MakeNew () where T : new() => new T (); + static T MakeNew2 () where T : new() => MakeNew (); + + public static void Test () + { + GenericTypeWithStaticMethodViaLdftn (); + MakeNew2 (); + } + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/Extensions/CecilExtensions.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/Extensions/CecilExtensions.cs new file mode 100644 index 00000000000000..afcefb93804888 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/Extensions/CecilExtensions.cs @@ -0,0 +1,368 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Mono.Cecil; + +namespace Mono.Linker.Tests.Extensions +{ + public static class CecilExtensions + { + public static IEnumerable AllDefinedTypes (this AssemblyDefinition assemblyDefinition) + { + return assemblyDefinition.Modules.SelectMany (m => m.AllDefinedTypes ()); + } + + public static IEnumerable AllDefinedTypes (this ModuleDefinition moduleDefinition) + { + foreach (var typeDefinition in moduleDefinition.Types) { + yield return typeDefinition; + + foreach (var definition in typeDefinition.AllDefinedTypes ()) + yield return definition; + } + } + + public static IEnumerable AllDefinedTypes (this TypeDefinition typeDefinition) + { + foreach (var nestedType in typeDefinition.NestedTypes) { + yield return nestedType; + + foreach (var definition in nestedType.AllDefinedTypes ()) + yield return definition; + } + } + + public static IEnumerable AllMembers (this ModuleDefinition module) + { + foreach (var type in module.AllDefinedTypes ()) { + yield return type; + + foreach (var member in type.AllMembers ()) + yield return member; + } + } + + public static IEnumerable AllMembers (this TypeDefinition type) + { + foreach (var field in type.Fields) + yield return field; + + foreach (var prop in type.Properties) + yield return prop; + + foreach (var method in type.Methods) + yield return method; + + foreach (var @event in type.Events) + yield return @event; + } + + public static IEnumerable AllMethods (this TypeDefinition type) + { + foreach (var m in type.AllMembers ()) { + switch (m) { + case MethodDefinition method: + yield return method; + break; + case PropertyDefinition @property: + if (@property.GetMethod != null) + yield return @property.GetMethod; + + if (@property.SetMethod != null) + yield return @property.SetMethod; + + break; + case EventDefinition @event: + if (@event.AddMethod != null) + yield return @event.AddMethod; + + if (@event.RemoveMethod != null) + yield return @event.RemoveMethod; + + break; + + default: + break; + } + } + } + + public static bool HasAttribute (this ICustomAttributeProvider provider, string name) + { + return provider.CustomAttributes.Any (ca => ca.AttributeType.Name == name); + } + + public static bool HasAttributeDerivedFrom (this ICustomAttributeProvider provider, string name) + { + return provider.CustomAttributes.Any (ca => ca.AttributeType.Resolve ().DerivesFrom (name)); + } + + public static bool DerivesFrom (this TypeDefinition type, string baseTypeName) + { + if (type.Name == baseTypeName) + return true; + + if (type.BaseType == null) + return false; + + if (type.BaseType.Name == baseTypeName) + return true; + + return type.BaseType.Resolve ()?.DerivesFrom (baseTypeName) ?? false; + } + + public static PropertyDefinition GetPropertyDefinition (this MethodDefinition method) + { + if (!method.IsSetter && !method.IsGetter) + throw new ArgumentException (); + + var propertyName = method.Name.Substring (4); + return method.DeclaringType.Properties.First (p => p.Name == propertyName); + } + + public static string GetSignature (this MethodDefinition method) + { + var builder = new StringBuilder (); + builder.Append (method.Name); + if (method.HasGenericParameters) { + builder.Append ($"<#{method.GenericParameters.Count}>"); + } + + builder.Append ("("); + + if (method.HasParameters) { + for (int i = 0; i < method.Parameters.Count - 1; i++) { + // TODO: modifiers + // TODO: default values + builder.Append ($"{method.Parameters[i].ParameterType},"); + } + + builder.Append (method.Parameters[method.Parameters.Count - 1].ParameterType); + } + + builder.Append (")"); + + return builder.ToString (); + } + + public static object GetConstructorArgumentValue (this CustomAttribute attr, int argumentIndex) + { + return attr.ConstructorArguments[argumentIndex].Value; + } + + public static object? GetPropertyValue (this CustomAttribute attr, string propertyName) + { + foreach (var prop in attr.Properties) + if (prop.Name == propertyName) + return prop.Argument.Value; + + return null; + } + + public static bool IsEventMethod(this MethodDefinition md) + { + return (md.SemanticsAttributes & MethodSemanticsAttributes.AddOn) != 0 || + (md.SemanticsAttributes & MethodSemanticsAttributes.Fire) != 0 || + (md.SemanticsAttributes & MethodSemanticsAttributes.RemoveOn) != 0; + } + + public static string GetDisplayName(this MethodReference method) + { + var sb = new System.Text.StringBuilder(); + + // Match C# syntaxis name if setter or getter + var methodDefinition = method.Resolve(); + if (methodDefinition != null && (methodDefinition.IsSetter || methodDefinition.IsGetter)) + { + // Append property name + string name = methodDefinition.IsSetter ? string.Concat(methodDefinition.Name.AsSpan(4), ".set") : string.Concat(methodDefinition.Name.AsSpan(4), ".get"); + sb.Append(name); + // Insert declaring type name and namespace + sb.Insert(0, '.').Insert(0, method.DeclaringType?.GetDisplayName()); + return sb.ToString(); + } + + if (methodDefinition != null && methodDefinition.IsEventMethod()) + { + // Append event name + string name = methodDefinition.SemanticsAttributes switch + { + MethodSemanticsAttributes.AddOn => string.Concat(methodDefinition.Name.AsSpan(4), ".add"), + MethodSemanticsAttributes.RemoveOn => string.Concat(methodDefinition.Name.AsSpan(7), ".remove"), + MethodSemanticsAttributes.Fire => string.Concat(methodDefinition.Name.AsSpan(6), ".raise"), + _ => throw new NotSupportedException(), + }; + sb.Append(name); + // Insert declaring type name and namespace + sb.Insert(0, '.').Insert(0, method.DeclaringType.GetDisplayName()); + return sb.ToString(); + } + + // Append parameters + sb.Append("("); + if (method.HasParameters) + { + for (int i = 0; i < method.Parameters.Count - 1; i++) + sb.Append(method.Parameters[i].ParameterType.GetDisplayNameWithoutNamespace()).Append(", "); + + sb.Append(method.Parameters[method.Parameters.Count - 1].ParameterType.GetDisplayNameWithoutNamespace()); + } + + sb.Append(")"); + + // Insert generic parameters + if (method.HasGenericParameters) + { + PrependGenericParameters(method.GenericParameters, sb); + } + + // Insert method name + if (method.Name == ".ctor") + sb.Insert(0, method.DeclaringType.Name); + else + sb.Insert(0, method.Name); + + // Insert declaring type name and namespace + if (method.DeclaringType != null) + sb.Insert(0, '.').Insert(0, method.DeclaringType.GetDisplayName()); + + return sb.ToString(); + } + + public static string GetDisplayName(this TypeReference type) + { + var builder = GetDisplayNameWithoutNamespace(type); + var namespaceDisplayName = type.GetNamespaceDisplayName(); + if (!string.IsNullOrEmpty(namespaceDisplayName)) + { + builder.Insert(0, "."); + builder.Insert(0, namespaceDisplayName); + } + + return builder.ToString(); + } + + public static string GetDisplayName(this FieldReference field) + { + var builder = new StringBuilder(); + if (field.DeclaringType != null) + { + builder.Append(field.DeclaringType.GetDisplayName()); + builder.Append("."); + } + + builder.Append(field.Name); + + return builder.ToString(); + } + + public static string GetNamespaceDisplayName(this MemberReference member) + { + var type = member is TypeReference typeReference ? typeReference : member.DeclaringType; + while (type.DeclaringType != null) + type = type.DeclaringType; + + return type.Namespace; + } + + public static StringBuilder GetDisplayNameWithoutNamespace(this TypeReference type) + { + var sb = new StringBuilder(); + if (type == null) + return sb; + + Stack? genericArguments = null; + while (true) + { + switch (type) + { + case ArrayType arrayType: + AppendArrayType(arrayType, sb); + break; + case GenericInstanceType genericInstanceType: + genericArguments = new Stack(genericInstanceType.GenericArguments); + type = genericInstanceType.ElementType; + continue; + default: + if (type.HasGenericParameters) + { + int genericParametersCount = type.GenericParameters.Count; + int declaringTypeGenericParametersCount = type.DeclaringType?.GenericParameters?.Count ?? 0; + + string simpleName; + if (genericParametersCount > declaringTypeGenericParametersCount) + { + if (genericArguments?.Count > 0) + PrependGenericArguments(genericArguments, genericParametersCount - declaringTypeGenericParametersCount, sb); + else + PrependGenericParameters(type.GenericParameters.Skip(declaringTypeGenericParametersCount).ToList(), sb); + + int explicitArityIndex = type.Name.IndexOf('`'); + simpleName = explicitArityIndex != -1 ? type.Name.Substring(0, explicitArityIndex) : type.Name; + } + else + simpleName = type.Name; + + sb.Insert(0, simpleName); + break; + } + + sb.Insert(0, type.Name); + break; + } + + if (type.DeclaringType is not TypeReference declaringType) + break; + + type = declaringType; + + sb.Insert(0, '.'); + } + + return sb; + } + + public static void PrependGenericParameters(IList genericParameters, StringBuilder sb) + { + sb.Insert(0, '>').Insert(0, genericParameters[genericParameters.Count - 1]); + for (int i = genericParameters.Count - 2; i >= 0; i--) + sb.Insert(0, ',').Insert(0, genericParameters[i]); + + sb.Insert(0, '<'); + } + + static void PrependGenericArguments(Stack genericArguments, int argumentsToTake, StringBuilder sb) + { + sb.Insert(0, '>').Insert(0, genericArguments.Pop().GetDisplayNameWithoutNamespace().ToString()); + while (--argumentsToTake > 0) + sb.Insert(0, ',').Insert(0, genericArguments.Pop().GetDisplayNameWithoutNamespace().ToString()); + + sb.Insert(0, '<'); + } + + static void AppendArrayType(ArrayType arrayType, StringBuilder sb) + { + void parseArrayDimensions(ArrayType at) + { + sb.Append('['); + for (int i = 0; i < at.Dimensions.Count - 1; i++) + sb.Append(','); + + sb.Append(']'); + } + + sb.Append(arrayType.Name.AsSpan(0, arrayType.Name.IndexOf('['))); + parseArrayDimensions(arrayType); + var element = arrayType.ElementType as ArrayType; + while (element != null) + { + parseArrayDimensions(element); + element = element.ElementType as ArrayType; + } + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/Extensions/NiceIO.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/Extensions/NiceIO.cs new file mode 100644 index 00000000000000..9272ffc026c03e --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/Extensions/NiceIO.cs @@ -0,0 +1,864 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +// The MIT License(MIT) +// ===================== +// +// Copyright © `2015-2017` `Lucas Meijer` +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the “Software”), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace Mono.Linker.Tests.Extensions +{ + public class NPath : IEquatable, IComparable + { + private static readonly StringComparison PathStringComparison = IsLinux () ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase; + + private readonly string[] _elements; + private readonly bool _isRelative; + private readonly string? _driveLetter; + + #region construction + + public NPath (string path) + { + if (path == null) + throw new ArgumentNullException (); + + path = ParseDriveLetter (path, out _driveLetter); + + if (path == "/") { + _isRelative = false; + _elements = new string[] { }; + } else { + var split = path.Split ('/', '\\'); + + _isRelative = _driveLetter == null && IsRelativeFromSplitString (split); + + _elements = ParseSplitStringIntoElements (split.Where (s => s.Length > 0).ToArray ()); + } + } + + private NPath (string[] elements, bool isRelative, string? driveLetter) + { + _elements = elements; + _isRelative = isRelative; + _driveLetter = driveLetter; + } + + private string[] ParseSplitStringIntoElements (IEnumerable inputs) + { + var stack = new List (); + + foreach (var input in inputs.Where (input => input.Length != 0)) { + if (input == ".") { + if ((stack.Count > 0) && (stack.Last () != ".")) + continue; + } else if (input == "..") { + if (HasNonDotDotLastElement (stack)) { + stack.RemoveAt (stack.Count - 1); + continue; + } + if (!_isRelative) + throw new ArgumentException ("You cannot create a path that tries to .. past the root"); + } + stack.Add (input); + } + return stack.ToArray (); + } + + private static bool HasNonDotDotLastElement (List stack) + { + return stack.Count > 0 && stack[stack.Count - 1] != ".."; + } + + private string ParseDriveLetter (string path, out string? driveLetter) + { + if (path.Length >= 2 && path[1] == ':') { + driveLetter = path[0].ToString (); + return path.Substring (2); + } + + driveLetter = null; + return path; + } + + private static bool IsRelativeFromSplitString (string[] split) + { + if (split.Length < 2) + return true; + + return split[0].Length != 0 || !split.Any (s => s.Length > 0); + } + + public NPath Combine (params string[] append) + { + return Combine (append.Select (a => new NPath (a)).ToArray ()); + } + + public NPath Combine (params NPath[] append) + { + if (!append.All (p => p.IsRelative)) + throw new ArgumentException ("You cannot .Combine a non-relative path"); + + return new NPath (ParseSplitStringIntoElements (_elements.Concat (append.SelectMany (p => p._elements))), _isRelative, _driveLetter); + } + + public NPath Parent { + get { + if (_elements.Length == 0) + throw new InvalidOperationException ("Parent is called on an empty path"); + + var newElements = _elements.Take (_elements.Length - 1).ToArray (); + + return new NPath (newElements, _isRelative, _driveLetter); + } + } + + public NPath RelativeTo (NPath path) + { + if (!IsChildOf (path)) { + if (!IsRelative && !path.IsRelative && _driveLetter != path._driveLetter) + throw new ArgumentException ("Path.RelativeTo() was invoked with two paths that are on different volumes. invoked on: " + ToString () + " asked to be made relative to: " + path); + + NPath? commonParent = null; + foreach (var parent in RecursiveParents) { + commonParent = path.RecursiveParents.FirstOrDefault (otherParent => otherParent == parent); + + if (commonParent != null) + break; + } + + if (commonParent == null) + throw new ArgumentException ("Path.RelativeTo() was unable to find a common parent between " + ToString () + " and " + path); + + if (IsRelative && path.IsRelative && commonParent.IsEmpty ()) + throw new ArgumentException ("Path.RelativeTo() was invoked with two relative paths that do not share a common parent. Invoked on: " + ToString () + " asked to be made relative to: " + path); + + var depthDiff = path.Depth - commonParent.Depth; + return new NPath (Enumerable.Repeat ("..", depthDiff).Concat (_elements.Skip (commonParent.Depth)).ToArray (), true, null); + } + + return new NPath (_elements.Skip (path._elements.Length).ToArray (), true, null); + } + + public NPath ChangeExtension (string extension) + { + ThrowIfRoot (); + + var newElements = (string[]) _elements.Clone (); + newElements[newElements.Length - 1] = Path.ChangeExtension (_elements[_elements.Length - 1], WithDot (extension)); + if (extension == string.Empty) + newElements[newElements.Length - 1] = newElements[newElements.Length - 1].TrimEnd ('.'); + return new NPath (newElements, _isRelative, _driveLetter); + } + #endregion construction + + #region inspection + + public bool IsRelative { + get { return _isRelative; } + } + + public string FileName { + get { + ThrowIfRoot (); + + return _elements.Last (); + } + } + + public string FileNameWithoutExtension { + get { return Path.GetFileNameWithoutExtension (FileName); } + } + + public IEnumerable Elements { + get { return _elements; } + } + + public int Depth { + get { return _elements.Length; } + } + + public bool Exists (string append = "") + { + return Exists (new NPath (append)); + } + + public bool Exists (NPath append) + { + return FileExists (append) || DirectoryExists (append); + } + + public bool DirectoryExists (string append = "") + { + return DirectoryExists (new NPath (append)); + } + + public bool DirectoryExists (NPath append) + { + return Directory.Exists (Combine (append).ToString ()); + } + + public bool FileExists (string append = "") + { + return FileExists (new NPath (append)); + } + + public bool FileExists (NPath append) + { + return File.Exists (Combine (append).ToString ()); + } + + public string ExtensionWithDot { + get { + if (IsRoot) + throw new ArgumentException ("A root directory does not have an extension"); + + var last = _elements.Last (); + var index = last.LastIndexOf ("."); + if (index < 0) return String.Empty; + return last.Substring (index); + } + } + + public string InQuotes () + { + return "\"" + ToString () + "\""; + } + + public string InQuotes (SlashMode slashMode) + { + return "\"" + ToString (slashMode) + "\""; + } + + public override string ToString () + { + return ToString (SlashMode.Native); + } + + public string ToString (SlashMode slashMode) + { + // Check if it's linux root / + if (IsRoot && string.IsNullOrEmpty (_driveLetter)) + return Slash (slashMode).ToString (); + + if (_isRelative && _elements.Length == 0) + return "."; + + var sb = new StringBuilder (); + if (_driveLetter != null) { + sb.Append (_driveLetter); + sb.Append (":"); + } + if (!_isRelative) + sb.Append (Slash (slashMode)); + var first = true; + foreach (var element in _elements) { + if (!first) + sb.Append (Slash (slashMode)); + + sb.Append (element); + first = false; + } + return sb.ToString (); + } + + public static implicit operator string (NPath path) + { + return path.ToString (); + } + + static char Slash (SlashMode slashMode) + { + return slashMode switch { + SlashMode.Backward => '\\', + SlashMode.Forward => '/', + _ => Path.DirectorySeparatorChar, + }; + } + + public override bool Equals (Object? obj) + { + if (obj == null) + return false; + + // If parameter cannot be cast to Point return false. + if (!(obj is NPath p)) + return false; + + return Equals (p); + } + + public bool Equals (NPath? p) + { + if (p == null) + return false; + + if (p._isRelative != _isRelative) + return false; + + if (!string.Equals (p._driveLetter, _driveLetter, PathStringComparison)) + return false; + + if (p._elements.Length != _elements.Length) + return false; + + for (var i = 0; i != _elements.Length; i++) + if (!string.Equals (p._elements[i], _elements[i], PathStringComparison)) + return false; + + return true; + } + + public static bool operator == (NPath? a, NPath? b) + { + // If both are null, or both are same instance, return true. + if (ReferenceEquals (a, b)) + return true; + + // If one is null, but not both, return false. + if ((a is null) || (b is null)) + return false; + + // Return true if the fields match: + return a.Equals (b); + } + + public override int GetHashCode () + { + unchecked { + int hash = 17; + // Suitable nullity checks etc, of course :) + hash = hash * 23 + _isRelative.GetHashCode (); + foreach (var element in _elements) + hash = hash * 23 + element.GetHashCode (); + if (_driveLetter != null) + hash = hash * 23 + _driveLetter.GetHashCode (); + return hash; + } + } + + public int CompareTo (object? obj) + { + if (obj == null) + return -1; + + return this.ToString ().CompareTo (((NPath) obj).ToString ()); + } + + public static bool operator != (NPath? a, NPath? b) + { + return !(a == b); + } + + public bool HasExtension (params string[] extensions) + { + var extensionWithDotLower = ExtensionWithDot.ToLower (); + return extensions.Any (e => WithDot (e).ToLower () == extensionWithDotLower); + } + + private static string WithDot (string extension) + { + return extension.StartsWith (".") ? extension : "." + extension; + } + + private bool IsEmpty () + { + return _elements.Length == 0; + } + + public bool IsRoot { + get { return _elements.Length == 0 && !_isRelative; } + } + + #endregion inspection + + #region directory enumeration + + public IEnumerable Files (string filter, bool recurse = false) + { + return Directory.GetFiles (ToString (), filter, recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly).Select (s => new NPath (s)); + } + + public IEnumerable Files (bool recurse = false) + { + return Files ("*", recurse); + } + + public IEnumerable Contents (string filter, bool recurse = false) + { + return Files (filter, recurse).Concat (Directories (filter, recurse)); + } + + public IEnumerable Contents (bool recurse = false) + { + return Contents ("*", recurse); + } + + public IEnumerable Directories (string filter, bool recurse = false) + { + return Directory.GetDirectories (ToString (), filter, recurse ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly).Select (s => new NPath (s)); + } + + public IEnumerable Directories (bool recurse = false) + { + return Directories ("*", recurse); + } + + #endregion + + #region filesystem writing operations + public NPath CreateFile () + { + ThrowIfRelative (); + ThrowIfRoot (); + EnsureParentDirectoryExists (); + File.WriteAllBytes (ToString (), new byte[0]); + return this; + } + + public NPath CreateFile (string file) + { + return CreateFile (new NPath (file)); + } + + public NPath CreateFile (NPath file) + { + if (!file.IsRelative) + throw new ArgumentException ("You cannot call CreateFile() on an existing path with a non relative argument"); + return Combine (file).CreateFile (); + } + + public NPath CreateDirectory () + { + ThrowIfRelative (); + + if (IsRoot) + throw new NotSupportedException ("CreateDirectory is not supported on a root level directory because it would be dangerous:" + ToString ()); + + Directory.CreateDirectory (ToString ()); + return this; + } + + public NPath CreateDirectory (string directory) + { + return CreateDirectory (new NPath (directory)); + } + + public NPath CreateDirectory (NPath directory) + { + if (!directory.IsRelative) + throw new ArgumentException ("Cannot call CreateDirectory with an absolute argument"); + + return Combine (directory).CreateDirectory (); + } + + public NPath? Copy (string dest) + { + return Copy (new NPath (dest)); + } + + public NPath? Copy (string dest, Func fileFilter) + { + return Copy (new NPath (dest), fileFilter); + } + + public NPath? Copy (NPath dest) + { + return Copy (dest, p => true); + } + + public NPath? Copy (NPath dest, Func fileFilter) + { + ThrowIfRelative (); + if (dest.IsRelative) + dest = Parent.Combine (dest); + + if (dest.DirectoryExists ()) + return CopyWithDeterminedDestination (dest.Combine (FileName), fileFilter); + + return CopyWithDeterminedDestination (dest, fileFilter); + } + + public NPath MakeAbsolute () + { + if (!IsRelative) + return this; + + return NPath.CurrentDirectory.Combine (this); + } + + NPath? CopyWithDeterminedDestination (NPath absoluteDestination, Func fileFilter) + { + if (absoluteDestination.IsRelative) + throw new ArgumentException ("absoluteDestination must be absolute"); + + if (FileExists ()) { + if (!fileFilter (absoluteDestination)) + return null; + + absoluteDestination.EnsureParentDirectoryExists (); + + File.Copy (ToString (), absoluteDestination.ToString (), true); + return absoluteDestination; + } + + if (DirectoryExists ()) { + absoluteDestination.EnsureDirectoryExists (); + foreach (var thing in Contents ()) + thing.CopyWithDeterminedDestination (absoluteDestination.Combine (thing.RelativeTo (this)), fileFilter); + return absoluteDestination; + } + + throw new ArgumentException ("Copy() called on path that doesnt exist: " + ToString ()); + } + + public void Delete (DeleteMode deleteMode = DeleteMode.Normal) + { + ThrowIfRelative (); + + if (IsRoot) + throw new NotSupportedException ("Delete is not supported on a root level directory because it would be dangerous:" + ToString ()); + + if (FileExists ()) + File.Delete (ToString ()); + else if (DirectoryExists ()) + try { + Directory.Delete (ToString (), true); + } catch (IOException) { + if (deleteMode == DeleteMode.Normal) + throw; + } + else + throw new InvalidOperationException ("Trying to delete a path that does not exist: " + ToString ()); + } + + public void DeleteIfExists (DeleteMode deleteMode = DeleteMode.Normal) + { + ThrowIfRelative (); + + if (FileExists () || DirectoryExists ()) + Delete (deleteMode); + } + + public NPath DeleteContents () + { + ThrowIfRelative (); + + if (IsRoot) + throw new NotSupportedException ("DeleteContents is not supported on a root level directory because it would be dangerous:" + ToString ()); + + if (FileExists ()) + throw new InvalidOperationException ("It is not valid to perform this operation on a file"); + + if (DirectoryExists ()) { + try { + Files ().Delete (); + Directories ().Delete (); + } catch (IOException) { + if (Files (true).Any ()) + throw; + } + + return this; + } + + return EnsureDirectoryExists (); + } + + public static NPath CreateTempDirectory (string myprefix) + { + var random = new Random (); + while (true) { + var candidate = new NPath (Path.GetTempPath () + "/" + myprefix + "_" + random.Next ()); + if (!candidate.Exists ()) + return candidate.CreateDirectory (); + } + } + + public NPath Move (string dest) + { + return Move (new NPath (dest)); + } + + public NPath Move (NPath dest) + { + ThrowIfRelative (); + + if (IsRoot) + throw new NotSupportedException ("Move is not supported on a root level directory because it would be dangerous:" + ToString ()); + + if (dest.IsRelative) + return Move (Parent.Combine (dest)); + + if (dest.DirectoryExists ()) + return Move (dest.Combine (FileName)); + + if (FileExists ()) { + dest.EnsureParentDirectoryExists (); + File.Move (ToString (), dest.ToString ()); + return dest; + } + + if (DirectoryExists ()) { + Directory.Move (ToString (), dest.ToString ()); + return dest; + } + + throw new ArgumentException ("Move() called on a path that doesn't exist: " + ToString ()); + } + + #endregion + + #region special paths + + public static NPath CurrentDirectory { + get { + return new NPath (Directory.GetCurrentDirectory ()); + } + } + + public static NPath HomeDirectory { + get { + if (Path.DirectorySeparatorChar == '\\') + return new NPath (Environment.GetEnvironmentVariable ("USERPROFILE")!); + return new NPath (Environment.GetEnvironmentVariable ("HOME")!); + } + } + + public static NPath SystemTemp { + get { + return new NPath (Path.GetTempPath ()); + } + } + + #endregion + + private void ThrowIfRelative () + { + if (_isRelative) + throw new ArgumentException ("You are attempting an operation on a Path that requires an absolute path, but the path is relative"); + } + + private void ThrowIfRoot () + { + if (IsRoot) + throw new ArgumentException ("You are attempting an operation that is not valid on a root level directory"); + } + + public NPath EnsureDirectoryExists (string append = "") + { + return EnsureDirectoryExists (new NPath (append)); + } + + public NPath EnsureDirectoryExists (NPath append) + { + var combined = Combine (append); + if (combined.DirectoryExists ()) + return combined; + combined.EnsureParentDirectoryExists (); + combined.CreateDirectory (); + return combined; + } + + public NPath EnsureParentDirectoryExists () + { + var parent = Parent; + parent.EnsureDirectoryExists (); + return parent; + } + + public NPath FileMustExist () + { + if (!FileExists ()) + throw new FileNotFoundException ("File was expected to exist : " + ToString ()); + + return this; + } + + public NPath DirectoryMustExist () + { + if (!DirectoryExists ()) + throw new DirectoryNotFoundException ("Expected directory to exist : " + ToString ()); + + return this; + } + + public bool IsChildOf (string potentialBasePath) + { + return IsChildOf (new NPath (potentialBasePath)); + } + + public bool IsChildOf (NPath potentialBasePath) + { + if ((IsRelative && !potentialBasePath.IsRelative) || !IsRelative && potentialBasePath.IsRelative) + throw new ArgumentException ("You can only call IsChildOf with two relative paths, or with two absolute paths"); + + // If the other path is the root directory, then anything is a child of it as long as it's not a Windows path + if (potentialBasePath.IsRoot) { + if (_driveLetter != potentialBasePath._driveLetter) + return false; + return true; + } + + if (IsEmpty ()) + return false; + + if (Equals (potentialBasePath)) + return true; + + return Parent.IsChildOf (potentialBasePath); + } + + public IEnumerable RecursiveParents { + get { + var candidate = this; + while (true) { + if (candidate.IsEmpty ()) + yield break; + + candidate = candidate.Parent; + yield return candidate; + } + } + } + + public NPath WriteAllText (string contents) + { + ThrowIfRelative (); + EnsureParentDirectoryExists (); + File.WriteAllText (ToString (), contents); + return this; + } + + public string ReadAllText () + { + ThrowIfRelative (); + return File.ReadAllText (ToString ()); + } + + public NPath WriteAllLines (string[] contents) + { + ThrowIfRelative (); + EnsureParentDirectoryExists (); + File.WriteAllLines (ToString (), contents); + return this; + } + + public string[] ReadAllLines () + { + ThrowIfRelative (); + return File.ReadAllLines (ToString ()); + } + + public IEnumerable CopyFiles (NPath destination, bool recurse, Func? fileFilter = null) + { + destination.EnsureDirectoryExists (); + return Files (recurse).Where (fileFilter ?? AlwaysTrue).Select (file => file.Copy (destination.Combine (file.RelativeTo (this)))).ToArray (); + } + + public IEnumerable MoveFiles (NPath destination, bool recurse, Func? fileFilter = null) + { + if (IsRoot) + throw new NotSupportedException ("MoveFiles is not supported on this directory because it would be dangerous:" + ToString ()); + + destination.EnsureDirectoryExists (); + return Files (recurse).Where (fileFilter ?? AlwaysTrue).Select (file => file.Move (destination.Combine (file.RelativeTo (this)))).ToArray (); + } + + static bool AlwaysTrue (NPath p) + { + return true; + } + + private static bool IsLinux () + { + return Directory.Exists ("/proc"); + } + } + + public static class Extensions + { + public static IEnumerable Copy (this IEnumerable self, string dest) + { + return Copy (self, new NPath (dest)); + } + + public static IEnumerable Copy (this IEnumerable self, NPath dest) + { + if (dest.IsRelative) + throw new ArgumentException ("When copying multiple files, the destination cannot be a relative path"); + dest.EnsureDirectoryExists (); + return self.Select (p => p.Copy (dest.Combine (p.FileName))).ToArray (); + } + + public static IEnumerable Move (this IEnumerable self, string dest) + { + return Move (self, new NPath (dest)); + } + + public static IEnumerable Move (this IEnumerable self, NPath dest) + { + if (dest.IsRelative) + throw new ArgumentException ("When moving multiple files, the destination cannot be a relative path"); + dest.EnsureDirectoryExists (); + return self.Select (p => p.Move (dest.Combine (p.FileName))).ToArray (); + } + + public static IEnumerable Delete (this IEnumerable self) + { + foreach (var p in self) + p.Delete (); + return self; + } + + public static IEnumerable InQuotes (this IEnumerable self, SlashMode forward = SlashMode.Native) + { + return self.Select (p => p.InQuotes (forward)); + } + + public static NPath ToNPath (this string path) + { + return new NPath (path); + } + } + + public enum SlashMode + { + Native, + Forward, + Backward + } + + public enum DeleteMode + { + Normal, + Soft + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/Mono.Linker.Tests.csproj b/src/coreclr/tools/aot/Mono.Linker.Tests/Mono.Linker.Tests.csproj new file mode 100644 index 00000000000000..479c971ed03fd7 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/Mono.Linker.Tests.csproj @@ -0,0 +1,51 @@ + + + + $(NetCoreAppToolCurrent) + enable + + false + true + x64;x86 + AnyCPU + + linux-x64;win-x64;osx-x64 + Debug;Release;Checked + + + + + + + + + + + + + + + + $(RuntimeBinDir) + + + $(MicrosoftNetCoreAppRuntimePackRidLibTfmDir) + + + $(Configuration) + + + $(ArtifactsDir) + + + $(ArtifactsBinDir) + + + $(_DirectoryBuildPropsBasePath) + + + $(TargetArchitecture) + + + + diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestCase.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestCase.cs new file mode 100644 index 00000000000000..a9c383d52c2d3d --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestCase.cs @@ -0,0 +1,59 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Linq; +using Mono.Linker.Tests.Extensions; + +namespace Mono.Linker.Tests.TestCases +{ + public class TestCase + { + public TestCase (NPath sourceFile, NPath rootCasesDirectory, NPath originalTestCaseAssemblyPath) + { + SourceFile = sourceFile; + RootCasesDirectory = rootCasesDirectory; + OriginalTestCaseAssemblyPath = originalTestCaseAssemblyPath; + Name = sourceFile.FileNameWithoutExtension; + var fullyRelative = sourceFile.RelativeTo (rootCasesDirectory); + var displayNameRelative = fullyRelative.RelativeTo (new NPath (fullyRelative.Elements.First ())); + string displayNameBase = displayNameRelative.Depth == 1 ? "" : displayNameRelative.Parent.ToString (SlashMode.Forward).Replace ('/', '.') + "."; + DisplayName = $"{displayNameBase}{sourceFile.FileNameWithoutExtension}"; + + // A little hacky, but good enough for name. No reason why namespace & type names + // should not follow the directory structure + //ReconstructedFullTypeName = $"{sourceFile.Parent.RelativeTo (rootCasesDirectory.Parent).ToString (SlashMode.Forward).Replace ('/', '.')}.{sourceFile.FileNameWithoutExtension}"; + ReconstructedFullTypeName = $"Mono.Linker.Tests.Cases.{fullyRelative.Parent.ToString (SlashMode.Forward).Replace ('/', '.')}.{sourceFile.FileNameWithoutExtension}"; + + var firstParentRelativeToRoot = SourceFile.RelativeTo (rootCasesDirectory).Elements.First (); + TestSuiteDirectory = rootCasesDirectory.Combine (firstParentRelativeToRoot); + } + + public NPath RootCasesDirectory { get; } + + public string Name { get; } + + public string DisplayName { get; } + + public NPath SourceFile { get; } + + public NPath OriginalTestCaseAssemblyPath { get; } + + public string ReconstructedFullTypeName { get; } + + public bool HasLinkXmlFile { + get { return SourceFile.ChangeExtension ("xml").FileExists (); } + } + + public NPath LinkXmlFile { + get { + if (!HasLinkXmlFile) + throw new InvalidOperationException ("This test case does not have a link xml file"); + + return SourceFile.ChangeExtension ("xml"); + } + } + + public NPath TestSuiteDirectory { get; } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestDatabase.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestDatabase.cs new file mode 100644 index 00000000000000..71c527c459d772 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestDatabase.cs @@ -0,0 +1,76 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Mono.Linker.Tests.Extensions; +using Mono.Linker.Tests.TestCasesRunner; + +namespace Mono.Linker.Tests.TestCases +{ + public static class TestDatabase + { + private static TestCase[]? _cachedAllCases; + + public static IEnumerable DataFlow () + { + return TestNamesBySuiteName ("DataFlow"); + } + + public static IEnumerable Repro () + { + return TestNamesBySuiteName ("Repro"); + } + + public static IEnumerable RequiresCapability () + { + return TestNamesBySuiteName ("RequiresCapability"); + } + + public static TestCaseCollector CreateCollector () + { + GetDirectoryPaths (out string rootSourceDirectory, out string testCaseAssemblyPath); + return new TestCaseCollector (rootSourceDirectory, testCaseAssemblyPath); + } + + public static NPath TestCasesRootDirectory { + get { + GetDirectoryPaths (out string rootSourceDirectory, out string _); + return rootSourceDirectory.ToNPath (); + } + } + + static IEnumerable AllCases () + { + if (_cachedAllCases == null) + _cachedAllCases = CreateCollector () + .Collect () + .Where (c => c != null) + .OrderBy (c => c.DisplayName) + .ToArray (); + + return _cachedAllCases; + } + + public static TestCase? GetTestCaseFromName (string name) + { + return AllCases ().FirstOrDefault (c => c.Name == name); + } + + static IEnumerable TestNamesBySuiteName (string suiteName) + { + return AllCases () + .Where (c => c.TestSuiteDirectory.FileName == suiteName) + .Select (c => c.DisplayName) + .OrderBy (c => c) + .Select (c => new object[] { c }); + } + + static void GetDirectoryPaths (out string rootSourceDirectory, out string testCaseAssemblyPath) + { + rootSourceDirectory = Path.GetFullPath (Path.Combine (PathUtilities.GetTestsSourceRootDirectory (), "Mono.Linker.Tests.Cases")); + testCaseAssemblyPath = PathUtilities.GetTestAssemblyPath ("Mono.Linker.Tests.Cases"); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestSuites.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestSuites.cs new file mode 100644 index 00000000000000..00cbb1437c10cb --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCases/TestSuites.cs @@ -0,0 +1,45 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using Mono.Linker.Tests.TestCasesRunner; +using Xunit; + +namespace Mono.Linker.Tests.TestCases +{ + public class All + { + + [Theory] + [MemberData(nameof(TestDatabase.DataFlow), MemberType = typeof(TestDatabase))] + public void DataFlow(string t) + { + Run(t); + } + + [Theory] + [MemberData (nameof (TestDatabase.Repro), MemberType = typeof (TestDatabase))] + public void Repro (string t) + { + Run (t); + } + + [Theory] + [MemberData(nameof(TestDatabase.RequiresCapability), MemberType = typeof(TestDatabase))] + public void RequiresCapability(string t) + { + Run(t); + } + + protected virtual void Run(string testName) + { + TestCase testCase = TestDatabase.GetTestCaseFromName(testName) ?? throw new InvalidOperationException($"Unknown test {testName}"); + var runner = new TestRunner(new ObjectFactory()); + var linkedResult = runner.Run(testCase); + if (linkedResult != null) + { + new ResultChecker().Check(linkedResult); + } + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/AssemblyChecker.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/AssemblyChecker.cs new file mode 100644 index 00000000000000..cac049b732ebb4 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/AssemblyChecker.cs @@ -0,0 +1,960 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using FluentAssertions; +using Mono.Cecil; +using Mono.Cecil.Cil; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Extensions; +using Xunit; + +namespace Mono.Linker.Tests.TestCasesRunner +{ + public class AssemblyChecker + { + readonly AssemblyDefinition originalAssembly, linkedAssembly; + + HashSet linkedMembers; + readonly HashSet verifiedGeneratedFields = new HashSet (); + readonly HashSet verifiedEventMethods = new HashSet (); + readonly HashSet verifiedGeneratedTypes = new HashSet (); + bool checkNames; + + public AssemblyChecker (AssemblyDefinition original, AssemblyDefinition linked) + { + this.originalAssembly = original; + this.linkedAssembly = linked; + this.linkedMembers = new (StringComparer.Ordinal); + + checkNames = original.MainModule.GetTypeReferences ().Any (attr => + attr.Name == nameof (RemovedNameValueAttribute)); + } + + public void Verify () + { + VerifyExportedTypes (originalAssembly, linkedAssembly); + + VerifyCustomAttributes (originalAssembly, linkedAssembly); + VerifySecurityAttributes (originalAssembly, linkedAssembly); + + foreach (var originalModule in originalAssembly.Modules) + VerifyModule (originalModule, linkedAssembly.Modules.FirstOrDefault (m => m.Name == originalModule.Name)); + + VerifyResources (originalAssembly, linkedAssembly); + VerifyReferences (originalAssembly, linkedAssembly); + + foreach (var s in linkedAssembly.MainModule.AllMembers ().Select (s => s.FullName)) { + this.linkedMembers.Add (s); + } + + var membersToAssert = originalAssembly.MainModule.Types; + foreach (var originalMember in membersToAssert) { + if (originalMember is TypeDefinition td) { + if (td.Name == "") { + linkedMembers.Remove (td.Name); + continue; + } + + TypeDefinition linkedType = linkedAssembly.MainModule.GetType (originalMember.FullName); + VerifyTypeDefinition (td, linkedType); + linkedMembers.Remove (td.FullName); + + continue; + } + + throw new NotImplementedException ($"Don't know how to check member of type {originalMember.GetType ()}"); + } + + Assert.Empty (linkedMembers); + } + + protected virtual void VerifyModule (ModuleDefinition original, ModuleDefinition? linked) + { + // We never link away a module today so let's make sure the linked one isn't null + if (linked == null) { + Assert.True (false, $"Linked assembly `{original.Assembly.Name.Name}` is missing module `{original.Name}`"); + return; + } + + var expected = original.Assembly.MainModule.AllDefinedTypes () + .SelectMany (t => GetCustomAttributeCtorValues (t, nameof (KeptModuleReferenceAttribute))) + .ToArray (); + + var actual = linked.ModuleReferences + .Select (name => name.Name) + .ToArray (); + + Assert.Equal (expected, actual); + + VerifyCustomAttributes (original, linked); + } + + protected virtual void VerifyTypeDefinition (TypeDefinition original, TypeDefinition? linked) + { + if (linked != null && verifiedGeneratedTypes.Contains (linked.FullName)) + return; + + ModuleDefinition? linkedModule = linked?.Module; + + // + // Little bit complex check to allow easier test writing to match + // - It has [Kept] attribute or any variation of it + // - It contains Main method + // - It contains at least one member which has [Kept] attribute (not recursive) + // + bool expectedKept = + original.HasAttributeDerivedFrom (nameof (KeptAttribute)) || + (linked != null && linkedModule!.Assembly.EntryPoint?.DeclaringType == linked) || + original.AllMembers ().Any (l => l.HasAttribute (nameof (KeptAttribute))); + + if (!expectedKept) { + if (linked != null) + Assert.True (false, $"Type `{original}' should have been removed"); + + return; + } + + bool prev = checkNames; + checkNames |= original.HasAttribute (nameof (VerifyMetadataNamesAttribute)); + + VerifyTypeDefinitionKept (original, linked); + + checkNames = prev; + + if (original.HasAttribute (nameof (CreatedMemberAttribute))) { + foreach (var attr in original.CustomAttributes.Where (l => l.AttributeType.Name == nameof (CreatedMemberAttribute))) { + var newName = original.FullName + "::" + attr.ConstructorArguments[0].Value.ToString (); + + if (linkedMembers!.RemoveWhere (l => l.Contains (newName)) != 1) + Assert.True (false, $"Newly created member '{newName}' was not found"); + } + } + } + + protected virtual void VerifyTypeDefinitionKept (TypeDefinition original, TypeDefinition? linked) + { + if (linked == null) { + Assert.True (false, $"Type `{original}' should have been kept"); + return; + } + + if (!original.IsInterface) + VerifyBaseType (original, linked); + + VerifyInterfaces (original, linked); + VerifyPseudoAttributes (original, linked); + VerifyGenericParameters (original, linked); + VerifyCustomAttributes (original, linked); + VerifySecurityAttributes (original, linked); + + VerifyFixedBufferFields (original, linked); + + foreach (var td in original.NestedTypes) { + VerifyTypeDefinition (td, linked?.NestedTypes.FirstOrDefault (l => td.FullName == l.FullName)); + linkedMembers.Remove (td.FullName); + } + + // Need to check properties before fields so that the KeptBackingFieldAttribute is handled correctly + foreach (var p in original.Properties) { + VerifyProperty (p, linked.Properties.FirstOrDefault (l => p.Name == l.Name), linked); + linkedMembers.Remove (p.FullName); + } + // Need to check events before fields so that the KeptBackingFieldAttribute is handled correctly + foreach (var e in original.Events) { + VerifyEvent (e, linked.Events.FirstOrDefault (l => e.Name == l.Name), linked); + linkedMembers.Remove (e.FullName); + } + + // Need to check delegate cache fields before the normal field check + VerifyDelegateBackingFields (original, linked); + + foreach (var f in original.Fields) { + if (verifiedGeneratedFields.Contains (f.FullName)) + continue; + VerifyField (f, linked.Fields.FirstOrDefault (l => f.Name == l.Name)); + linkedMembers.Remove (f.FullName); + } + + foreach (var m in original.Methods) { + if (verifiedEventMethods.Contains (m.FullName)) + continue; + var msign = m.GetSignature (); + VerifyMethod (m, linked.Methods.FirstOrDefault (l => msign == l.GetSignature ())); + linkedMembers.Remove (m.FullName); + } + } + + void VerifyBaseType (TypeDefinition src, TypeDefinition linked) + { + string expectedBaseName; + var expectedBaseGenericAttr = src.CustomAttributes.FirstOrDefault (w => w.AttributeType.Name == nameof (KeptBaseTypeAttribute) && w.ConstructorArguments.Count > 1); + if (expectedBaseGenericAttr != null) { + expectedBaseName = FormatBaseOrInterfaceAttributeValue (expectedBaseGenericAttr); + } else { + var defaultBaseType = src.IsEnum ? "System.Enum" : src.IsValueType ? "System.ValueType" : "System.Object"; + expectedBaseName = GetCustomAttributeCtorValues (src, nameof (KeptBaseTypeAttribute)).FirstOrDefault ()?.ToString () ?? defaultBaseType; + } + + if (expectedBaseName != linked.BaseType?.FullName) { + Assert.True (false, $"Incorrect base type on : {linked.Name}. Expected {expectedBaseName}, actual {linked.BaseType?.FullName}"); + } + } + + void VerifyInterfaces (TypeDefinition src, TypeDefinition linked) + { + var expectedInterfaces = new HashSet (src.CustomAttributes + .Where (w => w.AttributeType.Name == nameof (KeptInterfaceAttribute)) + .Select (FormatBaseOrInterfaceAttributeValue)); + if (expectedInterfaces.Count == 0) { + Assert.False (linked.HasInterfaces, $"Type `{src}' has unexpected interfaces"); + } else { + foreach (var iface in linked.Interfaces) { + if (!expectedInterfaces.Remove (iface.InterfaceType.FullName)) { + Assert.True (expectedInterfaces.Remove (iface.InterfaceType.Resolve ().FullName), $"Type `{src}' interface `{iface.InterfaceType.Resolve ().FullName}' should have been removed"); + } + } + + if (expectedInterfaces.Count != 0) + Assert.True (false, $"Expected interfaces were not found on {src}"); + } + } + + static string FormatBaseOrInterfaceAttributeValue (CustomAttribute attr) + { + if (attr.ConstructorArguments.Count == 1) + return attr.ConstructorArguments[0].Value.ToString ()!; + + StringBuilder builder = new StringBuilder (); + builder.Append (attr.ConstructorArguments[0].Value); + builder.Append ("<"); + bool separator = false; + foreach (var caa in (CustomAttributeArgument[]) attr.ConstructorArguments[1].Value) { + if (separator) + builder.Append (","); + else + separator = true; + + var arg = (CustomAttributeArgument) caa.Value; + builder.Append (arg.Value); + } + + builder.Append (">"); + return builder.ToString (); + } + + void VerifyField (FieldDefinition src, FieldDefinition? linked) + { + bool expectedKept = ShouldBeKept (src); + + if (!expectedKept) { + if (linked != null) + Assert.True (false, $"Field `{src}' should have been removed"); + + return; + } + + VerifyFieldKept (src, linked); + } + + void VerifyFieldKept (FieldDefinition src, FieldDefinition? linked) + { + if (linked == null) { + Assert.True (false, $"Field `{src}' should have been kept"); + return; + } + + if (!object.Equals (src.Constant, linked.Constant)) { + Assert.True (false, $"Field '{src}' value doesn's match. Expected {src.Constant}, actual {linked.Constant}"); + } + + VerifyPseudoAttributes (src, linked); + VerifyCustomAttributes (src, linked); + } + + void VerifyProperty (PropertyDefinition src, PropertyDefinition? linked, TypeDefinition linkedType) + { + VerifyMemberBackingField (src, linkedType); + + bool expectedKept = ShouldBeKept (src); + + if (!expectedKept) { + if (linked != null) + Assert.True (false, $"Property `{src}' should have been removed"); + + return; + } + + if (linked == null) { + Assert.True (false, $"Property `{src}' should have been kept"); + return; + } + + if (src.Constant != linked.Constant) { + Assert.True (false, $"Property '{src}' value doesn's match. Expected {src.Constant}, actual {linked.Constant}"); + } + + VerifyPseudoAttributes (src, linked); + VerifyCustomAttributes (src, linked); + } + + void VerifyEvent (EventDefinition src, EventDefinition? linked, TypeDefinition linkedType) + { + VerifyMemberBackingField (src, linkedType); + + bool expectedKept = ShouldBeKept (src); + + if (!expectedKept) { + if (linked != null) + Assert.True (false, $"Event `{src}' should have been removed"); + + return; + } + + if (linked == null) { + Assert.True (false, $"Event `{src}' should have been kept"); + return; + } + + if (src.CustomAttributes.Any (attr => attr.AttributeType.Name == nameof (KeptEventAddMethodAttribute))) { + VerifyMethodInternal (src.AddMethod, linked.AddMethod, true); + verifiedEventMethods.Add (src.AddMethod.FullName); + linkedMembers.Remove (src.AddMethod.FullName); + } + + if (src.CustomAttributes.Any (attr => attr.AttributeType.Name == nameof (KeptEventRemoveMethodAttribute))) { + VerifyMethodInternal (src.RemoveMethod, linked.RemoveMethod, true); + verifiedEventMethods.Add (src.RemoveMethod.FullName); + linkedMembers.Remove (src.RemoveMethod.FullName); + } + + VerifyPseudoAttributes (src, linked); + VerifyCustomAttributes (src, linked); + } + + void VerifyMethod (MethodDefinition src, MethodDefinition? linked) + { + bool expectedKept = ShouldMethodBeKept (src); + VerifyMethodInternal (src, linked, expectedKept); + } + + + void VerifyMethodInternal (MethodDefinition src, MethodDefinition? linked, bool expectedKept) + { + if (!expectedKept) { + if (linked != null) + Assert.True (false, $"Method `{src.FullName}' should have been removed"); + + return; + } + + VerifyMethodKept (src, linked); + } + + void VerifyMemberBackingField (IMemberDefinition src, TypeDefinition linkedType) + { + var keptBackingFieldAttribute = src.CustomAttributes.FirstOrDefault (attr => attr.AttributeType.Name == nameof (KeptBackingFieldAttribute)); + if (keptBackingFieldAttribute == null) + return; + + var backingFieldName = src.MetadataToken.TokenType == TokenType.Property + ? $"<{src.Name}>k__BackingField" : src.Name; + var srcField = src.DeclaringType.Fields.FirstOrDefault (f => f.Name == backingFieldName); + + if (srcField == null) { + // Can add more here if necessary + backingFieldName = backingFieldName.Replace ("System.Int32", "int"); + backingFieldName = backingFieldName.Replace ("System.String", "string"); + backingFieldName = backingFieldName.Replace ("System.Char", "char"); + + srcField = src.DeclaringType.Fields.FirstOrDefault (f => f.Name == backingFieldName); + } + + if (srcField == null) { + Assert.True (false, $"{src.MetadataToken.TokenType} `{src}', could not locate the expected backing field {backingFieldName}"); + return; + } + + VerifyFieldKept (srcField, linkedType?.Fields.FirstOrDefault (l => srcField.Name == l.Name)); + verifiedGeneratedFields.Add (srcField.FullName); + linkedMembers.Remove (srcField.FullName); + } + + protected virtual void VerifyMethodKept (MethodDefinition src, MethodDefinition? linked) + { + if (linked == null) { + Assert.True (false, $"Method `{src.FullName}' should have been kept"); + return; + } + + VerifyPseudoAttributes (src, linked); + VerifyGenericParameters (src, linked); + VerifyCustomAttributes (src, linked); + VerifyCustomAttributes (src.MethodReturnType, linked.MethodReturnType); + VerifyParameters (src, linked); + VerifySecurityAttributes (src, linked); + VerifyArrayInitializers (src, linked); + VerifyMethodBody (src, linked); + } + + protected virtual void VerifyMethodBody (MethodDefinition src, MethodDefinition linked) + { + if (!src.HasBody) + return; + + VerifyInstructions (src, linked); + VerifyLocals (src, linked); + } + + protected static void VerifyInstructions (MethodDefinition src, MethodDefinition linked) + { + VerifyBodyProperties ( + src, + linked, + nameof (ExpectedInstructionSequenceAttribute), + nameof (ExpectBodyModifiedAttribute), + "instructions", + m => FormatMethodBody (m.Body), + attr => GetStringArrayAttributeValue (attr)!.ToArray ()); + } + + public static string[] FormatMethodBody (MethodBody body) + { + List<(Instruction?, string)> result = new List<(Instruction?, string)> (body.Instructions.Count); + for (int index = 0; index < body.Instructions.Count; index++) { + var instruction = body.Instructions[index]; + result.Add ((instruction, FormatInstruction (instruction))); + } + + HashSet<(Instruction, Instruction)> existingTryBlocks = new HashSet<(Instruction, Instruction)> (); + foreach (var exHandler in body.ExceptionHandlers) { + if (existingTryBlocks.Add ((exHandler.TryStart, exHandler.TryEnd!))) { + InsertBeforeInstruction (exHandler.TryStart, ".try"); + if (exHandler.TryEnd != null) + InsertBeforeInstruction (exHandler.TryEnd, ".endtry"); + else + Append (".endtry"); + } + + if (exHandler.HandlerStart != null) + InsertBeforeInstruction (exHandler.HandlerStart, ".catch"); + + if (exHandler.HandlerEnd != null) + InsertBeforeInstruction (exHandler.HandlerEnd, ".endcatch"); + else + Append (".endcatch"); + + if (exHandler.FilterStart != null) + InsertBeforeInstruction (exHandler.FilterStart, ".filter"); + } + + return result.Select (i => i.Item2).ToArray (); + + void InsertBeforeInstruction (Instruction instruction, string text) => + result.Insert (result.FindIndex (i => i.Item1 == instruction), (null, text)); + + void Append (string text) => + result.Add ((null, text)); + } + + static string FormatInstruction (Instruction instr) + { + switch (instr.OpCode.FlowControl) { + case FlowControl.Branch: + case FlowControl.Cond_Branch: + if (instr.Operand is Instruction target) + return $"{instr.OpCode.ToString ()} il_{target.Offset.ToString ("x")}"; + + break; + } + + switch (instr.OpCode.Code) { + case Code.Ldc_I4: + if (instr.Operand is int ivalue) + return $"{instr.OpCode.ToString ()} 0x{ivalue.ToString ("x")}"; + + throw new NotImplementedException (instr.Operand.GetType ().ToString ()); + case Code.Ldc_I4_S: + if (instr.Operand is sbyte bvalue) + return $"{instr.OpCode.ToString ()} 0x{bvalue.ToString ("x")}"; + + throw new NotImplementedException (instr.Operand.GetType ().ToString ()); + case Code.Ldc_I8: + if (instr.Operand is long lvalue) + return $"{instr.OpCode.ToString ()} 0x{lvalue.ToString ("x")}"; + + throw new NotImplementedException (instr.Operand.GetType ().ToString ()); + + case Code.Ldc_R4: + if (instr.Operand is float fvalue) + return $"{instr.OpCode.ToString ()} {fvalue.ToString ()}"; + + throw new NotImplementedException (instr.Operand.GetType ().ToString ()); + + case Code.Ldc_R8: + if (instr.Operand is double dvalue) + return $"{instr.OpCode.ToString ()} {dvalue.ToString ()}"; + + throw new NotImplementedException (instr.Operand.GetType ().ToString ()); + + case Code.Ldstr: + if (instr.Operand is string svalue) + return $"{instr.OpCode.ToString ()} '{svalue}'"; + + throw new NotImplementedException (instr.Operand.GetType ().ToString ()); + + default: { + string? operandString = null; + switch (instr.OpCode.OperandType) { + case OperandType.InlineField: + case OperandType.InlineMethod: + case OperandType.InlineType: + case OperandType.InlineTok: + operandString = instr.Operand switch { + FieldReference fieldRef => fieldRef.FullName, + MethodReference methodRef => methodRef.FullName, + TypeReference typeRef => typeRef.FullName, + _ => null + }; + break; + } + + if (operandString != null) + return $"{instr.OpCode.ToString ()} {operandString}"; + else + return instr.OpCode.ToString (); + } + } + } + static void VerifyLocals (MethodDefinition src, MethodDefinition linked) + { + VerifyBodyProperties ( + src, + linked, + nameof (ExpectedLocalsSequenceAttribute), + nameof (ExpectLocalsModifiedAttribute), + "locals", + m => m.Body.Variables.Select (v => v.VariableType.ToString ()).ToArray (), + attr => GetStringOrTypeArrayAttributeValue (attr).ToArray ()); + } + + public static void VerifyBodyProperties (MethodDefinition src, MethodDefinition linked, string sequenceAttributeName, string expectModifiedAttributeName, + string propertyDescription, + Func valueCollector, + Func getExpectFromSequenceAttribute) + { + var expectedSequenceAttribute = src.CustomAttributes.FirstOrDefault (attr => attr.AttributeType.Name == sequenceAttributeName); + var linkedValues = valueCollector (linked); + var srcValues = valueCollector (src); + + if (src.CustomAttributes.Any (attr => attr.AttributeType.Name == expectModifiedAttributeName)) { + linkedValues.Should ().BeEquivalentTo (srcValues, $"Expected method `{src} to have {propertyDescription} modified, however, the {propertyDescription} were the same as the original\n{FormattingUtils.FormatSequenceCompareFailureMessage (linkedValues, srcValues)}"); + } else if (expectedSequenceAttribute != null) { + var expected = getExpectFromSequenceAttribute (expectedSequenceAttribute).ToArray (); + linkedValues.Should ().BeEquivalentTo (expected, $"Expected method `{src} to have it's {propertyDescription} modified, however, the sequence of {propertyDescription} does not match the expected value\n{FormattingUtils.FormatSequenceCompareFailureMessage2 (linkedValues, expected, srcValues)}"); + } else { + linkedValues.Should ().BeEquivalentTo (srcValues, $"Expected method `{src} to have it's {propertyDescription} unchanged, however, the {propertyDescription} differ from the original\n{FormattingUtils.FormatSequenceCompareFailureMessage (linkedValues, srcValues)}"); + } + } + + void VerifyReferences (AssemblyDefinition original, AssemblyDefinition linked) + { + var expected = original.MainModule.AllDefinedTypes () + .SelectMany (t => GetCustomAttributeCtorValues (t, nameof (KeptReferenceAttribute))) + .Select (ReduceAssemblyFileNameOrNameToNameOnly) + .ToArray (); + + /* + - The test case will always need to have at least 1 reference. + - Forcing all tests to define their expected references seems tedious + + Given the above, let's assume that when no [KeptReference] attributes are present, + the test case does not want to make any assertions regarding references. + + Once 1 kept reference attribute is used, the test will need to define all of of it's expected references + */ + if (expected.Length == 0) + return; + + var actual = linked.MainModule.AssemblyReferences + .Select (name => name.Name) + .ToArray (); + + actual.Should ().BeEquivalentTo (expected); + } + + string? ReduceAssemblyFileNameOrNameToNameOnly (string? fileNameOrAssemblyName) + { + if (fileNameOrAssemblyName == null) + return null; + + if (fileNameOrAssemblyName.EndsWith (".dll") || fileNameOrAssemblyName.EndsWith (".exe") || fileNameOrAssemblyName.EndsWith (".winmd")) + return System.IO.Path.GetFileNameWithoutExtension (fileNameOrAssemblyName); + + // It must already be just the assembly name + return fileNameOrAssemblyName; + } + + void VerifyResources (AssemblyDefinition original, AssemblyDefinition linked) + { + var expectedResourceNames = original.MainModule.AllDefinedTypes () + .SelectMany (t => GetCustomAttributeCtorValues (t, nameof (KeptResourceAttribute))) + .ToList (); + + foreach (var resource in linked.MainModule.Resources) { + if (!expectedResourceNames.Remove (resource.Name)) + Assert.True (false, $"Resource '{resource.Name}' should be removed."); + + EmbeddedResource embeddedResource = (EmbeddedResource) resource; + + var expectedResource = (EmbeddedResource) original.MainModule.Resources.First (r => r.Name == resource.Name); + + embeddedResource.GetResourceData ().Should ().BeEquivalentTo (expectedResource.GetResourceData (), $"Resource '{resource.Name}' data doesn't match."); + } + + if (expectedResourceNames.Count > 0) { + Assert.True (false, $"Resource '{expectedResourceNames.First ()}' should be kept."); + } + } + + void VerifyExportedTypes (AssemblyDefinition original, AssemblyDefinition linked) + { + var expectedTypes = original.MainModule.AllDefinedTypes () + .SelectMany (t => GetCustomAttributeCtorValues (t, nameof (KeptExportedTypeAttribute)).Select (l => l?.FullName ?? "")).ToArray (); + + linked.MainModule.ExportedTypes.Select (l => l.FullName).Should ().BeEquivalentTo (expectedTypes); + } + + protected virtual void VerifyPseudoAttributes (MethodDefinition src, MethodDefinition linked) + { + var expected = (MethodAttributes) GetExpectedPseudoAttributeValue (src, (uint) src.Attributes); + linked.Attributes.Should ().Be (expected, $"Method `{src}' pseudo attributes did not match expected"); + } + + protected virtual void VerifyPseudoAttributes (TypeDefinition src, TypeDefinition linked) + { + var expected = (TypeAttributes) GetExpectedPseudoAttributeValue (src, (uint) src.Attributes); + linked.Attributes.Should ().Be (expected, $"Type `{src}' pseudo attributes did not match expected"); + } + + protected virtual void VerifyPseudoAttributes (FieldDefinition src, FieldDefinition linked) + { + var expected = (FieldAttributes) GetExpectedPseudoAttributeValue (src, (uint) src.Attributes); + linked.Attributes.Should ().Be (expected, $"Field `{src}' pseudo attributes did not match expected"); + } + + protected virtual void VerifyPseudoAttributes (PropertyDefinition src, PropertyDefinition linked) + { + var expected = (PropertyAttributes) GetExpectedPseudoAttributeValue (src, (uint) src.Attributes); + linked.Attributes.Should ().Be (expected, $"Property `{src}' pseudo attributes did not match expected"); + } + + protected virtual void VerifyPseudoAttributes (EventDefinition src, EventDefinition linked) + { + var expected = (EventAttributes) GetExpectedPseudoAttributeValue (src, (uint) src.Attributes); + linked.Attributes.Should ().Be (expected, $"Event `{src}' pseudo attributes did not match expected"); + } + + protected virtual void VerifyCustomAttributes (ICustomAttributeProvider src, ICustomAttributeProvider linked) + { + var expectedAttrs = GetExpectedAttributes (src).ToList (); + var linkedAttrs = FilterLinkedAttributes (linked).ToList (); + + linkedAttrs.Should ().BeEquivalentTo (expectedAttrs, $"Custom attributes on `{src}' are not matching"); + } + + protected virtual void VerifySecurityAttributes (ICustomAttributeProvider src, ISecurityDeclarationProvider linked) + { + var expectedAttrs = GetCustomAttributeCtorValues (src, nameof (KeptSecurityAttribute)) + .Select (attr => attr?.ToString () ?? "") + .ToList (); + + var linkedAttrs = FilterLinkedSecurityAttributes (linked).ToList (); + + linkedAttrs.Should ().BeEquivalentTo (expectedAttrs, $"Security attributes on `{src}' are not matching"); + } + + protected virtual void VerifyArrayInitializers (MethodDefinition src, MethodDefinition linked) + { + var expectedIndicies = GetCustomAttributeCtorValues (src, nameof (KeptInitializerData)) + .Cast () + .ToArray (); + + var expectKeptAll = src.CustomAttributes.Any (attr => attr.AttributeType.Name == nameof (KeptInitializerData) && !attr.HasConstructorArguments); + + if (expectedIndicies.Length == 0 && !expectKeptAll) + return; + + if (!src.HasBody) + Assert.True (false, $"`{nameof (KeptInitializerData)}` cannot be used on methods that don't have bodies"); + + var srcImplementationDetails = src.Module.Types.FirstOrDefault (t => string.IsNullOrEmpty (t.Namespace) && t.Name.StartsWith ("")); + + if (srcImplementationDetails == null) { + Assert.True (false, "Could not locate in the original assembly. Does your test use initializers?"); + return; + } + + var linkedImplementationDetails = linked.Module.Types.FirstOrDefault (t => string.IsNullOrEmpty (t.Namespace) && t.Name.StartsWith ("")); + + if (linkedImplementationDetails == null) { + Assert.True (false, "Could not locate in the linked assembly"); + return; + } + + var possibleInitializerFields = src.Body.Instructions + .Where (ins => IsLdtokenOnPrivateImplementationDetails (srcImplementationDetails, ins)) + .Select (ins => ((FieldReference) ins.Operand).Resolve ()) + .ToArray (); + + if (possibleInitializerFields.Length == 0) + Assert.True (false, $"`{src}` does not make use of any initializers"); + + if (expectKeptAll) { + foreach (var srcField in possibleInitializerFields) { + var linkedField = linkedImplementationDetails.Fields.FirstOrDefault (f => f.InitialValue.SequenceEqual (srcField.InitialValue)); + VerifyInitializerField (srcField, linkedField); + } + } else { + foreach (var index in expectedIndicies) { + if (index < 0 || index > possibleInitializerFields.Length) + Assert.True (false, $"Invalid expected index `{index}` in {src}. Value must be between 0 and {expectedIndicies.Length}"); + + var srcField = possibleInitializerFields[index]; + var linkedField = linkedImplementationDetails.Fields.FirstOrDefault (f => f.InitialValue.SequenceEqual (srcField.InitialValue)); + + VerifyInitializerField (srcField, linkedField); + } + } + } + + void VerifyInitializerField (FieldDefinition src, FieldDefinition? linked) + { + VerifyFieldKept (src, linked); + verifiedGeneratedFields.Add (linked!.FullName); + linkedMembers.Remove (linked.FullName); + VerifyTypeDefinitionKept (src.FieldType.Resolve (), linked.FieldType.Resolve ()); + linkedMembers.Remove (linked.FieldType.FullName); + linkedMembers.Remove (linked.DeclaringType.FullName); + verifiedGeneratedTypes.Add (linked.DeclaringType.FullName); + } + + static bool IsLdtokenOnPrivateImplementationDetails (TypeDefinition privateImplementationDetails, Instruction instruction) + { + if (instruction.OpCode.Code == Code.Ldtoken && instruction.Operand is FieldReference field) { + return field.DeclaringType.Resolve () == privateImplementationDetails; + } + + return false; + } + + protected static IEnumerable GetExpectedAttributes (ICustomAttributeProvider original) + { + foreach (var expectedAttrs in GetCustomAttributeCtorValues (original, nameof (KeptAttributeAttribute))) + yield return expectedAttrs?.ToString (); + + // The name of the generated fixed buffer type is a little tricky. + // Some versions of csc name it `e__FixedBuffer0` + // while mcs and other versions of csc name it `__FixedBuffer0` + if (original is TypeDefinition srcDefinition && srcDefinition.Name.Contains ("__FixedBuffer")) { + var name = srcDefinition.Name.Substring (1, srcDefinition.Name.IndexOf ('>') - 1); + var fixedField = srcDefinition.DeclaringType.Fields.FirstOrDefault (f => f.Name == name); + if (fixedField == null) + Assert.True (false, $"Could not locate original fixed field for {srcDefinition}"); + + foreach (var additionalExpectedAttributesFromFixedField in GetCustomAttributeCtorValues (fixedField!, nameof (KeptAttributeOnFixedBufferTypeAttribute))) + yield return additionalExpectedAttributesFromFixedField?.ToString (); + + } + } + + /// + /// Filters out some attributes that should not be taken into consideration when checking the linked result against the expected result + /// + /// + /// + protected virtual IEnumerable FilterLinkedAttributes (ICustomAttributeProvider linked) + { + foreach (var attr in linked.CustomAttributes) { + switch (attr.AttributeType.FullName) { + case "System.Runtime.CompilerServices.RuntimeCompatibilityAttribute": + case "System.Runtime.CompilerServices.CompilerGeneratedAttribute": + continue; + + // When mcs is used to compile the test cases, backing fields end up with this attribute on them + case "System.Diagnostics.DebuggerBrowsableAttribute": + continue; + + // When compiling with roslyn, assemblies get the DebuggableAttribute by default. + case "System.Diagnostics.DebuggableAttribute": + continue; + + case "System.Runtime.CompilerServices.CompilationRelaxationsAttribute": + if (linked is AssemblyDefinition) + continue; + break; + } + + yield return attr.AttributeType.FullName; + } + } + + protected virtual IEnumerable FilterLinkedSecurityAttributes (ISecurityDeclarationProvider linked) + { + return linked.SecurityDeclarations + .SelectMany (d => d.SecurityAttributes) + .Select (attr => attr.AttributeType.ToString ()); + } + + void VerifyFixedBufferFields (TypeDefinition src, TypeDefinition linked) + { + var fields = src.Fields.Where (f => f.CustomAttributes.Any (attr => attr.AttributeType.Name == nameof (KeptFixedBufferAttribute))); + + foreach (var field in fields) { + // The name of the generated fixed buffer type is a little tricky. + // Some versions of csc name it `e__FixedBuffer0` + // while mcs and other versions of csc name it `__FixedBuffer0` + var originalCompilerGeneratedBufferType = src.NestedTypes.FirstOrDefault (t => t.FullName.Contains ($"<{field.Name}>") && t.FullName.Contains ("__FixedBuffer")); + if (originalCompilerGeneratedBufferType == null) { + Assert.True (false, $"Could not locate original compiler generated fixed buffer type for field {field}"); + return; + } + + var linkedCompilerGeneratedBufferType = linked.NestedTypes.FirstOrDefault (t => t.Name == originalCompilerGeneratedBufferType.Name); + if (linkedCompilerGeneratedBufferType == null) { + Assert.True (false, $"Missing expected type {originalCompilerGeneratedBufferType}"); + return; + } + + // Have to verify the field before the type + var originalElementField = originalCompilerGeneratedBufferType.Fields.FirstOrDefault (); + if (originalElementField == null) { + Assert.True (false, $"Could not locate original compiler generated FixedElementField on {originalCompilerGeneratedBufferType}"); + return; + } + + var linkedField = linkedCompilerGeneratedBufferType?.Fields.FirstOrDefault (); + VerifyFieldKept (originalElementField, linkedField); + verifiedGeneratedFields.Add (originalElementField.FullName); + linkedMembers.Remove (linkedField!.FullName); + + VerifyTypeDefinitionKept (originalCompilerGeneratedBufferType, linkedCompilerGeneratedBufferType); + verifiedGeneratedTypes.Add (originalCompilerGeneratedBufferType.FullName); + } + } + + void VerifyDelegateBackingFields (TypeDefinition src, TypeDefinition linked) + { + var expectedFieldNames = GetCustomAttributeCtorValues (src, nameof (KeptDelegateCacheFieldAttribute)) + .Select (unique => $"<>f__mg$cache{unique}") + .ToList (); + + if (expectedFieldNames.Count == 0) + return; + + foreach (var srcField in src.Fields) { + if (!expectedFieldNames.Contains (srcField.Name)) + continue; + + var linkedField = linked?.Fields.FirstOrDefault (l => l.Name == srcField.Name); + VerifyFieldKept (srcField, linkedField); + verifiedGeneratedFields.Add (srcField.FullName); + linkedMembers.Remove (srcField.FullName); + } + } + + void VerifyGenericParameters (IGenericParameterProvider src, IGenericParameterProvider linked) + { + Assert.Equal (src.HasGenericParameters, linked.HasGenericParameters); + if (src.HasGenericParameters) { + for (int i = 0; i < src.GenericParameters.Count; ++i) { + // TODO: Verify constraints + var srcp = src.GenericParameters[i]; + var lnkp = linked.GenericParameters[i]; + VerifyCustomAttributes (srcp, lnkp); + + if (checkNames) { + if (srcp.CustomAttributes.Any (attr => attr.AttributeType.Name == nameof (RemovedNameValueAttribute))) { + string name = (src.GenericParameterType == GenericParameterType.Method ? "!!" : "!") + srcp.Position; + lnkp.Name.Should ().Be (name, "Expected empty generic parameter name"); + } else { + lnkp.Name.Should ().Be (srcp.Name, "Mismatch in generic parameter name"); + } + } + } + } + } + + void VerifyParameters (IMethodSignature src, IMethodSignature linked) + { + Assert.Equal (src.HasParameters, linked.HasParameters); + if (src.HasParameters) { + for (int i = 0; i < src.Parameters.Count; ++i) { + var srcp = src.Parameters[i]; + var lnkp = linked.Parameters[i]; + + VerifyCustomAttributes (srcp, lnkp); + + if (checkNames) { + if (srcp.CustomAttributes.Any (attr => attr.AttributeType.Name == nameof (RemovedNameValueAttribute))) + lnkp.Name.Should ().BeEmpty ("Expected empty parameter name"); + else + lnkp.Name.Should ().Be (srcp.Name, "Mismatch in parameter name"); + } + } + } + } + + protected virtual bool ShouldMethodBeKept (MethodDefinition method) + { + var srcSignature = method.GetSignature (); + return ShouldBeKept (method, srcSignature) || method.DeclaringType.Module.EntryPoint == method; + } + + protected virtual bool ShouldBeKept (T member, string? signature = null) where T : MemberReference, ICustomAttributeProvider + { + if (member.HasAttribute (nameof (KeptAttribute))) + return true; + + ICustomAttributeProvider cap = (ICustomAttributeProvider) member.DeclaringType; + if (cap == null) + return false; + + return GetCustomAttributeCtorValues (cap, nameof (KeptMemberAttribute)).Any (a => a == (signature ?? member.Name)); + } + + protected static uint GetExpectedPseudoAttributeValue (ICustomAttributeProvider provider, uint sourceValue) + { + var removals = provider.CustomAttributes.Where (attr => attr.AttributeType.Name == nameof (RemovedPseudoAttributeAttribute)).ToArray (); + var adds = provider.CustomAttributes.Where (attr => attr.AttributeType.Name == nameof (AddedPseudoAttributeAttribute)).ToArray (); + + return removals.Aggregate (sourceValue, (accum, item) => accum & ~(uint) item.ConstructorArguments[0].Value) | + adds.Aggregate ((uint) 0, (acum, item) => acum | (uint) item.ConstructorArguments[0].Value); + } + + protected static IEnumerable GetCustomAttributeCtorValues (ICustomAttributeProvider provider, string attributeName) where T : class + { + return provider.CustomAttributes. + Where (w => w.AttributeType.Name == attributeName && w.Constructor.Parameters.Count == 1). + Select (l => l.ConstructorArguments[0].Value as T); + } + + protected static IEnumerable GetStringOrTypeArrayAttributeValue (CustomAttribute attribute) + { + foreach (var arg in (CustomAttributeArgument[]) attribute.ConstructorArguments[0].Value) { + if (arg.Value is TypeReference tRef) + yield return tRef.ToString (); + else + yield return (string) arg.Value; + } + } + + protected static IEnumerable? GetStringArrayAttributeValue (CustomAttribute attribute) + { + return ((CustomAttributeArgument[]) attribute.ConstructorArguments[0].Value)?.Select (arg => arg.Value.ToString ()!); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/BaseMetadataProvider.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/BaseMetadataProvider.cs new file mode 100644 index 00000000000000..b136da80846b44 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/BaseMetadataProvider.cs @@ -0,0 +1,96 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Linq; +using Mono.Cecil; +using Mono.Linker.Tests.Extensions; +using Mono.Linker.Tests.TestCases; + +namespace Mono.Linker.Tests.TestCasesRunner +{ + public abstract class BaseMetadataProvider + { + protected readonly TestCase _testCase; + protected readonly TypeDefinition _testCaseTypeDefinition; + + protected BaseMetadataProvider (TestCase testCase, AssemblyDefinition fullTestCaseAssemblyDefinition) + { + _testCase = testCase; + // The test case types are never nested so we don't need to worry about that + _testCaseTypeDefinition = fullTestCaseAssemblyDefinition.MainModule.GetType (_testCase.ReconstructedFullTypeName); + + if (_testCaseTypeDefinition == null) + throw new InvalidOperationException ($"Could not find the type definition for {_testCase.Name} in {_testCase.SourceFile}"); + } + + protected T? GetOptionAttributeValue (string attributeName, T? defaultValue) + { + var attribute = _testCaseTypeDefinition.CustomAttributes.FirstOrDefault (attr => attr.AttributeType.Name == attributeName); + if (attribute != null) + return (T?) attribute.ConstructorArguments.First ().Value; + + return defaultValue; + } + + protected NPath MakeSourceTreeFilePathAbsolute (string value) + { + return _testCase.SourceFile.Parent.Combine (value); + } + + protected SourceAndDestinationPair GetSourceAndRelativeDestinationValue (CustomAttribute attribute) + { + var fullSource = SourceFileForAttributeArgumentValue (attribute.ConstructorArguments.First ().Value); + var destinationFileName = (string) attribute.ConstructorArguments[1].Value; + return new SourceAndDestinationPair { + Source = fullSource, + DestinationFileName = string.IsNullOrEmpty (destinationFileName) ? fullSource.FileName : destinationFileName + }; + } + + + protected virtual NPath SourceFileForAttributeArgumentValue (object value) + { + if (value is TypeReference valueAsTypeRef) { + // Use the parent type for locating the source file + var parentType = ParentMostType (valueAsTypeRef); + var pathRelativeToAssembly = $"{parentType.FullName.Substring (parentType.Module.Name.Length - 3).Replace ('.', '/')}.cs".ToNPath (); + var pathElements = pathRelativeToAssembly.Elements.ToArray (); + var topMostDirectoryName = pathElements[0]; + var topMostDirectory = _testCase.SourceFile.RecursiveParents.Reverse ().FirstOrDefault (d => !d.IsRoot && d.FileName == topMostDirectoryName); + + if (topMostDirectory == null) { + // Before giving up, try and detect the naming scheme for tests that use a dot in the top level directory name. + // Ex: + // Attributes.Debugger + // + 1 because the file name is one of the elements + if (pathElements.Length >= 3) { + topMostDirectoryName = $"{pathElements[0]}.{pathElements[1]}"; + topMostDirectory = _testCase.SourceFile.RecursiveParents.Reverse ().FirstOrDefault (d => !d.IsRoot && d.FileName == topMostDirectoryName); + pathRelativeToAssembly = topMostDirectoryName.ToNPath ().Combine (pathElements.Skip (2).Aggregate (new NPath (string.Empty), (path, s) => path.Combine (s))); + } + + if (topMostDirectory == null) + throw new ArgumentException ($"Unable to locate the source file for type {valueAsTypeRef}. Could not locate directory {topMostDirectoryName}. Ensure the type name matches the file name. And the namespace match the directory structure on disk"); + } + + var fullPath = topMostDirectory.Parent.Combine (pathRelativeToAssembly); + + if (!fullPath.Exists ()) + throw new ArgumentException ($"Unable to locate the source file for type {valueAsTypeRef}. Expected {fullPath}. Ensure the type name matches the file name. And the namespace match the directory structure on disk"); + + return fullPath; + } + + return MakeSourceTreeFilePathAbsolute (value.ToString ()!); + } + + static TypeReference ParentMostType (TypeReference type) + { + if (!type.IsNested) + return type; + + return ParentMostType (type.DeclaringType); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/CompilerOptions.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/CompilerOptions.cs new file mode 100644 index 00000000000000..852576c73dfa0c --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/CompilerOptions.cs @@ -0,0 +1,20 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Mono.Linker.Tests.Extensions; + +#nullable disable + +namespace Mono.Linker.Tests.TestCasesRunner +{ + public class CompilerOptions + { + public NPath OutputPath; + public NPath[] SourceFiles; + public string[] Defines; + public NPath[] References; + public NPath[] Resources; + public string[] AdditionalArguments; + public string CompilerToUse; + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ExpectationsProvider.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ExpectationsProvider.cs new file mode 100644 index 00000000000000..7ca189d9befbde --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ExpectationsProvider.cs @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Mono.Cecil; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; + +namespace Mono.Linker.Tests.TestCasesRunner +{ + public static class ExpectationsProvider + { + + public static bool IsAssemblyAssertion (CustomAttribute attr) + { + return attr.AttributeType.Name == nameof (KeptAssemblyAttribute) || + attr.AttributeType.Name == nameof (RemovedAssemblyAttribute) || + attr.AttributeType.Name == nameof (SetupLinkerActionAttribute) || + attr.AttributeType.Name == nameof (SetupLinkerTrimModeAttribute); + } + + public static bool IsSymbolAssertion (CustomAttribute attr) + { + return attr.AttributeType.Name == nameof (KeptSymbolsAttribute) || attr.AttributeType.Name == nameof (RemovedSymbolsAttribute); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/FormattingUtils.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/FormattingUtils.cs new file mode 100644 index 00000000000000..108e065098add7 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/FormattingUtils.cs @@ -0,0 +1,64 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Mono.Linker.Tests.TestCasesRunner +{ + public static class FormattingUtils + { + public static string FormatSequenceCompareFailureMessage (IEnumerable actual, IEnumerable expected) + { + var builder = new StringBuilder (); + builder.AppendLine ("---------------"); + builder.AppendLine ($"Expected/Original (Total : {expected.Count ()})"); + builder.AppendLine ("---------------"); + // Format in a quoted array form for easier copying into a expected sequence attribute + builder.AppendLine (expected.Select (c => $"\"{c}\",").AggregateWithNewLine ()); + builder.AppendLine ("---------------"); + builder.AppendLine ($"Actual/Linked (Total : {actual.Count ()})"); + builder.AppendLine ("---------------"); + // Format in a quoted array form for easier copying into a expected sequence attribute + builder.AppendLine (actual.Select (c => $"\"{c}\",").AggregateWithNewLine ()); + builder.AppendLine ("---------------"); + return builder.ToString (); + } + + public static string FormatSequenceCompareFailureMessage2 (IEnumerable actual, IEnumerable expected, IEnumerable original) + { + var builder = new StringBuilder (); + builder.AppendLine ("---------------"); + builder.AppendLine ($"Expected (Total : {expected.Count ()})"); + builder.AppendLine ("---------------"); + // Format in a quoted array form for easier copying into a expected sequence attribute + builder.AppendLine (expected.Select (c => $"\"{c}\",").AggregateWithNewLine ()); + builder.AppendLine ("---------------"); + builder.AppendLine ($"Actual/Linked (Total : {actual.Count ()})"); + builder.AppendLine ("---------------"); + // Format in a quoted array form for easier copying into a expected sequence attribute + builder.AppendLine (actual.Select (c => $"\"{c}\",").AggregateWithNewLine ()); + builder.AppendLine ("---------------"); + builder.AppendLine ($"Original (Total : {original.Count ()})"); + builder.AppendLine ("---------------"); + // Format in a quoted array form for easier copying into a expected sequence attribute + builder.AppendLine (original.Select (c => $"\"{c}\",").AggregateWithNewLine ()); + builder.AppendLine ("---------------"); + return builder.ToString (); + } + + private static string AggregateWithNewLine (this IEnumerable elements) + { + return elements.AggregateWith (System.Environment.NewLine); + } + + private static string AggregateWith (this IEnumerable elements, string separator) + { + if (elements.Any ()) + return elements.Aggregate ((buff, s) => buff + separator + s); + + return string.Empty; + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILCompilerDriver.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILCompilerDriver.cs new file mode 100644 index 00000000000000..a0eff369ee98ab --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILCompilerDriver.cs @@ -0,0 +1,137 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.InteropServices; +using ILCompiler; +using ILLink.Shared.TrimAnalysis; +using Internal.IL; +using Internal.TypeSystem; +using Internal.TypeSystem.Ecma; + +namespace Mono.Linker.Tests.TestCasesRunner +{ + public class ILCompilerDriver + { + private const string DefaultSystemModule = "System.Private.CoreLib"; + + public void Trim (ILCompilerOptions options, ILogWriter logWriter) + { + ComputeDefaultOptions (out var targetOS, out var targetArchitecture); + var targetDetails = new TargetDetails (targetArchitecture, targetOS, TargetAbi.NativeAot); + CompilerTypeSystemContext typeSystemContext = + new CompilerTypeSystemContext (targetDetails, SharedGenericsMode.CanonicalReferenceTypes, DelegateFeature.All); + + typeSystemContext.InputFilePaths = options.InputFilePaths; + typeSystemContext.ReferenceFilePaths = options.ReferenceFilePaths; + typeSystemContext.SetSystemModule (typeSystemContext.GetModuleForSimpleName (DefaultSystemModule)); + + List inputModules = new List (); + foreach (var inputFile in typeSystemContext.InputFilePaths) { + EcmaModule module = typeSystemContext.GetModuleFromPath (inputFile.Value); + inputModules.Add (module); + } + + CompilationModuleGroup compilationGroup = new MultiFileSharedCompilationModuleGroup (typeSystemContext, inputModules); + + List compilationRoots = new List (); + EcmaModule? entrypointModule = null; + foreach (var inputFile in typeSystemContext.InputFilePaths) { + EcmaModule module = typeSystemContext.GetModuleFromPath (inputFile.Value); + + if (module.PEReader.PEHeaders.IsExe) { + if (entrypointModule != null) + throw new Exception ("Multiple EXE modules"); + entrypointModule = module; + } + + compilationRoots.Add (new ExportedMethodsRootProvider (module)); + } + + compilationRoots.Add (new MainMethodRootProvider (entrypointModule, CreateInitializerList (typeSystemContext, options))); + + ILProvider ilProvider = new NativeAotILProvider (); + + ilProvider = new FeatureSwitchManager (ilProvider, options.FeatureSwitches); + + Logger logger = new Logger (logWriter, isVerbose: true); + + UsageBasedMetadataManager metadataManager = new UsageBasedMetadataManager ( + compilationGroup, + typeSystemContext, + new NoMetadataBlockingPolicy (), + new ManifestResourceBlockingPolicy (options.FeatureSwitches), + logFile: null, + new NoStackTraceEmissionPolicy (), + new NoDynamicInvokeThunkGenerationPolicy (), + new FlowAnnotations (logger, ilProvider), + UsageBasedMetadataGenerationOptions.ReflectionILScanning, + logger, + Array.Empty> (), + Array.Empty (), + options.TrimAssemblies.ToArray ()); + + CompilationBuilder builder = new RyuJitCompilationBuilder (typeSystemContext, compilationGroup) + .UseILProvider (ilProvider) + .UseCompilationUnitPrefix(""); + + IILScanner scanner = builder.GetILScannerBuilder () + .UseCompilationRoots (compilationRoots) + .UseMetadataManager (metadataManager) + .UseParallelism (System.Diagnostics.Debugger.IsAttached ? 1 : -1) + .ToILScanner (); + + ILScanResults results = scanner.Scan (); + } + + public static void ComputeDefaultOptions (out TargetOS os, out TargetArchitecture arch) + { + if (RuntimeInformation.IsOSPlatform (OSPlatform.Windows)) + os = TargetOS.Windows; + else if (RuntimeInformation.IsOSPlatform (OSPlatform.Linux)) + os = TargetOS.Linux; + else if (RuntimeInformation.IsOSPlatform (OSPlatform.OSX)) + os = TargetOS.OSX; + else if (RuntimeInformation.IsOSPlatform (OSPlatform.FreeBSD)) + os = TargetOS.FreeBSD; + else + throw new NotImplementedException (); + + switch (RuntimeInformation.ProcessArchitecture) { + case Architecture.X86: + arch = TargetArchitecture.X86; + break; + case Architecture.X64: + arch = TargetArchitecture.X64; + break; + case Architecture.Arm: + arch = TargetArchitecture.ARM; + break; + case Architecture.Arm64: + arch = TargetArchitecture.ARM64; + break; + default: + throw new NotImplementedException (); + } + } + + private IReadOnlyCollection CreateInitializerList (CompilerTypeSystemContext context, ILCompilerOptions options) + { + List assembliesWithInitalizers = new List (); + + // Build a list of assemblies that have an initializer that needs to run before + // any user code runs. + foreach (string initAssemblyName in options.InitAssemblies) { + ModuleDesc assembly = context.ResolveAssembly (new AssemblyName (initAssemblyName), throwIfNotFound: true); + assembliesWithInitalizers.Add (assembly); + } + + var libraryInitializers = new LibraryInitializers (context, assembliesWithInitalizers); + + List initializerList = new List (libraryInitializers.LibraryInitializerMethods); + return initializerList; + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILCompilerOptions.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILCompilerOptions.cs new file mode 100644 index 00000000000000..7bba7ae4de334d --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILCompilerOptions.cs @@ -0,0 +1,16 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Collections.Generic; + +namespace Mono.Linker.Tests.TestCasesRunner +{ + public class ILCompilerOptions + { + public Dictionary InputFilePaths = new Dictionary (); + public Dictionary ReferenceFilePaths = new Dictionary (); + public List InitAssemblies = new List (); + public List TrimAssemblies = new List (); + public Dictionary FeatureSwitches = new Dictionary (); + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILCompilerOptionsBuilder.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILCompilerOptionsBuilder.cs new file mode 100644 index 00000000000000..98f0ee4351ef12 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILCompilerOptionsBuilder.cs @@ -0,0 +1,253 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.IO; +using Mono.Linker.Tests.Extensions; + +namespace Mono.Linker.Tests.TestCasesRunner +{ + public class ILCompilerOptionsBuilder + { + //public TrimmerOptions Options { get; } = new(); + private readonly TestCaseMetadataProvider _metadataProvider; + + public readonly ILCompilerOptions Options; + + public ILCompilerOptionsBuilder (TestCaseMetadataProvider metadataProvider) + { + Options = new ILCompilerOptions (); + _metadataProvider = metadataProvider; + + string runtimeBinDir = (string) AppContext.GetData ("Mono.Linker.Tests.RuntimeBinDirectory")!; + AppendExpandedPaths (Options.ReferenceFilePaths, Path.Combine (runtimeBinDir, "aotsdk", "*.dll")); + + string runtimePackDir = (string) AppContext.GetData ("Mono.Linker.Tests.MicrosoftNetCoreAppRuntimePackDirectory")!; + if (!Directory.Exists (runtimePackDir) && runtimePackDir.Contains ("Debug")) { + // Frequently we'll have a Debug runtime and Release libraries, which actually produces a Release runtime pack + // but from within VS we're see Debug everything. So if the runtime pack directory doesn't exist + // try the Release path (simple string replace) + string candidate = runtimePackDir.Replace ("Debug", "Release"); + if (Directory.Exists (candidate)) + runtimePackDir = candidate; + } + AppendExpandedPaths (Options.ReferenceFilePaths, Path.Combine (runtimePackDir, "*.dll")); + + Options.InitAssemblies.Add ("System.Private.CoreLib"); + Options.InitAssemblies.Add ("System.Private.StackTraceMetadata"); + Options.InitAssemblies.Add ("System.Private.TypeLoader"); + Options.InitAssemblies.Add ("System.Private.Reflection.Execution"); + + Options.FeatureSwitches.Add ("System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization", false); + Options.FeatureSwitches.Add ("System.Resources.ResourceManager.AllowCustomResourceTypes", false); + Options.FeatureSwitches.Add ("System.Linq.Expressions.CanCompileToIL", false); + Options.FeatureSwitches.Add ("System.Linq.Expressions.CanEmitObjectArrayDelegate", false); + Options.FeatureSwitches.Add ("System.Linq.Expressions.CanCreateArbitraryDelegates", false); + } + + public virtual void AddSearchDirectory (NPath directory) + { + } + + public virtual void AddReference (NPath path) + { + AppendExpandedPaths (Options.ReferenceFilePaths, path.ToString ()); + } + + public virtual void AddOutputDirectory (NPath directory) + { + } + + public virtual void AddLinkXmlFile (string file) + { + } + + public virtual void AddResponseFile (NPath path) + { + } + + public virtual void AddTrimMode (string value) + { + } + + public virtual void AddDefaultAction (string value) + { + } + + public virtual void AddLinkAssembly (string fileName) + { + Options.TrimAssemblies.Add (fileName); + } + + public virtual void LinkFromAssembly (string fileName) + { + AppendExpandedPaths (Options.InputFilePaths, fileName); + } + + public virtual void LinkFromPublicAndFamily (string fileName) + { + } + + public virtual void IgnoreDescriptors (bool value) + { + } + + public virtual void IgnoreSubstitutions (bool value) + { + } + + public virtual void IgnoreLinkAttributes (bool value) + { + } + + public virtual void AddIl8n (string value) + { + } + + public virtual void AddKeepTypeForwarderOnlyAssemblies (string value) + { + } + + public virtual void AddLinkSymbols (string value) + { + } + + public virtual void AddKeepDebugMembers (string value) + { + } + + public virtual void AddAssemblyAction (string action, string assembly) + { + } + + public virtual void AddSkipUnresolved (bool skipUnresolved) + { + } + + public virtual void AddStripDescriptors (bool stripDescriptors) + { + } + + public virtual void AddStripSubstitutions (bool stripSubstitutions) + { + } + + public virtual void AddStripLinkAttributes (bool stripLinkAttributes) + { + } + + public virtual void AddSubstitutions (string file) + { + } + + public virtual void AddLinkAttributes (string file) + { + } + + public virtual void AddAdditionalArgument (string flag, string[] values) + { + if (flag == "--feature") { + Options.FeatureSwitches.Add (values[0], bool.Parse (values[1])); + } + } + + public virtual void ProcessTestInputAssembly (NPath inputAssemblyPath) + { + if (_metadataProvider.LinkPublicAndFamily ()) + LinkFromPublicAndFamily (inputAssemblyPath.ToString ()); + else + LinkFromAssembly (inputAssemblyPath.ToString ()); + } + + public virtual void ProcessOptions (TestCaseLinkerOptions options) + { + if (options.TrimMode != null) + AddTrimMode (options.TrimMode); + + if (options.DefaultAssembliesAction != null) + AddDefaultAction (options.DefaultAssembliesAction); + + if (options.AssembliesAction != null) { + foreach (var (action, assembly) in options.AssembliesAction) + AddAssemblyAction (action, assembly); + } + + // Honoring descriptors causes a ton of stuff to be preserved. That's good for normal use cases, but for + // our test cases that pollutes the results + IgnoreDescriptors (options.IgnoreDescriptors); + + IgnoreSubstitutions (options.IgnoreSubstitutions); + + IgnoreLinkAttributes (options.IgnoreLinkAttributes); + +#if !NETCOREAPP + if (!string.IsNullOrEmpty (options.Il8n)) + AddIl8n (options.Il8n); +#endif + + if (!string.IsNullOrEmpty (options.KeepTypeForwarderOnlyAssemblies)) + AddKeepTypeForwarderOnlyAssemblies (options.KeepTypeForwarderOnlyAssemblies); + + if (!string.IsNullOrEmpty (options.LinkSymbols)) + AddLinkSymbols (options.LinkSymbols); + + if (!string.IsNullOrEmpty (options.KeepDebugMembers)) + AddKeepDebugMembers (options.KeepDebugMembers); + + AddSkipUnresolved (options.SkipUnresolved); + + AddStripDescriptors (options.StripDescriptors); + + AddStripSubstitutions (options.StripSubstitutions); + + AddStripLinkAttributes (options.StripLinkAttributes); + + foreach (var descriptor in options.Descriptors) + AddLinkXmlFile (descriptor); + + foreach (var substitutions in options.Substitutions) + AddSubstitutions (substitutions); + + foreach (var attributeDefinition in options.LinkAttributes) + AddLinkAttributes (attributeDefinition); + + // A list of expensive optimizations which should not run by default + AddAdditionalArgument ("--disable-opt", new[] { "ipconstprop" }); + + // Unity uses different argument format and needs to be able to translate to their format. In order to make that easier + // we keep the information in flag + values format for as long as we can so that this information doesn't have to be parsed out of a single string + foreach (var additionalArgument in options.AdditionalArguments) + AddAdditionalArgument (additionalArgument.Key, additionalArgument.Value); + } + + static void AppendExpandedPaths (Dictionary dictionary, string pattern) + { + bool empty = true; + + string directoryName = Path.GetDirectoryName (pattern)!; + string searchPattern = Path.GetFileName (pattern); + + if (directoryName == "") + directoryName = "."; + + if (Directory.Exists (directoryName)) { + foreach (string fileName in Directory.EnumerateFiles (directoryName, searchPattern)) { + string fullFileName = Path.GetFullPath (fileName); + + string simpleName = Path.GetFileNameWithoutExtension (fileName); + + if (!dictionary.ContainsKey (simpleName)) { + dictionary.Add (simpleName, fullFileName); + } + + empty = false; + } + } + + if (empty) { + throw new Exception ("No files matching " + pattern); + } + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILCompilerTestCaseResult.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILCompilerTestCaseResult.cs new file mode 100644 index 00000000000000..8fe4bfe8b8e71f --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILCompilerTestCaseResult.cs @@ -0,0 +1,31 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Mono.Linker.Tests.TestCasesRunner; +using Mono.Linker.Tests.Extensions; +using Mono.Linker.Tests.TestCases; + +namespace Mono.Linker.Tests.TestCasesRunner +{ + public class ILCompilerTestCaseResult + { + public readonly TestCase TestCase; + public readonly NPath InputAssemblyPath; + public readonly NPath ExpectationsAssemblyPath; + public readonly TestCaseSandbox Sandbox; + public readonly TestCaseMetadataProvider MetadataProvider; + public readonly ManagedCompilationResult CompilationResult; + public readonly TestLogWriter LogWriter; + + public ILCompilerTestCaseResult (TestCase testCase, NPath inputAssemblyPath, NPath expectationsAssemblyPath, TestCaseSandbox sandbox, TestCaseMetadataProvider metadataProvider, ManagedCompilationResult compilationResult, TestLogWriter logWriter) + { + TestCase = testCase; + InputAssemblyPath = inputAssemblyPath; + ExpectationsAssemblyPath = expectationsAssemblyPath; + Sandbox = sandbox; + MetadataProvider = metadataProvider; + CompilationResult = compilationResult; + LogWriter = logWriter; + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILInputCompiler.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILInputCompiler.cs new file mode 100644 index 00000000000000..32973f050fa6ea --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ILInputCompiler.cs @@ -0,0 +1,93 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using Mono.Linker.Tests.Extensions; +using Xunit; + +namespace Mono.Linker.Tests.TestCasesRunner +{ + public class ILInputCompiler + { + public NPath Compile (CompilerOptions options) + { + var capturedOutput = new List (); + var process = new Process (); + SetupProcess (process, options); + process.StartInfo.RedirectStandardOutput = true; + process.OutputDataReceived += (sender, args) => capturedOutput.Add (args.Data!); + process.Start (); + process.BeginOutputReadLine (); + process.WaitForExit (); + + if (process.ExitCode != 0) { + Assert.True (false, $"Failed to compile IL assembly : {options.OutputPath}\n{capturedOutput.Aggregate ((buff, s) => buff + Environment.NewLine + s)}"); + } + + return options.OutputPath; + } + + protected virtual void SetupProcess (Process process, CompilerOptions options) + { + process.StartInfo.FileName = LocateIlasm ().ToString (); + process.StartInfo.Arguments = BuildArguments (options); + process.StartInfo.UseShellExecute = false; + process.StartInfo.CreateNoWindow = true; + process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + } + + private string BuildArguments (CompilerOptions options) + { + var args = new StringBuilder (); +#if NETCOREAPP + args.Append (options.OutputPath.ExtensionWithDot == ".dll" ? "-dll" : "-exe"); + args.Append ($" -out:{options.OutputPath.InQuotes ()}"); +#else + args.Append (options.OutputPath.ExtensionWithDot == ".dll" ? "/dll" : "/exe"); + args.Append ($" /out:{options.OutputPath.InQuotes ()}"); +#endif + args.Append ($" {options.SourceFiles.Aggregate (string.Empty, (buff, file) => $"{buff} {file.InQuotes ()}")}"); + return args.ToString (); + } + + protected virtual NPath LocateIlasm () + { +#if NETCOREAPP + var extension = RuntimeInformation.IsOSPlatform (OSPlatform.Windows) ? ".exe" : ""; + + // working directory is artifacts/bin/Mono.Linker.Tests// + var toolsDir = Path.Combine (Directory.GetCurrentDirectory (), "..", "..", "..", "..", "tools"); + + var ilasmPath = Path.GetFullPath (Path.Combine (toolsDir, "ilasm", $"ilasm{extension}")).ToNPath (); + if (ilasmPath.FileExists ()) + return ilasmPath; + + throw new InvalidOperationException ("ilasm not found at " + ilasmPath); +#else + return Environment.OSVersion.Platform == PlatformID.Win32NT ? LocateIlasmOnWindows () : "ilasm".ToNPath (); +#endif + } + + public static NPath LocateIlasmOnWindows () + { + if (Environment.OSVersion.Platform != PlatformID.Win32NT) + throw new InvalidOperationException ("This method should only be called on windows"); + + var possiblePath = RuntimeEnvironment.GetRuntimeDirectory ().ToNPath ().Combine ("ilasm.exe"); + if (possiblePath.FileExists ()) + return possiblePath; + + possiblePath = Environment.CurrentDirectory.ToNPath ().Combine ("ilasm.exe"); + if (possiblePath.FileExists ()) + return possiblePath; + + throw new InvalidOperationException ("Could not locate a ilasm.exe executable"); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/IgnoreTestException.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/IgnoreTestException.cs new file mode 100644 index 00000000000000..767bc07454fcb9 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/IgnoreTestException.cs @@ -0,0 +1,12 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; + +namespace Mono.Linker.Tests.TestCasesRunner +{ + internal class IgnoreTestException : Exception + { + public IgnoreTestException (string message) : base (message) { } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ManagedCompilationResult.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ManagedCompilationResult.cs new file mode 100644 index 00000000000000..fe7aa4c767da19 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ManagedCompilationResult.cs @@ -0,0 +1,20 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Mono.Linker.Tests.Extensions; + +namespace Mono.Linker.Tests.TestCasesRunner +{ + public class ManagedCompilationResult + { + public ManagedCompilationResult (NPath inputAssemblyPath, NPath expectationsAssemblyPath) + { + InputAssemblyPath = inputAssemblyPath; + ExpectationsAssemblyPath = expectationsAssemblyPath; + } + + public NPath InputAssemblyPath { get; } + + public NPath ExpectationsAssemblyPath { get; } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ObjectFactory.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ObjectFactory.cs new file mode 100644 index 00000000000000..f99a06ad15062d --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ObjectFactory.cs @@ -0,0 +1,41 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Mono.Cecil; +using Mono.Linker.Tests.TestCases; + +namespace Mono.Linker.Tests.TestCasesRunner +{ + public class ObjectFactory + { + public virtual TestCaseSandbox CreateSandbox (TestCase testCase) + { + return new TestCaseSandbox (testCase); + } + + public virtual TestCaseCompiler CreateCompiler (TestCaseSandbox sandbox, TestCaseCompilationMetadataProvider metadataProvider) + { + return new TestCaseCompiler (sandbox, metadataProvider); + } + + public virtual ILCompilerDriver CreateTrimmer () + { + return new ILCompilerDriver (); + } + + public virtual TestCaseMetadataProvider CreateMetadataProvider (TestCase testCase, AssemblyDefinition expectationsAssemblyDefinition) + { + return new TestCaseMetadataProvider (testCase, expectationsAssemblyDefinition); + } + + public virtual TestCaseCompilationMetadataProvider CreateCompilationMetadataProvider (TestCase testCase, AssemblyDefinition fullTestCaseAssemblyDefinition) + { + return new TestCaseCompilationMetadataProvider (testCase, fullTestCaseAssemblyDefinition); + } + + public virtual ILCompilerOptionsBuilder CreateTrimmerOptionsBuilder (TestCaseMetadataProvider metadataProvider) + { + return new ILCompilerOptionsBuilder (metadataProvider); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/PathUtilities.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/PathUtilities.cs new file mode 100644 index 00000000000000..5fb2090ac65e3a --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/PathUtilities.cs @@ -0,0 +1,35 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.IO; +using System.Runtime.CompilerServices; + +namespace Mono.Linker.Tests.TestCasesRunner +{ + public static class PathUtilities + { +#if NET7_0 + public const string TFMDirectoryName = "net7.0"; +#elif NET6_0 + public const string TFMDirectoryName = "net6.0"; +#elif NET5_0 + public const string TFMDirectoryName = "net5.0"; +#elif NETCOREAPP3_0 + public const string TFMDirectoryName = "netcoreapp3.0"; +#else +#error "Unknown TFM" +#endif + + public static string GetTestsSourceRootDirectory ([CallerFilePath] string? thisFile = null) => + Path.GetFullPath ((string) AppContext.GetData ("Mono.Linker.Tests.NativeAotDir")!); + + public static string GetTestAssemblyPath (string assemblyName) + { + var artifactsBinDirectory = (string) AppContext.GetData ("Mono.Linker.Tests.ArtifactsBinDir")!; + var targetArch = (string) AppContext.GetData ("Mono.Linker.Tests.TargetArchitecture")!; + var configuration = (string) AppContext.GetData ("Mono.Linker.Tests.Configuration")!; + return Path.GetFullPath (Path.Combine (artifactsBinDirectory, assemblyName, targetArch, configuration, $"{assemblyName}.dll")); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs new file mode 100644 index 00000000000000..cd3a1c2eca2511 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/ResultChecker.cs @@ -0,0 +1,405 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection.Metadata.Ecma335; +using System.Reflection.PortableExecutable; +using System.Runtime.CompilerServices; +using System.Text; +using System.Text.RegularExpressions; +using FluentAssertions; +using ILCompiler; +using ILCompiler.Dataflow; +using ILCompiler.Logging; +using Mono.Linker.Tests.TestCasesRunner; +using Internal.TypeSystem; +using Mono.Cecil; +using Mono.Cecil.Cil; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; +using Mono.Linker.Tests.Extensions; +using Xunit; +using Mono.Linker.Tests.Cases.RequiresCapability; + +namespace Mono.Linker.Tests.TestCasesRunner +{ + public class ResultChecker + { + readonly BaseAssemblyResolver _originalsResolver; + readonly ReaderParameters _originalReaderParameters; + readonly ReaderParameters _linkedReaderParameters; + + public ResultChecker () + : this (new TestCaseAssemblyResolver (), + new ReaderParameters { + SymbolReaderProvider = new DefaultSymbolReaderProvider (false) + }, + new ReaderParameters { + SymbolReaderProvider = new DefaultSymbolReaderProvider (false) + }) + { + } + + public ResultChecker (BaseAssemblyResolver originalsResolver, + ReaderParameters originalReaderParameters, ReaderParameters linkedReaderParameters) + { + _originalsResolver = originalsResolver; + _originalReaderParameters = originalReaderParameters; + _linkedReaderParameters = linkedReaderParameters; + } + + public virtual void Check (ILCompilerTestCaseResult trimmedResult) + { + InitializeResolvers (trimmedResult); + + try { + var original = ResolveOriginalsAssembly (trimmedResult.ExpectationsAssemblyPath.FileNameWithoutExtension); + AdditionalChecking (trimmedResult, original); + } finally { + _originalsResolver.Dispose (); + } + } + + void InitializeResolvers (ILCompilerTestCaseResult linkedResult) + { + _originalsResolver.AddSearchDirectory (linkedResult.ExpectationsAssemblyPath.Parent.ToString ()); + } + + protected AssemblyDefinition ResolveOriginalsAssembly (string assemblyName) + { + var cleanAssemblyName = assemblyName; + if (assemblyName.EndsWith (".exe") || assemblyName.EndsWith (".dll")) + cleanAssemblyName = Path.GetFileNameWithoutExtension (assemblyName); + return _originalsResolver.Resolve (new AssemblyNameReference (cleanAssemblyName, null), _originalReaderParameters); + } + + protected virtual void AdditionalChecking (ILCompilerTestCaseResult linkResult, AssemblyDefinition original) + { + bool checkRemainingErrors = !HasAttribute (original.MainModule.GetType (linkResult.TestCase.ReconstructedFullTypeName), nameof (SkipRemainingErrorsValidationAttribute)); + VerifyLoggedMessages (original, linkResult.LogWriter, checkRemainingErrors); + } + + static bool IsProducedByNativeAOT (CustomAttribute attr) + { + var producedBy = attr.GetPropertyValue ("ProducedBy"); + return producedBy is null ? true : ((ProducedBy) producedBy).HasFlag (ProducedBy.NativeAot); + } + + static IEnumerable GetAttributeProviders (AssemblyDefinition assembly) + { + foreach (var testType in assembly.AllDefinedTypes ()) { + foreach (var provider in testType.AllMembers ()) + yield return provider; + + yield return testType; + } + + foreach (var module in assembly.Modules) + yield return module; + + yield return assembly; + } + + void VerifyLoggedMessages (AssemblyDefinition original, TestLogWriter logger, bool checkRemainingErrors) + { + List loggedMessages = logger.GetLoggedMessages (); + List<(IMemberDefinition, CustomAttribute)> expectedNoWarningsAttributes = new List<(IMemberDefinition, CustomAttribute)> (); + foreach (var attrProvider in GetAttributeProviders (original)) { + if (attrProvider.ToString() is String mystring && mystring.Contains ("RequiresInCompilerGeneratedCode/SuppressInLambda")) + Debug.WriteLine ("Print"); + foreach (var attr in attrProvider.CustomAttributes) { + if (!IsProducedByNativeAOT (attr)) + continue; + + switch (attr.AttributeType.Name) { + + case nameof (LogContainsAttribute): { + var expectedMessage = (string) attr.ConstructorArguments[0].Value; + + List matchedMessages; + if ((bool) attr.ConstructorArguments[1].Value) + matchedMessages = loggedMessages.Where (m => Regex.IsMatch (m.ToString (), expectedMessage)).ToList (); + else + matchedMessages = loggedMessages.Where (m => MessageTextContains (m.ToString (), expectedMessage)).ToList (); ; + Assert.True ( + matchedMessages.Count > 0, + $"Expected to find logged message matching `{expectedMessage}`, but no such message was found.{Environment.NewLine}Logged messages:{Environment.NewLine}{string.Join (Environment.NewLine, loggedMessages)}"); + + foreach (var matchedMessage in matchedMessages) + loggedMessages.Remove (matchedMessage); + } + break; + + case nameof (LogDoesNotContainAttribute): { + var unexpectedMessage = (string) attr.ConstructorArguments[0].Value; + foreach (var loggedMessage in loggedMessages) { + var isLogged = () => { + if ((bool) attr.ConstructorArguments[1].Value) + return !Regex.IsMatch (loggedMessage.ToString (), unexpectedMessage); + return !MessageTextContains (loggedMessage.ToString (), unexpectedMessage); + }; + + Assert.True ( + isLogged (), + $"Expected to not find logged message matching `{unexpectedMessage}`, but found:{Environment.NewLine}{loggedMessage.ToString ()}{Environment.NewLine}Logged messages:{Environment.NewLine}{string.Join (Environment.NewLine, loggedMessages)}"); + } + } + break; + + case nameof (ExpectedWarningAttribute): { + var expectedWarningCode = (string) attr.GetConstructorArgumentValue (0); + if (!expectedWarningCode.StartsWith ("IL")) { + Assert.Fail ($"The warning code specified in {nameof (ExpectedWarningAttribute)} must start with the 'IL' prefix. Specified value: '{expectedWarningCode}'."); + } + var expectedMessageContains = ((CustomAttributeArgument[]) attr.GetConstructorArgumentValue (1)).Select (a => (string) a.Value).ToArray (); + string fileName = (string) attr.GetPropertyValue ("FileName")!; + int? sourceLine = (int?) attr.GetPropertyValue ("SourceLine"); + int? sourceColumn = (int?) attr.GetPropertyValue ("SourceColumn"); + bool? isCompilerGeneratedCode = (bool?) attr.GetPropertyValue ("CompilerGeneratedCode"); + + int expectedWarningCodeNumber = int.Parse (expectedWarningCode.Substring (2)); + string? expectedOrigin = null; + bool expectedWarningFound = false; + + foreach (var loggedMessage in loggedMessages) { + if (loggedMessage.ToString ().Contains ("RequiresInCompilerGeneratedCode.SuppressInLambda")) { + Debug.WriteLine ("Print 2"); + } + + if (loggedMessage.Category != MessageCategory.Warning || loggedMessage.Code != expectedWarningCodeNumber) + continue; + + bool messageNotFound = false; + foreach (var expectedMessage in expectedMessageContains) { + if (!MessageTextContains (loggedMessage.Text, expectedMessage)) { + messageNotFound = true; + break; + } + } + if (messageNotFound) + continue; + + if (fileName != null) { + if (loggedMessage.Origin == null) + continue; + + var actualOrigin = loggedMessage.Origin.Value; + if (actualOrigin.FileName != null) { + // Note: string.Compare(string, StringComparison) doesn't exist in .NET Framework API set + if (actualOrigin.FileName.IndexOf (fileName, StringComparison.OrdinalIgnoreCase) < 0) + continue; + + if (sourceLine != null && loggedMessage.Origin?.SourceLine != sourceLine.Value) + continue; + + if (sourceColumn != null && loggedMessage.Origin?.SourceColumn != sourceColumn.Value) + continue; + } else { + // The warning was logged with member/ILoffset, so it didn't have line/column info filled + // but it will be computed from PDBs, so instead compare it in a string representation + if (expectedOrigin == null) { + expectedOrigin = fileName; + if (sourceLine.HasValue) { + expectedOrigin += "(" + sourceLine.Value; + if (sourceColumn.HasValue) + expectedOrigin += "," + sourceColumn.Value; + expectedOrigin += ")"; + } + } + + string actualOriginString = actualOrigin.ToString () ?? ""; + if (!actualOriginString.EndsWith (expectedOrigin, StringComparison.OrdinalIgnoreCase)) + continue; + } + } else if (isCompilerGeneratedCode == true) { + if (loggedMessage.Origin?.MemberDefinition is MethodDesc methodDesc) { + if (attrProvider is not IMemberDefinition expectedMember) + continue; + + string actualName = methodDesc.OwningType.ToString ().Replace("+", ".") + "." + methodDesc.Name; + if (actualName.Contains (expectedMember.DeclaringType.FullName.Replace ("/", ".")) && + actualName.Contains ("<" + expectedMember.Name + ">")) { + expectedWarningFound = true; + loggedMessages.Remove (loggedMessage); + break; + } + if (actualName.StartsWith (expectedMember.DeclaringType.FullName) && + actualName.Contains (".cctor") && (expectedMember is FieldDefinition || expectedMember is PropertyDefinition)) { + expectedWarningFound = true; + loggedMessages.Remove (loggedMessage); + break; + } + if (methodDesc.Name == ".ctor" && + methodDesc.OwningType.ToString () == expectedMember.FullName) { + expectedWarningFound = true; + loggedMessages.Remove (loggedMessage); + break; + } + } + continue; + } else { + if (LogMessageHasSameOriginMember (loggedMessage, attrProvider)) { + expectedWarningFound = true; + loggedMessages.Remove (loggedMessage); + break; + } + continue; + } + + expectedWarningFound = true; + loggedMessages.Remove (loggedMessage); + break; + } + + var expectedOriginString = fileName == null + ? GetExpectedOriginDisplayName (attrProvider) + ": " + : ""; + + Assert.True (expectedWarningFound, + $"Expected to find warning: {(fileName != null ? fileName + (sourceLine != null ? $"({sourceLine},{sourceColumn})" : "") + ": " : "")}" + + $"warning {expectedWarningCode}: {expectedOriginString}" + + $"and message containing {string.Join (" ", expectedMessageContains.Select (m => "'" + m + "'"))}, " + + $"but no such message was found.{Environment.NewLine}Logged messages:{Environment.NewLine}{string.Join (Environment.NewLine, loggedMessages)}"); + } + break; + + case nameof (ExpectedNoWarningsAttribute): + // Postpone processing of negative checks, to make it possible to mark some warnings as expected (will be removed from the list above) + // and then do the negative check on the rest. + var memberDefinition = attrProvider as IMemberDefinition; + Assert.NotNull (memberDefinition); + expectedNoWarningsAttributes.Add ((memberDefinition, attr)); + break; + } + } + } + + foreach ((var attrProvider, var attr) in expectedNoWarningsAttributes) { + var unexpectedWarningCode = attr.ConstructorArguments.Count == 0 ? null : (string) attr.GetConstructorArgumentValue (0); + if (unexpectedWarningCode != null && !unexpectedWarningCode.StartsWith ("IL")) { + Assert.Fail ($"The warning code specified in ExpectedNoWarnings attribute must start with the 'IL' prefix. Specified value: '{unexpectedWarningCode}'."); + } + + int? unexpectedWarningCodeNumber = unexpectedWarningCode == null ? null : int.Parse (unexpectedWarningCode.Substring (2)); + + MessageContainer? unexpectedWarningMessage = null; + foreach (var mc in logger.GetLoggedMessages ()) { + if (mc.Category != MessageCategory.Warning) + continue; + + if (unexpectedWarningCodeNumber != null && unexpectedWarningCodeNumber.Value != mc.Code) + continue; + + // This is a hacky way to say anything in the "subtree" of the attrProvider + if ((mc.Origin?.MemberDefinition is TypeSystemEntity member) && member.ToString ()?.Contains (attrProvider.FullName) != true) + continue; + + unexpectedWarningMessage = mc; + break; + } + + Assert.False (unexpectedWarningMessage.HasValue, + $"Unexpected warning found: {unexpectedWarningMessage}"); + } + + if (checkRemainingErrors) { + var remainingErrors = loggedMessages.Where (m => Regex.IsMatch (m.ToString (), @".*(error | warning): \d{4}.*")); + Assert.False (remainingErrors.Any (), $"Found unexpected errors:{Environment.NewLine}{string.Join (Environment.NewLine, remainingErrors)}"); + } + + bool LogMessageHasSameOriginMember (MessageContainer mc, ICustomAttributeProvider expectedOriginProvider) + { + var origin = mc.Origin; + Debug.Assert (origin != null); + if (GetActualOriginDisplayName (origin?.MemberDefinition) == ConvertSignatureToIlcFormat (GetExpectedOriginDisplayName (expectedOriginProvider))) + return true; + + var actualMember = origin!.Value.MemberDefinition; + // Compensate for cases where for some reason the OM doesn't preserve the declaring types + // on certain things after trimming. + if (actualMember != null && GetOwningType (actualMember) == null && + GetMemberName (actualMember) == (expectedOriginProvider as IMemberDefinition)?.Name) + return true; + + return false; + } + + static TypeDesc? GetOwningType (TypeSystemEntity entity) => entity switch { + DefType defType => defType.ContainingType, + MethodDesc method => method.OwningType, + FieldDesc field => field.OwningType, + _ => null + }; + + static string? GetMemberName (TypeSystemEntity? entity) => entity switch { + DefType defType => defType.Name, + MethodDesc method => method.Name, + FieldDesc field => field.Name, + _ => null + }; + + static string? GetActualOriginDisplayName (TypeSystemEntity? entity) => entity switch { + DefType defType => TrimAssemblyNamePrefix (defType.ToString ()), + MethodDesc method => TrimAssemblyNamePrefix (method.GetDisplayName ()), + FieldDesc field => TrimAssemblyNamePrefix (field.ToString ()), + ModuleDesc module => module.Assembly.GetName ().Name, + _ => null + }; + + static string TrimAssemblyNamePrefix (string name) + { + if (name.StartsWith ('[')) { + int i = name.IndexOf (']'); + if (i > 0) { + return name.Substring (i + 1); + } + } + + return name; + } + + static string GetExpectedOriginDisplayName (ICustomAttributeProvider provider) => + provider switch { + MethodDefinition method => method.GetDisplayName (), + FieldDefinition field => field.GetDisplayName (), + IMemberDefinition member => member.FullName, + AssemblyDefinition asm => asm.Name.Name, + _ => throw new NotImplementedException () + }; + + static bool MessageTextContains (string message, string value) + { + // This is a workaround for different formatting of methods between ilc and linker/analyzer + // Sometimes they're written with a space after comma and sometimes without + // Method(String,String) - ilc + // Method(String, String) - linker/analyzer + return message.Contains (value) || message.Contains (ConvertSignatureToIlcFormat (value)); + } + + static string ConvertSignatureToIlcFormat (string value) + { + if (value.Contains ('(') || value.Contains ('<')) { + value = value.Replace (", ", ","); + } + + return value; + } + } + + static bool HasAttribute (ICustomAttributeProvider caProvider, string attributeName) + { + if (caProvider is AssemblyDefinition assembly && assembly.EntryPoint != null) + return assembly.EntryPoint.DeclaringType.CustomAttributes + .Any (attr => attr.AttributeType.Name == attributeName); + + if (caProvider is TypeDefinition type) + return type.CustomAttributes.Any (attr => attr.AttributeType.Name == attributeName); + + return false; + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/SetupCompileInfo.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/SetupCompileInfo.cs new file mode 100644 index 00000000000000..37883af7d3bdaf --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/SetupCompileInfo.cs @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Mono.Linker.Tests.Extensions; + +#nullable disable + +namespace Mono.Linker.Tests.TestCasesRunner +{ + public class SetupCompileInfo + { + public string OutputName; + public NPath[] SourceFiles; + public string[] Defines; + public string[] References; + public SourceAndDestinationPair[] Resources; + public string AdditionalArguments; + public string CompilerToUse; + public bool AddAsReference; + public bool RemoveFromLinkerInput; + public string OutputSubFolder; + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/SourceAndDestinationPair.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/SourceAndDestinationPair.cs new file mode 100644 index 00000000000000..52d333d9caf6a5 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/SourceAndDestinationPair.cs @@ -0,0 +1,15 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Mono.Linker.Tests.Extensions; + +#nullable disable + +namespace Mono.Linker.Tests.TestCasesRunner +{ + public class SourceAndDestinationPair + { + public NPath Source; + public string DestinationFileName; + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseAssemblyResolver.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseAssemblyResolver.cs new file mode 100644 index 00000000000000..dec3270905e447 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseAssemblyResolver.cs @@ -0,0 +1,43 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using Mono.Cecil; + +namespace Mono.Linker.Tests.TestCasesRunner +{ + public class TestCaseAssemblyResolver : DefaultAssemblyResolver + { + readonly HashSet itemsToDispose; + + public TestCaseAssemblyResolver () + { + itemsToDispose = new HashSet (); + } + + public override AssemblyDefinition? Resolve (AssemblyNameReference name, ReaderParameters parameters) + { + var assembly = base.Resolve (name, parameters); + + if (assembly == null) + return null; + + // Don't do any caching because the reader parameters could be different each time + // but we still want to track items that need to be disposed for easy clean up + itemsToDispose.Add (assembly); + + if (assembly.MainModule.SymbolReader != null) + itemsToDispose.Add (assembly.MainModule.SymbolReader); + return assembly; + } + + protected override void Dispose (bool disposing) + { + foreach (var item in itemsToDispose) + item.Dispose (); + + base.Dispose (disposing); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseCollector.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseCollector.cs new file mode 100644 index 00000000000000..1f9fe04d70e11d --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseCollector.cs @@ -0,0 +1,165 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Linq; +using Mono.Cecil; +using Mono.Linker.Tests.Cases.Expectations.Metadata; +using Mono.Linker.Tests.Extensions; +using Mono.Linker.Tests.TestCases; + +namespace Mono.Linker.Tests.TestCasesRunner +{ + public class TestCaseCollector + { + private readonly NPath _rootDirectory; + private readonly NPath _testCaseAssemblyPath; + + public TestCaseCollector (string rootDirectory, string testCaseAssemblyPath) + : this (rootDirectory.ToNPath (), testCaseAssemblyPath.ToNPath ()) + { + } + + public TestCaseCollector (NPath rootDirectory, NPath testCaseAssemblyPath) + { + _rootDirectory = rootDirectory; + _testCaseAssemblyPath = testCaseAssemblyPath; + } + + public IEnumerable Collect () + { + return Collect (AllSourceFiles ()); + } + + public TestCase? Collect (NPath sourceFile) + { + return Collect (new[] { sourceFile }).FirstOrDefault (); + } + + public IEnumerable Collect (IEnumerable sourceFiles) + { + _rootDirectory.DirectoryMustExist (); + _testCaseAssemblyPath.FileMustExist (); + + using (var caseAssemblyDefinition = AssemblyDefinition.ReadAssembly (_testCaseAssemblyPath.ToString ())) { + foreach (var file in sourceFiles) { + if (CreateCase (caseAssemblyDefinition, file, out TestCase? testCase) && testCase != null) + yield return testCase; + } + } + } + + public IEnumerable AllSourceFiles () + { + _rootDirectory.DirectoryMustExist (); + + foreach (var file in _rootDirectory.Files ("*.cs")) { + yield return file; + } + + foreach (var subDir in _rootDirectory.Directories ()) { + if (subDir.FileName == "bin" || subDir.FileName == "obj" || subDir.FileName == "Properties") + continue; + + foreach (var file in subDir.Files ("*.cs", true)) { + + var relativeParents = file.RelativeTo (_rootDirectory); + // Magic : Anything in a directory named Dependencies is assumed to be a dependency to a test case + // and never a test itself + // This makes life a little easier when writing these supporting files as it removes some constraints you would previously have + // had to follow such as ensuring a class exists that matches the file name and putting [NotATestCase] on that class + if (relativeParents.RecursiveParents.Any (p => p.Elements.Any () && p.FileName == "Dependencies")) + continue; + + // Magic: Anything in a directory named Individual is expected to be ran by it's own [Test] rather than as part of [TestCaseSource] + if (relativeParents.RecursiveParents.Any (p => p.Elements.Any () && p.FileName == "Individual")) + continue; + + yield return file; + } + } + } + + public TestCase? CreateIndividualCase (Type testCaseType) + { + _rootDirectory.DirectoryMustExist (); + _testCaseAssemblyPath.FileMustExist (); + + var pathRelativeToAssembly = $"{testCaseType.FullName?.Substring (testCaseType.Module.Name.Length - 3).Replace ('.', '/')}.cs"; + var fullSourcePath = _rootDirectory.Combine (pathRelativeToAssembly).FileMustExist (); + + using (var caseAssemblyDefinition = AssemblyDefinition.ReadAssembly (_testCaseAssemblyPath.ToString ())) { + if (!CreateCase (caseAssemblyDefinition, fullSourcePath, out TestCase? testCase)) + throw new ArgumentException ($"Could not create a test case for `{testCaseType}`. Ensure the namespace matches it's location on disk"); + + return testCase; + } + } + + private bool CreateCase (AssemblyDefinition caseAssemblyDefinition, NPath sourceFile, out TestCase? testCase) + { + var potentialCase = new TestCase (sourceFile, _rootDirectory, _testCaseAssemblyPath); + + var typeDefinition = FindTypeDefinition (caseAssemblyDefinition, potentialCase); + + testCase = null; + + if (typeDefinition == null) { + Console.WriteLine ($"Could not find the matching type for test case {sourceFile}. Ensure the file name and class name match"); + return false; + } + + if (typeDefinition.HasAttribute (nameof (NotATestCaseAttribute))) { + return false; + } + + // Verify the class as a static main method + var mainMethod = typeDefinition.Methods.FirstOrDefault (m => m.Name == "Main"); + + if (mainMethod == null) { + Console.WriteLine ($"{typeDefinition} in {sourceFile} is missing a Main() method"); + return false; + } + + if (!mainMethod.IsStatic) { + Console.WriteLine ($"The Main() method for {typeDefinition} in {sourceFile} should be static"); + return false; + } + + testCase = potentialCase; + return true; + } + + private static TypeDefinition? FindTypeDefinition (AssemblyDefinition caseAssemblyDefinition, TestCase testCase) + { + var typeDefinition = caseAssemblyDefinition.MainModule.GetType (testCase.ReconstructedFullTypeName); + + // For all of the Test Cases, the full type name we constructed from the directory structure will be correct and we can successfully find + // the type from GetType. + if (typeDefinition != null) + return typeDefinition; + + // However, some of types are supporting types rather than test cases. and may not follow the standardized naming scheme of the test cases + // We still need to be able to locate these type defs so that we can parse some of the metadata on them. + // One example, Unity run's into this with it's tests that require a type UnityEngine.MonoBehaviours to exist. This tpe is defined in it's own + // file and it cannot follow our standardized naming directory & namespace naming scheme since the namespace must be UnityEngine + foreach (var type in caseAssemblyDefinition.MainModule.Types) { + // Let's assume we should never have to search for a test case that has no namespace. If we don't find the type from GetType, then o well, that's not a test case. + if (string.IsNullOrEmpty (type.Namespace)) + continue; + + if (type.Name == testCase.Name) { + // This isn't foolproof, but let's do a little extra vetting to make sure the type we found corresponds to the source file we are + // processing. + if (!testCase.SourceFile.ReadAllText ().Contains ($"namespace {type.Namespace}")) + continue; + + return type; + } + } + + return null; + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseCompilationMetadataProvider.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseCompilationMetadataProvider.cs new file mode 100644 index 00000000000000..1aa354f58176b3 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseCompilationMetadataProvider.cs @@ -0,0 +1,242 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Linq; +using Mono.Cecil; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; +using Mono.Linker.Tests.Extensions; +using Mono.Linker.Tests.TestCases; + +namespace Mono.Linker.Tests.TestCasesRunner +{ + public class TestCaseCompilationMetadataProvider : BaseMetadataProvider + { + + public TestCaseCompilationMetadataProvider (TestCase testCase, AssemblyDefinition fullTestCaseAssemblyDefinition) + : base (testCase, fullTestCaseAssemblyDefinition) + { + + } + + public virtual TestRunCharacteristics Characteristics => + TestRunCharacteristics.TargetingNetCore | TestRunCharacteristics.SupportsDefaultInterfaceMethods | TestRunCharacteristics.SupportsStaticInterfaceMethods; + + public virtual bool IsIgnored ([NotNullWhen(true)] out string? reason) + { + var ignoreAttribute = _testCaseTypeDefinition.CustomAttributes.FirstOrDefault (attr => attr.AttributeType.Name == nameof (IgnoreTestCaseAttribute)); + if (ignoreAttribute != null) { + if (ignoreAttribute.ConstructorArguments.Count == 1) { + reason = (string) ignoreAttribute.ConstructorArguments.First ().Value; + return true; + } else { + throw new ArgumentException ($"Unhandled {nameof (IgnoreTestCaseAttribute)} constructor with {ignoreAttribute.ConstructorArguments} arguments"); + } + } + + var requirementsAttribute = _testCaseTypeDefinition.CustomAttributes.FirstOrDefault (attr => attr.AttributeType.Name == nameof (TestCaseRequirementsAttribute)); + if (requirementsAttribute != null) { + if (requirementsAttribute.ConstructorArguments.Count == 2) { + var testCaseRequirements = (TestRunCharacteristics) requirementsAttribute.ConstructorArguments[0].Value; + + foreach (var value in Enum.GetValues (typeof (TestRunCharacteristics))) { + if (IsRequirementMissing ((TestRunCharacteristics) value, testCaseRequirements)) { + reason = (string) requirementsAttribute.ConstructorArguments[1].Value; + return true; + } + } + } else { + throw new ArgumentException ($"Unhandled {nameof (TestCaseRequirementsAttribute)} constructor with {requirementsAttribute.ConstructorArguments} arguments"); + } + } + + reason = null; + return false; + } + + bool IsRequirementMissing (TestRunCharacteristics requirement, TestRunCharacteristics testCaseRequirements) + { + return testCaseRequirements.HasFlag (requirement) && !Characteristics.HasFlag (requirement); + } + + public virtual IEnumerable GetDefines () + { + // There are a few tests related to native pdbs where the assertions are different between windows and non-windows + // To enable test cases to define different expected behavior we set this special define + if (Environment.OSVersion.Platform == PlatformID.Win32NT) + yield return "WIN32"; + + if (Characteristics.HasFlag (TestRunCharacteristics.TargetingNetCore)) + yield return "NETCOREAPP"; + + if (Characteristics.HasFlag (TestRunCharacteristics.SupportsDefaultInterfaceMethods)) + yield return "SUPPORTS_DEFAULT_INTERFACE_METHODS"; + + foreach (var attr in _testCaseTypeDefinition.CustomAttributes.Where (attr => attr.AttributeType.Name == nameof (DefineAttribute))) + yield return (string) attr.ConstructorArguments.First ().Value; + } + + public virtual string GetAssemblyName () + { + var asLibraryAttribute = _testCaseTypeDefinition.CustomAttributes + .FirstOrDefault (attr => attr.AttributeType.Name == nameof (SetupCompileAsLibraryAttribute)); + var defaultName = asLibraryAttribute == null ? "test.exe" : "test.dll"; + return GetOptionAttributeValue (nameof (SetupCompileAssemblyNameAttribute), defaultName)!; + } + + public virtual string GetCSharpCompilerToUse () + { + return GetOptionAttributeValue (nameof (SetupCSharpCompilerToUseAttribute), string.Empty)!.ToLower (); + } + + public virtual IEnumerable GetSetupCompilerArguments () + { + return _testCaseTypeDefinition.CustomAttributes + .Where (attr => attr.AttributeType.Name == nameof (SetupCompileArgumentAttribute)) + .Select (attr => (string) attr.ConstructorArguments.First ().Value); + } + + public virtual IEnumerable AdditionalFilesToSandbox () + { + return _testCaseTypeDefinition.CustomAttributes + .Where (attr => attr.AttributeType.Name == nameof (SandboxDependencyAttribute)) + .Select (GetSourceAndRelativeDestinationValue); + } + + static string GetReferenceDir () + { + string runtimeDir = Path.GetDirectoryName (typeof (object).Assembly.Location)!; + string ncaVersion = Path.GetFileName (runtimeDir); + string dotnetDir = Path.GetDirectoryName (Path.GetDirectoryName (Path.GetDirectoryName (runtimeDir)))!; + return Path.Combine (dotnetDir, "packs", "Microsoft.NETCore.App.Ref", ncaVersion, "ref", PathUtilities.TFMDirectoryName); + } + + public virtual IEnumerable GetCommonReferencedAssemblies (NPath workingDirectory) + { + yield return workingDirectory.Combine ("Mono.Linker.Tests.Cases.Expectations.dll").ToString (); + if (Characteristics.HasFlag (TestRunCharacteristics.TargetingNetCore)) { + string referenceDir = GetReferenceDir (); + + yield return Path.Combine (referenceDir, "mscorlib.dll"); + yield return Path.Combine (referenceDir, "System.Collections.dll"); + yield return Path.Combine (referenceDir, "System.ComponentModel.TypeConverter.dll"); + yield return Path.Combine (referenceDir, "System.Console.dll"); + yield return Path.Combine (referenceDir, "System.Linq.Expressions.dll"); + yield return Path.Combine (referenceDir, "System.ObjectModel.dll"); + yield return Path.Combine (referenceDir, "System.Runtime.dll"); + yield return Path.Combine (referenceDir, "System.Runtime.Extensions.dll"); + yield return Path.Combine (referenceDir, "System.Runtime.InteropServices.dll"); + } else { + yield return "mscorlib.dll"; + } + } + + public virtual IEnumerable GetReferencedAssemblies (NPath workingDirectory) + { + foreach (var fileName in GetReferenceValues ()) { + + if (fileName.StartsWith ("System.", StringComparison.Ordinal) || fileName.StartsWith ("Mono.", StringComparison.Ordinal) || fileName.StartsWith ("Microsoft.", StringComparison.Ordinal)) { + if (Characteristics.HasFlag (TestRunCharacteristics.TargetingNetCore)) { + var referenceDir = GetReferenceDir (); + var filePath = Path.Combine (referenceDir, fileName); + + if (File.Exists (filePath)) { + yield return filePath; + } else { + yield return fileName; + } + } else { + yield return fileName; + } + } else { + // Drop any relative path information. Sandboxing will have taken care of copying the reference to the directory + yield return workingDirectory.Combine (Path.GetFileName (fileName)); + } + } + } + + public virtual IEnumerable GetReferenceDependencies () + { + return _testCaseTypeDefinition.CustomAttributes + .Where (attr => attr.AttributeType.Name == nameof (ReferenceDependencyAttribute)) + .Select (attr => (string) attr.ConstructorArguments[0].Value); + } + + public virtual IEnumerable GetReferenceValues () + { + foreach (var referenceAttr in _testCaseTypeDefinition.CustomAttributes.Where (attr => attr.AttributeType.Name == nameof (ReferenceAttribute))) + yield return (string) referenceAttr.ConstructorArguments.First ().Value; + } + + public virtual IEnumerable GetResources () + { + return _testCaseTypeDefinition.CustomAttributes + .Where (attr => attr.AttributeType.Name == nameof (SetupCompileResourceAttribute)) + .Select (GetSourceAndRelativeDestinationValue); + } + + public virtual IEnumerable GetSetupCompileAssembliesBefore () + { + return _testCaseTypeDefinition.CustomAttributes + .Where (attr => attr.AttributeType.Name == nameof (SetupCompileBeforeAttribute)) + .Select (CreateSetupCompileAssemblyInfo); + } + + public virtual IEnumerable GetSetupCompileAssembliesAfter () + { + return _testCaseTypeDefinition.CustomAttributes + .Where (attr => attr.AttributeType.Name == nameof (SetupCompileAfterAttribute)) + .Select (CreateSetupCompileAssemblyInfo); + } + + private SetupCompileInfo CreateSetupCompileAssemblyInfo (CustomAttribute attribute) + { + var ctorArguments = attribute.ConstructorArguments; + return new SetupCompileInfo { + OutputName = (string) ctorArguments[0].Value, + SourceFiles = SourceFilesForAttributeArgument (ctorArguments[1]), + References = ((CustomAttributeArgument[]) ctorArguments[2].Value)?.Select (arg => arg.Value.ToString ()).ToArray (), + Defines = ((CustomAttributeArgument[]) ctorArguments[3].Value)?.Select (arg => arg.Value.ToString ()).ToArray (), + Resources = ResourcesForAttributeArgument (ctorArguments[4]), + AdditionalArguments = (string) ctorArguments[5].Value, + CompilerToUse = (string) ctorArguments[6].Value, + AddAsReference = ctorArguments.Count >= 8 ? (bool) ctorArguments[7].Value : true, + RemoveFromLinkerInput = ctorArguments.Count >= 9 ? (bool) ctorArguments[8].Value : false, + OutputSubFolder = ctorArguments.Count >= 10 ? (string) ctorArguments[9].Value : null + }; + } + + protected NPath[] SourceFilesForAttributeArgument (CustomAttributeArgument attributeArgument) + { + return ((CustomAttributeArgument[]) attributeArgument.Value) + .Select (attributeArg => SourceFileForAttributeArgumentValue (attributeArg.Value)) + .Distinct () + .ToArray (); + } + + protected SourceAndDestinationPair[]? ResourcesForAttributeArgument (CustomAttributeArgument attributeArgument) + { + return ((CustomAttributeArgument[]) attributeArgument.Value) + ?.Select (arg => { + var referenceArg = (CustomAttributeArgument) arg.Value; + if (referenceArg.Value is string source) { + var fullSource = MakeSourceTreeFilePathAbsolute (source); + return new SourceAndDestinationPair { + Source = fullSource, + DestinationFileName = fullSource.FileName + }; + } + var sourceAndDestination = (CustomAttributeArgument[]) referenceArg.Value; + return new SourceAndDestinationPair { + Source = MakeSourceTreeFilePathAbsolute (sourceAndDestination[0].Value!.ToString ()!), + DestinationFileName = sourceAndDestination[1].Value!.ToString ()! + }; + }) + ?.ToArray (); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseCompiler.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseCompiler.cs new file mode 100644 index 00000000000000..3f47904efa69ec --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseCompiler.cs @@ -0,0 +1,411 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using Mono.Linker.Tests.Extensions; +using Xunit; +#if NETCOREAPP +using System.Runtime.InteropServices; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Emit; +using Microsoft.CodeAnalysis.CSharp; +#endif + +namespace Mono.Linker.Tests.TestCasesRunner +{ + public class TestCaseCompiler + { + protected readonly TestCaseCompilationMetadataProvider _metadataProvider; + protected readonly TestCaseSandbox _sandbox; + protected readonly ILInputCompiler _ilCompiler; + + public TestCaseCompiler (TestCaseSandbox sandbox, TestCaseCompilationMetadataProvider metadataProvider) + : this (sandbox, metadataProvider, new ILInputCompiler ()) + { + } + + public TestCaseCompiler (TestCaseSandbox sandbox, TestCaseCompilationMetadataProvider metadataProvider, ILInputCompiler ilCompiler) + { + _ilCompiler = ilCompiler; + _sandbox = sandbox; + _metadataProvider = metadataProvider; + } + + public NPath CompileTestIn (NPath outputDirectory, string outputName, IEnumerable sourceFiles, string[] commonReferences, string[] mainAssemblyReferences, IEnumerable? defines, NPath[] resources, string[] additionalArguments) + { + var originalCommonReferences = commonReferences.Select (r => r.ToNPath ()).ToArray (); + var originalDefines = defines?.ToArray () ?? new string[0]; + + Prepare (outputDirectory); + + var removeFromLinkerInputAssemblies = new List (); + var compiledReferences = CompileBeforeTestCaseAssemblies (outputDirectory, originalCommonReferences, originalDefines, removeFromLinkerInputAssemblies).ToArray (); + var allTestCaseReferences = originalCommonReferences + .Concat (compiledReferences) + .Concat (mainAssemblyReferences.Select (r => r.ToNPath ())) + .ToArray (); + + var options = CreateOptionsForTestCase ( + outputDirectory.Combine (outputName), + sourceFiles.Select (s => s.ToNPath ()).ToArray (), + allTestCaseReferences, + originalDefines, + resources, + additionalArguments); + var testAssembly = CompileAssembly (options); + + + // The compile after step is used by tests to mess around with the input to the linker. Generally speaking, it doesn't seem like we would ever want to mess with the + // expectations assemblies because this would undermine our ability to inspect them for expected results during ResultChecking. The UnityLinker UnresolvedHandling tests depend on this + // behavior of skipping the after test compile + if (outputDirectory != _sandbox.ExpectationsDirectory) { + CompileAfterTestCaseAssemblies (outputDirectory, originalCommonReferences, originalDefines, removeFromLinkerInputAssemblies); + + foreach (var assemblyToRemove in removeFromLinkerInputAssemblies) + assemblyToRemove.DeleteIfExists (); + } + + return testAssembly; + } + + protected virtual void Prepare (NPath outputDirectory) + { + } + + protected virtual CompilerOptions CreateOptionsForTestCase (NPath outputPath, NPath[] sourceFiles, NPath[] references, string[] defines, NPath[] resources, string[] additionalArguments) + { + return new CompilerOptions { + OutputPath = outputPath, + SourceFiles = sourceFiles, + References = references, + Defines = defines.Concat (_metadataProvider.GetDefines ()).ToArray (), + Resources = resources, + AdditionalArguments = additionalArguments, + CompilerToUse = _metadataProvider.GetCSharpCompilerToUse () + }; + } + + protected virtual CompilerOptions CreateOptionsForSupportingAssembly (SetupCompileInfo setupCompileInfo, NPath outputDirectory, NPath[] sourceFiles, NPath[] references, string[] defines, NPath[] resources) + { + var allDefines = defines.Concat (setupCompileInfo.Defines ?? new string[0]).ToArray (); + var allReferences = references.Concat (setupCompileInfo.References?.Select (p => MakeSupportingAssemblyReferencePathAbsolute (outputDirectory, p)) ?? new NPath[0]).ToArray (); + string[]? additionalArguments = string.IsNullOrEmpty (setupCompileInfo.AdditionalArguments) ? null : new[] { setupCompileInfo.AdditionalArguments }; + return new CompilerOptions { + OutputPath = outputDirectory.Combine (setupCompileInfo.OutputName), + SourceFiles = sourceFiles, + References = allReferences, + Defines = allDefines, + Resources = resources, + AdditionalArguments = additionalArguments, + CompilerToUse = setupCompileInfo.CompilerToUse?.ToLower () + }; + } + + private IEnumerable CompileBeforeTestCaseAssemblies (NPath outputDirectory, NPath[] references, string[] defines, IList removeFromLinkerInputAssemblies) + { + foreach (var setupCompileInfo in _metadataProvider.GetSetupCompileAssembliesBefore ()) { + NPath outputFolder; + if (setupCompileInfo.OutputSubFolder == null) { + outputFolder = outputDirectory; + } else { + outputFolder = outputDirectory.Combine (setupCompileInfo.OutputSubFolder); + Directory.CreateDirectory (outputFolder.ToString ()); + } + + var options = CreateOptionsForSupportingAssembly ( + setupCompileInfo, + outputFolder, + CollectSetupBeforeSourcesFiles (setupCompileInfo), + references, + defines, + CollectSetupBeforeResourcesFiles (setupCompileInfo)); + var output = CompileAssembly (options); + + if (setupCompileInfo.RemoveFromLinkerInput) + removeFromLinkerInputAssemblies.Add (output); + + if (setupCompileInfo.AddAsReference) + yield return output; + } + } + + private void CompileAfterTestCaseAssemblies (NPath outputDirectory, NPath[] references, string[] defines, IList removeFromLinkerInputAssemblies) + { + foreach (var setupCompileInfo in _metadataProvider.GetSetupCompileAssembliesAfter ()) { + var options = CreateOptionsForSupportingAssembly ( + setupCompileInfo, + outputDirectory, + CollectSetupAfterSourcesFiles (setupCompileInfo), + references, + defines, + CollectSetupAfterResourcesFiles (setupCompileInfo)); + var output = CompileAssembly (options); + + if (setupCompileInfo.RemoveFromLinkerInput) + removeFromLinkerInputAssemblies.Add (output); + } + } + + private NPath[] CollectSetupBeforeSourcesFiles (SetupCompileInfo info) + { + return CollectSourceFilesFrom (_sandbox.BeforeReferenceSourceDirectoryFor (info.OutputName)); + } + + private NPath[] CollectSetupAfterSourcesFiles (SetupCompileInfo info) + { + return CollectSourceFilesFrom (_sandbox.AfterReferenceSourceDirectoryFor (info.OutputName)); + } + + private NPath[] CollectSetupBeforeResourcesFiles (SetupCompileInfo info) + { + return _sandbox.BeforeReferenceResourceDirectoryFor (info.OutputName).Files ().ToArray (); + } + + private NPath[] CollectSetupAfterResourcesFiles (SetupCompileInfo info) + { + return _sandbox.AfterReferenceResourceDirectoryFor (info.OutputName).Files ().ToArray (); + } + + private static NPath[] CollectSourceFilesFrom (NPath directory) + { + var sourceFiles = directory.Files ("*.cs").ToArray (); + if (sourceFiles.Length > 0) + return sourceFiles; + + sourceFiles = directory.Files ("*.il").ToArray (); + if (sourceFiles.Length > 0) + return sourceFiles; + + throw new FileNotFoundException ($"Didn't find any sources files in {directory}"); + } + + protected static NPath MakeSupportingAssemblyReferencePathAbsolute (NPath outputDirectory, string referenceFileName) + { + // Not a good idea to use a full path in a test, but maybe someone is trying to quickly test something locally + if (Path.IsPathRooted (referenceFileName)) + return referenceFileName.ToNPath (); + +#if NETCOREAPP + if (referenceFileName.StartsWith ("System.", StringComparison.Ordinal) || + referenceFileName.StartsWith ("Mono.", StringComparison.Ordinal) || + referenceFileName.StartsWith ("Microsoft.", StringComparison.Ordinal) || + referenceFileName == "netstandard.dll") { + + var frameworkDir = Path.GetFullPath (Path.GetDirectoryName (typeof (object).Assembly.Location)!); + var filePath = Path.Combine (frameworkDir, referenceFileName); + + if (File.Exists (filePath)) + return filePath.ToNPath (); + } +#endif + + var possiblePath = outputDirectory.Combine (referenceFileName); + if (possiblePath.FileExists ()) + return possiblePath; + + return referenceFileName.ToNPath (); + } + + protected NPath CompileAssembly (CompilerOptions options) + { + if (options.SourceFiles.Any (path => path.ExtensionWithDot == ".cs")) + return CompileCSharpAssembly (options); + + if (options.SourceFiles.Any (path => path.ExtensionWithDot == ".il")) + return CompileIlAssembly (options); + + throw new NotSupportedException ($"Unable to compile sources files with extension `{options.SourceFiles.First ().ExtensionWithDot}`"); + } + + protected virtual NPath CompileCSharpAssemblyWithDefaultCompiler (CompilerOptions options) + { +#if NETCOREAPP + return CompileCSharpAssemblyWithRoslyn (options); +#else + return CompileCSharpAssemblyWithCsc (options); +#endif + } + +#if NETCOREAPP + protected virtual NPath CompileCSharpAssemblyWithRoslyn (CompilerOptions options) + { + var languageVersion = LanguageVersion.Default; + var compilationOptions = new CSharpCompilationOptions ( + outputKind: options.OutputPath.FileName.EndsWith (".exe") ? OutputKind.ConsoleApplication : OutputKind.DynamicallyLinkedLibrary, + assemblyIdentityComparer: DesktopAssemblyIdentityComparer.Default + ); + // Default debug info format for the current platform. + DebugInformationFormat debugType = RuntimeInformation.IsOSPlatform (OSPlatform.Windows) ? DebugInformationFormat.Pdb : DebugInformationFormat.PortablePdb; + bool emitPdb = false; + if (options.AdditionalArguments != null) { + foreach (var option in options.AdditionalArguments) { + switch (option) { + case "/unsafe": + compilationOptions = compilationOptions.WithAllowUnsafe (true); + break; + case "/optimize+": + compilationOptions = compilationOptions.WithOptimizationLevel (OptimizationLevel.Release); + break; + case "/debug:full": + case "/debug:pdbonly": + // Use platform's default debug info. This behavior is the same as csc. + emitPdb = true; + break; + case "/debug:portable": + emitPdb = true; + debugType = DebugInformationFormat.PortablePdb; + break; + case "/debug:embedded": + emitPdb = true; + debugType = DebugInformationFormat.Embedded; + break; + case "/langversion:7.3": + languageVersion = LanguageVersion.CSharp7_3; + break; + + } + } + } + var parseOptions = new CSharpParseOptions (preprocessorSymbols: options.Defines, languageVersion: languageVersion); + var emitOptions = new EmitOptions (debugInformationFormat: debugType); + var pdbPath = (!emitPdb || debugType == DebugInformationFormat.Embedded) ? null : options.OutputPath.ChangeExtension (".pdb").ToString (); + + var syntaxTrees = options.SourceFiles.Select (p => + CSharpSyntaxTree.ParseText ( + text: p.ReadAllText (), + options: parseOptions + ) + ); + + var compilation = CSharpCompilation.Create ( + assemblyName: options.OutputPath.FileNameWithoutExtension, + syntaxTrees: syntaxTrees, + references: options.References.Select (r => MetadataReference.CreateFromFile (r)), + options: compilationOptions + ); + + var manifestResources = options.Resources.Select (r => { + var fullPath = r.ToString (); + return new ResourceDescription ( + resourceName: Path.GetFileName (fullPath), + dataProvider: () => new FileStream (fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), + isPublic: true + ); + }); + + EmitResult result; + using (var outputStream = File.Create (options.OutputPath.ToString ())) + using (var pdbStream = pdbPath == null ? null : File.Create (pdbPath)) { + result = compilation.Emit ( + peStream: outputStream, + pdbStream: pdbStream, + manifestResources: manifestResources, + options: emitOptions + ); + } + + var errors = new StringBuilder (); + if (result.Success) + return options.OutputPath; + + foreach (var diagnostic in result.Diagnostics) + errors.AppendLine (diagnostic.ToString ()); + throw new Exception ("Roslyn compilation errors: " + errors); + } +#endif + + protected virtual NPath CompileCSharpAssemblyWithCsc (CompilerOptions options) + { +#if NETCOREAPP + return CompileCSharpAssemblyWithRoslyn (options); +#else + return CompileCSharpAssemblyWithExternalCompiler (LocateCscExecutable (), options, "/shared "); +#endif + } + + protected virtual NPath CompileCSharpAssemblyWithMcs (CompilerOptions options) + { + if (Environment.OSVersion.Platform == PlatformID.Win32NT) + CompileCSharpAssemblyWithExternalCompiler (LocateMcsExecutable (), options, string.Empty); + + return CompileCSharpAssemblyWithDefaultCompiler (options); + } + + protected NPath CompileCSharpAssemblyWithExternalCompiler (string executable, CompilerOptions options, string compilerSpecificArguments) + { + var capturedOutput = new List (); + var process = new Process (); + process.StartInfo.FileName = executable; + process.StartInfo.Arguments = OptionsToCompilerCommandLineArguments (options, compilerSpecificArguments); + process.StartInfo.UseShellExecute = false; + process.StartInfo.CreateNoWindow = true; + process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + process.StartInfo.RedirectStandardOutput = true; + process.OutputDataReceived += (sender, args) => capturedOutput.Add (args.Data!); + process.Start (); + process.BeginOutputReadLine (); + process.WaitForExit (); + + if (process.ExitCode != 0) + Assert.True (false, $"Failed to compile assembly with csc: {options.OutputPath}\n{capturedOutput.Aggregate ((buff, s) => buff + Environment.NewLine + s)}"); + + return options.OutputPath; + } + + static string LocateMcsExecutable () + { + if (Environment.OSVersion.Platform == PlatformID.Win32NT) + throw new IgnoreTestException ("We don't have a universal way of locating mcs on Windows"); + + return "mcs"; + } + + protected string OptionsToCompilerCommandLineArguments (CompilerOptions options, string compilerSpecificArguments) + { + var builder = new StringBuilder (); + if (!string.IsNullOrEmpty (compilerSpecificArguments)) + builder.Append (compilerSpecificArguments); + builder.Append ($"/out:{options.OutputPath}"); + var target = options.OutputPath.ExtensionWithDot == ".exe" ? "exe" : "library"; + builder.Append ($" /target:{target}"); + if (options.Defines != null && options.Defines.Length > 0) + builder.Append (options.Defines.Aggregate (string.Empty, (buff, arg) => $"{buff} /define:{arg}")); + + builder.Append (options.References.Aggregate (string.Empty, (buff, arg) => $"{buff} /r:{arg}")); + + if (options.Resources != null && options.Resources.Length > 0) + builder.Append (options.Resources.Aggregate (string.Empty, (buff, arg) => $"{buff} /res:{arg}")); + + if (options.AdditionalArguments != null && options.AdditionalArguments.Length > 0) + builder.Append (options.AdditionalArguments.Aggregate (string.Empty, (buff, arg) => $"{buff} {arg}")); + + builder.Append (options.SourceFiles.Aggregate (string.Empty, (buff, arg) => $"{buff} {arg}")); + + return builder.ToString (); + } + + protected NPath CompileCSharpAssembly (CompilerOptions options) + { + if (string.IsNullOrEmpty (options.CompilerToUse)) + return CompileCSharpAssemblyWithDefaultCompiler (options); + + if (options.CompilerToUse == "csc") + return CompileCSharpAssemblyWithCsc (options); + + if (options.CompilerToUse == "mcs") + return CompileCSharpAssemblyWithMcs (options); + + throw new ArgumentException ($"Invalid compiler value `{options.CompilerToUse}`"); + } + + protected NPath CompileIlAssembly (CompilerOptions options) + { + return _ilCompiler.Compile (options); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseLinkerOptions.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseLinkerOptions.cs new file mode 100644 index 00000000000000..161e9af1c33cea --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseLinkerOptions.cs @@ -0,0 +1,36 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Collections.Generic; + +#nullable disable + +namespace Mono.Linker.Tests.TestCasesRunner +{ + public class TestCaseLinkerOptions + { + public string TrimMode; + public string DefaultAssembliesAction; + public List<(string Action, string Assembly)> AssembliesAction = new(); + + public string Il8n; + public bool IgnoreDescriptors; + public bool IgnoreSubstitutions; + public bool IgnoreLinkAttributes; + public string KeepTypeForwarderOnlyAssemblies; + public string KeepDebugMembers; + public string LinkSymbols; + public bool SkipUnresolved; + public bool StripDescriptors; + public bool StripSubstitutions; + public bool StripLinkAttributes; + + public List> AdditionalArguments = new List> (); + + public List Descriptors = new List (); + + public List Substitutions = new List (); + + public List LinkAttributes = new List (); + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseMetadataProvider.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseMetadataProvider.cs new file mode 100644 index 00000000000000..cf3a7623963790 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseMetadataProvider.cs @@ -0,0 +1,141 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Mono.Cecil; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Cases.Expectations.Metadata; +using Mono.Linker.Tests.Extensions; +using Mono.Linker.Tests.TestCases; + +namespace Mono.Linker.Tests.TestCasesRunner +{ + public class TestCaseMetadataProvider : BaseMetadataProvider + { + public TestCaseMetadataProvider (TestCase testCase, AssemblyDefinition fullTestCaseAssemblyDefinition) + : base (testCase, fullTestCaseAssemblyDefinition) + { + } + + public virtual TestCaseLinkerOptions GetLinkerOptions (NPath inputPath) + { + var tclo = new TestCaseLinkerOptions { + Il8n = GetOptionAttributeValue (nameof (Il8nAttribute), "none"), + IgnoreDescriptors = GetOptionAttributeValue (nameof (IgnoreDescriptorsAttribute), true), + IgnoreSubstitutions = GetOptionAttributeValue (nameof (IgnoreSubstitutionsAttribute), true), + IgnoreLinkAttributes = GetOptionAttributeValue (nameof (IgnoreLinkAttributesAttribute), true), + KeepTypeForwarderOnlyAssemblies = GetOptionAttributeValue (nameof (KeepTypeForwarderOnlyAssembliesAttribute), string.Empty), + KeepDebugMembers = GetOptionAttributeValue (nameof (SetupLinkerKeepDebugMembersAttribute), string.Empty), + LinkSymbols = GetOptionAttributeValue (nameof (SetupLinkerLinkSymbolsAttribute), string.Empty), + TrimMode = GetOptionAttributeValue (nameof (SetupLinkerTrimModeAttribute), null), + DefaultAssembliesAction = GetOptionAttributeValue (nameof (SetupLinkerDefaultActionAttribute), null), + SkipUnresolved = GetOptionAttributeValue (nameof (SkipUnresolvedAttribute), false), + StripDescriptors = GetOptionAttributeValue (nameof (StripDescriptorsAttribute), true), + StripSubstitutions = GetOptionAttributeValue (nameof (StripSubstitutionsAttribute), true), + StripLinkAttributes = GetOptionAttributeValue (nameof (StripLinkAttributesAttribute), true), + }; + + foreach (var assemblyAction in _testCaseTypeDefinition.CustomAttributes.Where (attr => attr.AttributeType.Name == nameof (SetupLinkerActionAttribute))) { + var ca = assemblyAction.ConstructorArguments; + tclo.AssembliesAction.Add (((string) ca[0].Value, (string) ca[1].Value)); + } + + foreach (var descFile in _testCaseTypeDefinition.CustomAttributes.Where (attr => attr.AttributeType.Name == nameof (SetupLinkerDescriptorFile))) { + var ca = descFile.ConstructorArguments; + var file = (string) ca[0].Value; + tclo.Descriptors.Add (Path.Combine (inputPath, file)); + } + + foreach (var subsFile in _testCaseTypeDefinition.CustomAttributes.Where (attr => attr.AttributeType.Name == nameof (SetupLinkerSubstitutionFileAttribute))) { + var ca = subsFile.ConstructorArguments; + var file = (string) ca[0].Value; + tclo.Substitutions.Add (Path.Combine (inputPath, file)); + } + + foreach (var linkAttrFile in _testCaseTypeDefinition.CustomAttributes.Where (attr => attr.AttributeType.Name == nameof (SetupLinkAttributesFile))) { + var ca = linkAttrFile.ConstructorArguments; + var file = (string) ca[0].Value; + tclo.LinkAttributes.Add (Path.Combine (inputPath, file)); + } + + foreach (var additionalArgumentAttr in _testCaseTypeDefinition.CustomAttributes.Where (attr => attr.AttributeType.Name == nameof (SetupLinkerArgumentAttribute))) { + var ca = additionalArgumentAttr.ConstructorArguments; + var values = ((CustomAttributeArgument[]) ca[1].Value)!.Select (arg => arg.Value.ToString ()!).ToArray (); + // Since custom attribute arguments need to be constant expressions, we need to add + // the path to the temp directory (where the custom assembly is located) here. + switch ((string) ca[0].Value) { + case "--custom-step": + int pos = values[0].IndexOf (","); + if (pos != -1) { + string custom_assembly_path = values[0].Substring (pos + 1); + if (!Path.IsPathRooted (custom_assembly_path)) + values[0] = values[0].Substring (0, pos + 1) + Path.Combine (inputPath, custom_assembly_path); + } + break; + case "-a": + if (!Path.IsPathRooted (values[0])) + values[0] = Path.Combine (inputPath, values[0]); + + break; + } + + tclo.AdditionalArguments.Add (new KeyValuePair ((string) ca[0].Value, values)); + } + + return tclo; + } + + public virtual IEnumerable GetResponseFiles () + { + return _testCaseTypeDefinition.CustomAttributes + .Where (attr => attr.AttributeType.Name == nameof (SetupLinkerResponseFileAttribute)) + .Select (GetSourceAndRelativeDestinationValue); + } + + public virtual IEnumerable GetDescriptorFiles () + { + return _testCaseTypeDefinition.CustomAttributes + .Where (attr => attr.AttributeType.Name == nameof (SetupLinkerDescriptorFile)) + .Select (GetSourceAndRelativeDestinationValue); + } + + public virtual IEnumerable GetSubstitutionFiles () + { + return _testCaseTypeDefinition.CustomAttributes + .Where (attr => attr.AttributeType.Name == nameof (SetupLinkerSubstitutionFileAttribute)) + .Select (GetSourceAndRelativeDestinationValue); + } + + public virtual IEnumerable GetLinkAttributesFiles () + { + return _testCaseTypeDefinition.CustomAttributes + .Where (attr => attr.AttributeType.Name == nameof (SetupLinkAttributesFile)) + .Select (GetSourceAndRelativeDestinationValue); + } + + public virtual IEnumerable GetExtraLinkerReferences () + { + var netcoreappDir = Path.GetDirectoryName (typeof (object).Assembly.Location)!; + foreach (var assembly in Directory.EnumerateFiles (netcoreappDir)) { + if (Path.GetExtension (assembly) != ".dll") + continue; + var assemblyName = Path.GetFileNameWithoutExtension (assembly); + if (assemblyName.Contains ("Native")) + continue; + if (assemblyName.StartsWith ("Microsoft") || + assemblyName.StartsWith ("System") || + assemblyName == "mscorlib" || assemblyName == "netstandard") + yield return assembly.ToNPath (); + } + } + + public virtual bool LinkPublicAndFamily () + { + return _testCaseTypeDefinition.CustomAttributes + .FirstOrDefault (attr => attr.AttributeType.Name == nameof (SetupLinkerLinkPublicAndFamilyAttribute)) != null; + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseSandbox.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseSandbox.cs new file mode 100644 index 00000000000000..c7041020c44810 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestCaseSandbox.cs @@ -0,0 +1,195 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Collections.Generic; +using System.IO; +using Mono.Linker.Tests.Cases.Expectations.Assertions; +using Mono.Linker.Tests.Extensions; +using Mono.Linker.Tests.TestCases; + +namespace Mono.Linker.Tests.TestCasesRunner +{ + public class TestCaseSandbox + { + protected readonly TestCase _testCase; + protected readonly NPath _directory; + + static readonly string _linkerAssemblyPath = "";//typeof (Trimmer).Assembly.Location; + + static NPath GetArtifactsTestPath () + { + // Converts paths like /root-folder/runtime/artifacts/bin/Mono.Linker.Tests/x64/Debug/Mono.Linker.Tests.dll + // to /root-folder/runtime/artifacts/bin/ILLink.testcases/ + string artifacts = (string) AppContext.GetData ("Mono.Linker.Tests.ArtifactsDir")!; + string tests = Path.Combine (artifacts, "ILLink.testcases"); + return new NPath (tests); + } + + public TestCaseSandbox (TestCase testCase) + : this (testCase, GetArtifactsTestPath (), Path.GetFileNameWithoutExtension (_linkerAssemblyPath)) + { + } + + public TestCaseSandbox (TestCase testCase, NPath rootTemporaryDirectory) + : this (testCase, rootTemporaryDirectory, string.Empty) + { + } + + public TestCaseSandbox (TestCase testCase, string rootTemporaryDirectory, string namePrefix) + : this (testCase, rootTemporaryDirectory.ToNPath (), namePrefix) + { + } + + public TestCaseSandbox (TestCase testCase, NPath rootTemporaryDirectory, string namePrefix) + { + _testCase = testCase; + + var rootDirectory = rootTemporaryDirectory.Combine (string.IsNullOrEmpty (namePrefix) ? "linker_tests" : namePrefix); + + var locationRelativeToRoot = testCase.SourceFile.Parent.RelativeTo (testCase.RootCasesDirectory); + var suiteDirectory = rootDirectory.Combine (locationRelativeToRoot); + _directory = suiteDirectory.Combine (testCase.SourceFile.FileNameWithoutExtension); + + _directory.DeleteContents (); + + InputDirectory = _directory.Combine ("input").EnsureDirectoryExists (); + OutputDirectory = _directory.Combine ("output").EnsureDirectoryExists (); + ExpectationsDirectory = _directory.Combine ("expectations").EnsureDirectoryExists (); + ResourcesDirectory = _directory.Combine ("resources").EnsureDirectoryExists (); + } + + public NPath InputDirectory { get; } + + public NPath OutputDirectory { get; } + + public NPath ExpectationsDirectory { get; } + + public NPath ResourcesDirectory { get; } + + public IEnumerable SourceFiles { + get { return _directory.Files ("*.cs"); } + } + + public IEnumerable ResponseFiles { + get { return InputDirectory.Files ("*.rsp"); } + } + + public IEnumerable ResourceFiles => ResourcesDirectory.Files (); + + public virtual void Populate (TestCaseCompilationMetadataProvider metadataProvider) + { + _testCase.SourceFile.Copy (_directory); + + if (_testCase.HasLinkXmlFile) + _testCase.LinkXmlFile.Copy (InputDirectory); + + CopyToInputAndExpectations (GetExpectationsAssemblyPath ()); + + foreach (var dep in metadataProvider.AdditionalFilesToSandbox ()) { + var destination = _directory.Combine (dep.DestinationFileName); + dep.Source.FileMustExist ().Copy (destination); + + // In a few niche tests we need to copy pre-built assemblies directly into the input directory. + // When this is done, we also need to copy them into the expectations directory so that if they are used + // as references we can still compile the expectations version of the assemblies + if (destination.Parent == InputDirectory) + dep.Source.Copy (ExpectationsDirectory.Combine (destination.RelativeTo (InputDirectory))); + } + + // Copy non class library dependencies to the sandbox + foreach (var fileName in metadataProvider.GetReferenceValues ()) { + if (!fileName.StartsWith ("System.", StringComparison.Ordinal) && !fileName.StartsWith ("Mono.", StringComparison.Ordinal) && !fileName.StartsWith ("Microsoft.", StringComparison.Ordinal)) + CopyToInputAndExpectations (_testCase.SourceFile.Parent.Combine (fileName.ToNPath ())); + } + + foreach (var referenceDependency in metadataProvider.GetReferenceDependencies ()) + CopyToInputAndExpectations (_testCase.SourceFile.Parent.Combine (referenceDependency.ToNPath ())); + + foreach (var res in metadataProvider.GetResources ()) { + res.Source.FileMustExist ().Copy (ResourcesDirectory.Combine (res.DestinationFileName)); + } + + foreach (var compileRefInfo in metadataProvider.GetSetupCompileAssembliesBefore ()) { + var destination = BeforeReferenceSourceDirectoryFor (compileRefInfo.OutputName).EnsureDirectoryExists (); + compileRefInfo.SourceFiles.Copy (destination); + + destination = BeforeReferenceResourceDirectoryFor (compileRefInfo.OutputName).EnsureDirectoryExists (); + + if (compileRefInfo.Resources == null) + continue; + + foreach (var res in compileRefInfo.Resources) + res.Source.FileMustExist ().Copy (destination.Combine (res.DestinationFileName)); + } + + foreach (var compileRefInfo in metadataProvider.GetSetupCompileAssembliesAfter ()) { + var destination = AfterReferenceSourceDirectoryFor (compileRefInfo.OutputName).EnsureDirectoryExists (); + compileRefInfo.SourceFiles.Copy (destination); + + destination = AfterReferenceResourceDirectoryFor (compileRefInfo.OutputName).EnsureDirectoryExists (); + + if (compileRefInfo.Resources == null) + continue; + + foreach (var res in compileRefInfo.Resources) + res.Source.FileMustExist ().Copy (destination.Combine (res.DestinationFileName)); + } + } + + /// + /// Any files that are needed for linking should come from the expectations assembly so that these values + /// can be controlled using #ifs regardless of the framework the NUnit test project is compiled against + /// + /// + public virtual void PopulateFromExpectations (TestCaseMetadataProvider metadataProvider) + { + foreach (var res in metadataProvider.GetResponseFiles ()) { + res.Source.FileMustExist ().Copy (InputDirectory.Combine (res.DestinationFileName)); + } + + foreach (var res in metadataProvider.GetDescriptorFiles ()) { + res.Source.FileMustExist ().Copy (InputDirectory.Combine (res.DestinationFileName)); + } + + foreach (var res in metadataProvider.GetSubstitutionFiles ()) { + res.Source.FileMustExist ().Copy (InputDirectory.Combine (res.DestinationFileName)); + } + + foreach (var res in metadataProvider.GetLinkAttributesFiles ()) { + res.Source.FileMustExist ().Copy (InputDirectory.Combine (res.DestinationFileName)); + } + } + + private static NPath GetExpectationsAssemblyPath () + { + return new Uri (typeof (KeptAttribute).Assembly.Location).LocalPath.ToNPath (); + } + + protected void CopyToInputAndExpectations (NPath source) + { + source.Copy (InputDirectory); + source.Copy (ExpectationsDirectory); + } + + public NPath BeforeReferenceSourceDirectoryFor (string outputName) + { + return _directory.Combine ($"ref_source_before_{Path.GetFileNameWithoutExtension (outputName)}"); + } + + public NPath AfterReferenceSourceDirectoryFor (string outputName) + { + return _directory.Combine ($"ref_source_after_{Path.GetFileNameWithoutExtension (outputName)}"); + } + + public NPath BeforeReferenceResourceDirectoryFor (string outputName) + { + return _directory.Combine ($"ref_resource_before_{Path.GetFileNameWithoutExtension (outputName)}"); + } + + public NPath AfterReferenceResourceDirectoryFor (string outputName) + { + return _directory.Combine ($"ref_resource_after_{Path.GetFileNameWithoutExtension (outputName)}"); + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestLogWriter.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestLogWriter.cs new file mode 100644 index 00000000000000..c8d4a40a7eabd8 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestLogWriter.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; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ILCompiler; +using ILCompiler.Logging; + +namespace Mono.Linker.Tests.TestCasesRunner +{ + public class TestLogWriter : ILogWriter + { + private readonly StringWriter _infoStringWriter; + private readonly TextWriter _infoWriter; + + private readonly List _messageContainers; + + public TestLogWriter () + { + _infoStringWriter = new StringWriter (); + _infoWriter = TextWriter.Synchronized (_infoStringWriter); + _messageContainers = new List (); + } + + public TextWriter Writer => _infoWriter; + + public List GetLoggedMessages () + { + return _messageContainers; + } + + public void WriteError (MessageContainer error) + { + lock (_messageContainers) { + _messageContainers.Add (error); + } + } + + public void WriteMessage (MessageContainer message) + { + lock (_messageContainers) { + _messageContainers.Add (message); + } + } + + public void WriteWarning (MessageContainer warning) + { + lock (_messageContainers) { + _messageContainers.Add (warning); + } + } + } +} diff --git a/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestRunner.cs b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestRunner.cs new file mode 100644 index 00000000000000..3540250b709f31 --- /dev/null +++ b/src/coreclr/tools/aot/Mono.Linker.Tests/TestCasesRunner/TestRunner.cs @@ -0,0 +1,165 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Linq; +using System.Threading.Tasks; +using Mono.Linker.Tests.TestCasesRunner; +using Mono.Cecil; +using Mono.Linker.Tests.Extensions; +using Mono.Linker.Tests.TestCases; +using Xunit.Sdk; + +namespace Mono.Linker.Tests.TestCasesRunner +{ + public class TestRunner + { + private readonly ObjectFactory _factory; + + public TestRunner (ObjectFactory factory) + { + _factory = factory; + } + + public virtual ILCompilerTestCaseResult? Run (TestCase testCase) + { + try { + using (var fullTestCaseAssemblyDefinition = AssemblyDefinition.ReadAssembly (testCase.OriginalTestCaseAssemblyPath.ToString ())) { + var compilationMetadataProvider = _factory.CreateCompilationMetadataProvider (testCase, fullTestCaseAssemblyDefinition); + + if (compilationMetadataProvider.IsIgnored (out string? ignoreReason)) + throw new IgnoreTestException (ignoreReason); + + var sandbox = Sandbox (testCase, compilationMetadataProvider); + var compilationResult = Compile (sandbox, compilationMetadataProvider); + using (var expectationsAssemblyDefinition = AssemblyDefinition.ReadAssembly (compilationResult.ExpectationsAssemblyPath.ToString ())) { + var metadataProvider = _factory.CreateMetadataProvider (testCase, expectationsAssemblyDefinition); + + sandbox.PopulateFromExpectations (metadataProvider); + + PrepForLink (sandbox, compilationResult); + return Link (testCase, sandbox, compilationResult, metadataProvider); + } + } + } catch (IgnoreTestException) { + return null; + } + } + + public virtual ILCompilerTestCaseResult Relink (ILCompilerTestCaseResult result) + { + PrepForLink (result.Sandbox, result.CompilationResult); + return Link (result.TestCase, result.Sandbox, result.CompilationResult, result.MetadataProvider); + } + + private TestCaseSandbox Sandbox (TestCase testCase, TestCaseCompilationMetadataProvider metadataProvider) + { + var sandbox = _factory.CreateSandbox (testCase); + sandbox.Populate (metadataProvider); + return sandbox; + } + + private ManagedCompilationResult Compile (TestCaseSandbox sandbox, TestCaseCompilationMetadataProvider metadataProvider) + { + var inputCompiler = _factory.CreateCompiler (sandbox, metadataProvider); + var expectationsCompiler = _factory.CreateCompiler (sandbox, metadataProvider); + var sourceFiles = sandbox.SourceFiles.Select (s => s.ToString ()).ToArray (); + + var assemblyName = metadataProvider.GetAssemblyName (); + + var commonReferences = metadataProvider.GetCommonReferencedAssemblies (sandbox.InputDirectory).ToArray (); + var mainAssemblyReferences = metadataProvider.GetReferencedAssemblies (sandbox.InputDirectory).ToArray (); + var resources = sandbox.ResourceFiles.ToArray (); + var additionalArguments = metadataProvider.GetSetupCompilerArguments ().ToArray (); + + var expectationsCommonReferences = metadataProvider.GetCommonReferencedAssemblies (sandbox.ExpectationsDirectory).ToArray (); + var expectationsMainAssemblyReferences = metadataProvider.GetReferencedAssemblies (sandbox.ExpectationsDirectory).ToArray (); + + var inputTask = Task.Run (() => inputCompiler.CompileTestIn (sandbox.InputDirectory, assemblyName!, sourceFiles, commonReferences, mainAssemblyReferences, null, resources, additionalArguments)); + var expectationsTask = Task.Run (() => expectationsCompiler.CompileTestIn (sandbox.ExpectationsDirectory, assemblyName!, sourceFiles, expectationsCommonReferences, expectationsMainAssemblyReferences, new[] { "INCLUDE_EXPECTATIONS" }, resources, additionalArguments)); + + NPath? inputAssemblyPath = null; + NPath? expectationsAssemblyPath = null; + try { + inputAssemblyPath = GetResultOfTaskThatMakesXUnitAssertions (inputTask); + expectationsAssemblyPath = GetResultOfTaskThatMakesXUnitAssertions (expectationsTask); + } catch (Exception) { + // If completing the input assembly task threw, we need to wait for the expectations task to complete before continuing + // otherwise we could set the next test up for a race condition with the expectations compilation over access to the sandbox directory + if (inputAssemblyPath == null && expectationsAssemblyPath == null) { + try { + expectationsTask.Wait (); + } catch (Exception) { + // Don't care, we want to throw the first exception + } + } + + throw; + } + + return new ManagedCompilationResult (inputAssemblyPath, expectationsAssemblyPath); + } + + protected virtual void PrepForLink (TestCaseSandbox sandbox, ManagedCompilationResult compilationResult) + { + } + + private ILCompilerTestCaseResult Link (TestCase testCase, TestCaseSandbox sandbox, ManagedCompilationResult compilationResult, TestCaseMetadataProvider metadataProvider) + { + var trimmer = _factory.CreateTrimmer (); + + var builder = _factory.CreateTrimmerOptionsBuilder (metadataProvider); + + AddLinkOptions (sandbox, compilationResult, builder, metadataProvider); + + var logWriter = new TestLogWriter (); + trimmer.Trim (builder.Options, logWriter); + + return new ILCompilerTestCaseResult (testCase, compilationResult.InputAssemblyPath, compilationResult.ExpectationsAssemblyPath, sandbox, metadataProvider, compilationResult, logWriter); + } + + protected virtual void AddLinkOptions (TestCaseSandbox sandbox, ManagedCompilationResult compilationResult, ILCompilerOptionsBuilder builder, TestCaseMetadataProvider metadataProvider) + { + var caseDefinedOptions = metadataProvider.GetLinkerOptions (sandbox.InputDirectory); + + builder.AddOutputDirectory (sandbox.OutputDirectory.Combine (compilationResult.InputAssemblyPath.FileNameWithoutExtension + ".obj")); + + foreach (var rspFile in sandbox.ResponseFiles) + builder.AddResponseFile (rspFile); + + foreach (var inputReference in sandbox.InputDirectory.Files ()) { + var ext = inputReference.ExtensionWithDot; + if (ext == ".dll" || ext == ".exe") { + if (caseDefinedOptions.AssembliesAction.Contains (("link", inputReference.FileNameWithoutExtension))) { + builder.AddLinkAssembly (inputReference); + } else { + builder.AddReference (inputReference); + } + } + } + var coreAction = caseDefinedOptions.TrimMode ?? "skip"; + foreach (var extraReference in metadataProvider.GetExtraLinkerReferences ()) { + builder.AddReference (extraReference); + builder.AddAssemblyAction (coreAction, extraReference.FileNameWithoutExtension); + } + + builder.ProcessOptions (caseDefinedOptions); + + builder.ProcessTestInputAssembly (compilationResult.InputAssemblyPath); + } + + private T GetResultOfTaskThatMakesXUnitAssertions (Task task) + { + try { + return task.Result; + } catch (AggregateException e) { + if (e.InnerException != null) { + if (e.InnerException is XunitException) + throw e.InnerException; + } + + throw; + } + } + } +} diff --git a/src/coreclr/tools/aot/ilc.sln b/src/coreclr/tools/aot/ilc.sln index b1c7181908a26d..2ea6f046a1b267 100644 --- a/src/coreclr/tools/aot/ilc.sln +++ b/src/coreclr/tools/aot/ilc.sln @@ -22,11 +22,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILCompiler.Compiler.Tests", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ILCompiler.TypeSystem.Tests", "ILCompiler.TypeSystem.Tests\ILCompiler.TypeSystem.Tests.csproj", "{740CDFF4-B8EC-4A37-951B-C9FE9980EF2A}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mono.Linker.Tests", "Mono.Linker.Tests\Mono.Linker.Tests.csproj", "{4CF2ECD3-A1C3-4A28-AB08-A61C53114143}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mono.Linker.Tests.Cases", "Mono.Linker.Tests.Cases\Mono.Linker.Tests.Cases.csproj", "{13F90593-7DF6-4B16-B6C1-283905C05A6A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mono.Linker.Tests.Cases.Expectations", "Mono.Linker.Tests.Cases.Expectations\Mono.Linker.Tests.Cases.Expectations.csproj", "{26C08C03-921E-4795-AA0B-F3049416E300}" +EndProject Global - GlobalSection(SharedMSBuildProjectFiles) = preSolution - ILLink.Shared\ILLink.Shared.projitems*{ff598e93-8e9e-4091-9f50-61a7572663ae}*SharedItemsImports = 13 - ILLink.Shared\ILLink.Shared.projitems*{ffbd9619-de6f-4a98-8732-8a14ec3c1a18}*SharedItemsImports = 5 - EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Checked|Any CPU = Checked|Any CPU Checked|x64 = Checked|x64 @@ -180,6 +182,60 @@ Global {740CDFF4-B8EC-4A37-951B-C9FE9980EF2A}.Release|x64.Build.0 = Release|x64 {740CDFF4-B8EC-4A37-951B-C9FE9980EF2A}.Release|x86.ActiveCfg = Release|Any CPU {740CDFF4-B8EC-4A37-951B-C9FE9980EF2A}.Release|x86.Build.0 = Release|Any CPU + {4CF2ECD3-A1C3-4A28-AB08-A61C53114143}.Checked|Any CPU.ActiveCfg = Checked|x64 + {4CF2ECD3-A1C3-4A28-AB08-A61C53114143}.Checked|Any CPU.Build.0 = Checked|x64 + {4CF2ECD3-A1C3-4A28-AB08-A61C53114143}.Checked|x64.ActiveCfg = Checked|x64 + {4CF2ECD3-A1C3-4A28-AB08-A61C53114143}.Checked|x64.Build.0 = Checked|x64 + {4CF2ECD3-A1C3-4A28-AB08-A61C53114143}.Checked|x86.ActiveCfg = Checked|x86 + {4CF2ECD3-A1C3-4A28-AB08-A61C53114143}.Checked|x86.Build.0 = Checked|x86 + {4CF2ECD3-A1C3-4A28-AB08-A61C53114143}.Debug|Any CPU.ActiveCfg = Debug|x64 + {4CF2ECD3-A1C3-4A28-AB08-A61C53114143}.Debug|Any CPU.Build.0 = Debug|x64 + {4CF2ECD3-A1C3-4A28-AB08-A61C53114143}.Debug|x64.ActiveCfg = Debug|x64 + {4CF2ECD3-A1C3-4A28-AB08-A61C53114143}.Debug|x64.Build.0 = Debug|x64 + {4CF2ECD3-A1C3-4A28-AB08-A61C53114143}.Debug|x86.ActiveCfg = Debug|x86 + {4CF2ECD3-A1C3-4A28-AB08-A61C53114143}.Debug|x86.Build.0 = Debug|x86 + {4CF2ECD3-A1C3-4A28-AB08-A61C53114143}.Release|Any CPU.ActiveCfg = Release|x64 + {4CF2ECD3-A1C3-4A28-AB08-A61C53114143}.Release|Any CPU.Build.0 = Release|x64 + {4CF2ECD3-A1C3-4A28-AB08-A61C53114143}.Release|x64.ActiveCfg = Release|x64 + {4CF2ECD3-A1C3-4A28-AB08-A61C53114143}.Release|x64.Build.0 = Release|x64 + {4CF2ECD3-A1C3-4A28-AB08-A61C53114143}.Release|x86.ActiveCfg = Release|x86 + {4CF2ECD3-A1C3-4A28-AB08-A61C53114143}.Release|x86.Build.0 = Release|x86 + {13F90593-7DF6-4B16-B6C1-283905C05A6A}.Checked|Any CPU.ActiveCfg = Debug|x64 + {13F90593-7DF6-4B16-B6C1-283905C05A6A}.Checked|Any CPU.Build.0 = Debug|x64 + {13F90593-7DF6-4B16-B6C1-283905C05A6A}.Checked|x64.ActiveCfg = Debug|x64 + {13F90593-7DF6-4B16-B6C1-283905C05A6A}.Checked|x64.Build.0 = Debug|x64 + {13F90593-7DF6-4B16-B6C1-283905C05A6A}.Checked|x86.ActiveCfg = Debug|x86 + {13F90593-7DF6-4B16-B6C1-283905C05A6A}.Checked|x86.Build.0 = Debug|x86 + {13F90593-7DF6-4B16-B6C1-283905C05A6A}.Debug|Any CPU.ActiveCfg = Debug|x64 + {13F90593-7DF6-4B16-B6C1-283905C05A6A}.Debug|Any CPU.Build.0 = Debug|x64 + {13F90593-7DF6-4B16-B6C1-283905C05A6A}.Debug|x64.ActiveCfg = Debug|x64 + {13F90593-7DF6-4B16-B6C1-283905C05A6A}.Debug|x64.Build.0 = Debug|x64 + {13F90593-7DF6-4B16-B6C1-283905C05A6A}.Debug|x86.ActiveCfg = Debug|x86 + {13F90593-7DF6-4B16-B6C1-283905C05A6A}.Debug|x86.Build.0 = Debug|x86 + {13F90593-7DF6-4B16-B6C1-283905C05A6A}.Release|Any CPU.ActiveCfg = Release|x64 + {13F90593-7DF6-4B16-B6C1-283905C05A6A}.Release|Any CPU.Build.0 = Release|x64 + {13F90593-7DF6-4B16-B6C1-283905C05A6A}.Release|x64.ActiveCfg = Release|x64 + {13F90593-7DF6-4B16-B6C1-283905C05A6A}.Release|x64.Build.0 = Release|x64 + {13F90593-7DF6-4B16-B6C1-283905C05A6A}.Release|x86.ActiveCfg = Release|x86 + {13F90593-7DF6-4B16-B6C1-283905C05A6A}.Release|x86.Build.0 = Release|x86 + {26C08C03-921E-4795-AA0B-F3049416E300}.Checked|Any CPU.ActiveCfg = Debug|x64 + {26C08C03-921E-4795-AA0B-F3049416E300}.Checked|Any CPU.Build.0 = Debug|x64 + {26C08C03-921E-4795-AA0B-F3049416E300}.Checked|x64.ActiveCfg = Debug|x64 + {26C08C03-921E-4795-AA0B-F3049416E300}.Checked|x64.Build.0 = Debug|x64 + {26C08C03-921E-4795-AA0B-F3049416E300}.Checked|x86.ActiveCfg = Debug|x86 + {26C08C03-921E-4795-AA0B-F3049416E300}.Checked|x86.Build.0 = Debug|x86 + {26C08C03-921E-4795-AA0B-F3049416E300}.Debug|Any CPU.ActiveCfg = Debug|x64 + {26C08C03-921E-4795-AA0B-F3049416E300}.Debug|Any CPU.Build.0 = Debug|x64 + {26C08C03-921E-4795-AA0B-F3049416E300}.Debug|x64.ActiveCfg = Debug|x64 + {26C08C03-921E-4795-AA0B-F3049416E300}.Debug|x64.Build.0 = Debug|x64 + {26C08C03-921E-4795-AA0B-F3049416E300}.Debug|x86.ActiveCfg = Debug|x86 + {26C08C03-921E-4795-AA0B-F3049416E300}.Debug|x86.Build.0 = Debug|x86 + {26C08C03-921E-4795-AA0B-F3049416E300}.Release|Any CPU.ActiveCfg = Release|x64 + {26C08C03-921E-4795-AA0B-F3049416E300}.Release|Any CPU.Build.0 = Release|x64 + {26C08C03-921E-4795-AA0B-F3049416E300}.Release|x64.ActiveCfg = Release|x64 + {26C08C03-921E-4795-AA0B-F3049416E300}.Release|x64.Build.0 = Release|x64 + {26C08C03-921E-4795-AA0B-F3049416E300}.Release|x86.ActiveCfg = Release|x86 + {26C08C03-921E-4795-AA0B-F3049416E300}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -187,4 +243,8 @@ Global GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {A484CF9D-B203-427F-9D15-A5BBC6013421} EndGlobalSection + GlobalSection(SharedMSBuildProjectFiles) = preSolution + ILLink.Shared\ILLink.Shared.projitems*{ff598e93-8e9e-4091-9f50-61a7572663ae}*SharedItemsImports = 13 + ILLink.Shared\ILLink.Shared.projitems*{ffbd9619-de6f-4a98-8732-8a14ec3c1a18}*SharedItemsImports = 5 + EndGlobalSection EndGlobal From c36185784ee4b81d5a11d9048f13eee32c9d4302 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Thu, 9 Jun 2022 21:09:07 -0400 Subject: [PATCH 022/337] [wasm][nodejs] Ensure that stdout/stderr have been flushed out before exiting (#70416) When the results xml is large, and we are writing the base64 representation in one line, `node` can exit before all the output gets flushed out. This results in xharness getting an incomplete `STARTRESULTXML ... ` with missing `ENDRESULTXML`, thus no `testResults.xml` is generated. This can be seen in the case of `Microsoft.Extensions.Primitives.Tests` which has xml ~140KB, and `System.Memory.Tests` which has a xml ~13MB. So, wait for the two streams to be flushed out, with a timeout of 3secs. - use the `drain` event only if `stream.write('')` returns `false` * Address review feedback @kg, @maraf --- src/mono/wasm/test-main.js | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/mono/wasm/test-main.js b/src/mono/wasm/test-main.js index f13fa2dbe60988..2706e8f8c214ad 100644 --- a/src/mono/wasm/test-main.js +++ b/src/mono/wasm/test-main.js @@ -105,7 +105,30 @@ function set_exit_code(exit_code, reason) { } } else if (App && App.INTERNAL) { - App.INTERNAL.mono_wasm_exit(exit_code); + if (is_node) { + let _flush = function(_stream) { + return new Promise((resolve, reject) => { + if (!_stream.write('')) { + _stream.on('drain', () => resolve()); + setTimeout(reject, 3000); + } else { + resolve(); + } + }); + }; + let stderrFlushed = _flush(process.stderr); + let stdoutFlushed = _flush(process.stdout); + + Promise.all([ stdoutFlushed, stderrFlushed ]) + .then( + () => App.INTERNAL.mono_wasm_exit(exit_code), + reason => { + console.error(`flushing std* streams failed: ${reason}`); + App.INTERNAL.mono_wasm_exit(123); + }); + } else { + App.INTERNAL.mono_wasm_exit(exit_code); + } } } From b2add4986c2da96e6e5fbf6f1fbb947cc7e33b42 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Thu, 9 Jun 2022 21:39:03 -0400 Subject: [PATCH 023/337] [mono][wasm] Add a 'wasm-gc-safepoints' option to enable the generation of GC safe points in AOTed code on WASM. (#70520) --- src/mono/mono/mini/mini-llvm.c | 2 +- src/mono/mono/mini/mini.h | 3 ++- src/mono/mono/utils/options-def.h | 3 ++- src/mono/wasm/build/WasmApp.Native.targets | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/mono/mono/mini/mini-llvm.c b/src/mono/mono/mini/mini-llvm.c index 73ec31e4bbdd26..444f39ac8b7a13 100644 --- a/src/mono/mono/mini/mini-llvm.c +++ b/src/mono/mono/mini/mini-llvm.c @@ -11831,7 +11831,7 @@ emit_method_inner (EmitContext *ctx) } ctx->has_safepoints = requires_safepoint; - if (!cfg->llvm_only && mono_threads_are_safepoints_enabled () && requires_safepoint) { + if (requires_safepoint && mini_safepoints_enabled ()) { if (!cfg->compile_aot) { LLVMSetGC (method, "coreclr"); emit_gc_safepoint_poll (ctx->module, ctx->lmodule, cfg); diff --git a/src/mono/mono/mini/mini.h b/src/mono/mono/mini/mini.h index 06883aafe5d285..3a4dd3453114be 100644 --- a/src/mono/mono/mini/mini.h +++ b/src/mono/mono/mini/mini.h @@ -41,6 +41,7 @@ #include #include #include +#include #include // Forward declare so that mini-*.h can have pointers to them. @@ -2931,7 +2932,7 @@ static inline gboolean mini_safepoints_enabled (void) { #if defined (TARGET_WASM) - return FALSE; + return mono_opt_wasm_gc_safepoints; #else return TRUE; #endif diff --git a/src/mono/mono/utils/options-def.h b/src/mono/mono/utils/options-def.h index 42d890f3816fef..85b693f0871648 100644 --- a/src/mono/mono/utils/options-def.h +++ b/src/mono/mono/utils/options-def.h @@ -57,7 +57,8 @@ DEFINE_BOOL_READONLY(readonly_flag, "readonly-flag", FALSE, "Example") #endif */ -DEFINE_BOOL(wasm_exceptions, "wasm-exceptions", FALSE, "Enable codegen for wasm exceptions") +DEFINE_BOOL(wasm_exceptions, "wasm-exceptions", FALSE, "Enable codegen for WASM exceptions") +DEFINE_BOOL(wasm_gc_safepoints, "wasm-gc-safepoints", FALSE, "Use GC safepoints on WASM") DEFINE_BOOL(aot_lazy_assembly_load, "aot-lazy-assembly-load", FALSE, "Load assemblies referenced by AOT images lazily") /* Cleanup */ diff --git a/src/mono/wasm/build/WasmApp.Native.targets b/src/mono/wasm/build/WasmApp.Native.targets index e924b0b689ec9f..c1ff7669c9d395 100644 --- a/src/mono/wasm/build/WasmApp.Native.targets +++ b/src/mono/wasm/build/WasmApp.Native.targets @@ -531,6 +531,7 @@ + From e026f392b2bb93bc9509ac5403d3e8cd7d3eee72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksey=20Kliger=20=28=CE=BBgeek=29?= Date: Fri, 10 Jun 2022 00:22:27 -0400 Subject: [PATCH 024/337] [wasm] Add infrastructure for building WebWorkers (#70220) * [wasm] Add infrastructure for building WebWorkers - Modify the rollup.config.js script to look for webworkers and to roll them up into IIFE js files in the ${nativeBinDir}/src artifacts directory - A "webworker" is any file in `src/mono/wasm/runtime/workers/` that looks like `dotnet-{workerName}-worker.ts` or `.js`. It can also include other files (ideally by defining them in files in subdirectories for that worker `src/mono/wasm/runtime/workers/dotnet-{workerName}-worker/utility.ts`) - Other changes still have to be done manually in wasm.proj, and elsewhere in order to place the bundled JS file in the right place. - Adds a tsconfig.json for the workers to typecheck using the DedicatedWorkerGlobalScope and without the DOM globals (`window`, etc) - This doesn't convert dotnet-crypto-worker.js into TypeScript, but it does turn on TypeScript checking using a JSDoc comment. To convert that file to typescript: 1. rename `workers/dotnet-crypto-worker.js` to `workers/dotnet-crypto-worker.ts` 2. replace uses of `var` by `let` or `const` 3. add `:any` in various places. * use fast-glob instead of fs.readdir * add fast-glob to devDependencies --- src/mono/wasm/runtime/package-lock.json | 2113 ++++++++++++++++- src/mono/wasm/runtime/package.json | 1 + src/mono/wasm/runtime/rollup.config.js | 53 +- src/mono/wasm/runtime/workers/README.md | 31 + .../{ => workers}/dotnet-crypto-worker.js | 4 + src/mono/wasm/runtime/workers/tsconfig.json | 13 + src/mono/wasm/wasm.proj | 3 +- 7 files changed, 2210 insertions(+), 8 deletions(-) create mode 100644 src/mono/wasm/runtime/workers/README.md rename src/mono/wasm/runtime/{ => workers}/dotnet-crypto-worker.js (98%) create mode 100644 src/mono/wasm/runtime/workers/tsconfig.json diff --git a/src/mono/wasm/runtime/package-lock.json b/src/mono/wasm/runtime/package-lock.json index b4ddc8bca99e6c..fb4979dbd09cc6 100644 --- a/src/mono/wasm/runtime/package-lock.json +++ b/src/mono/wasm/runtime/package-lock.json @@ -1,8 +1,2113 @@ { "name": "@microsoft/dotnet-runtime", "version": "1.0.0", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "@microsoft/dotnet-runtime", + "version": "1.0.0", + "license": "MIT", + "devDependencies": { + "@rollup/plugin-typescript": "8.2.5", + "@typescript-eslint/eslint-plugin": "4.31.2", + "@typescript-eslint/parser": "4.31.2", + "eslint": "7.32.0", + "fast-glob": "3.2.7", + "rollup": "2.56.3", + "rollup-plugin-consts": "1.0.2", + "rollup-plugin-dts": "4.0.0", + "rollup-plugin-terser": "7.0.2", + "tslib": "2.3.1", + "typescript": "4.4.3" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@rollup/plugin-typescript": { + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-8.2.5.tgz", + "integrity": "sha512-QL/LvDol/PAGB2O0S7/+q2HpSUNodpw7z6nGn9BfoVCPOZ0r4EALrojFU29Bkoi2Hr2jgTocTejJ5GGWZfOxbQ==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^3.1.0", + "resolve": "^1.17.0" + }, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "rollup": "^2.14.0", + "tslib": "*", + "typescript": ">=3.7.0" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", + "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", + "dev": true, + "dependencies": { + "@types/estree": "0.0.39", + "estree-walker": "^1.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0" + } + }, + "node_modules/@rollup/pluginutils/node_modules/@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "16.9.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.4.tgz", + "integrity": "sha512-KDazLNYAGIuJugdbULwFZULF9qQ13yNWEBFnfVpqlpgAAo6H/qnM9RjBgh0A0kmHf3XxAKLdN5mTIng9iUvVLA==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.31.2.tgz", + "integrity": "sha512-w63SCQ4bIwWN/+3FxzpnWrDjQRXVEGiTt9tJTRptRXeFvdZc/wLiz3FQUwNQ2CVoRGI6KUWMNUj/pk63noUfcA==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "4.31.2", + "@typescript-eslint/scope-manager": "4.31.2", + "debug": "^4.3.1", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^4.0.0", + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.31.2.tgz", + "integrity": "sha512-3tm2T4nyA970yQ6R3JZV9l0yilE2FedYg8dcXrTar34zC9r6JB7WyBQbpIVongKPlhEMjhQ01qkwrzWy38Bk1Q==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.31.2", + "@typescript-eslint/types": "4.31.2", + "@typescript-eslint/typescript-estree": "4.31.2", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.31.2.tgz", + "integrity": "sha512-EcdO0E7M/sv23S/rLvenHkb58l3XhuSZzKf6DBvLgHqOYdL6YFMYVtreGFWirxaU2mS1GYDby3Lyxco7X5+Vjw==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "4.31.2", + "@typescript-eslint/types": "4.31.2", + "@typescript-eslint/typescript-estree": "4.31.2", + "debug": "^4.3.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.31.2.tgz", + "integrity": "sha512-2JGwudpFoR/3Czq6mPpE8zBPYdHWFGL6lUNIGolbKQeSNv4EAiHaR5GVDQaLA0FwgcdcMtRk+SBJbFGL7+La5w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.31.2", + "@typescript-eslint/visitor-keys": "4.31.2" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.31.2.tgz", + "integrity": "sha512-kWiTTBCTKEdBGrZKwFvOlGNcAsKGJSBc8xLvSjSppFO88AqGxGNYtF36EuEYG6XZ9vT0xX8RNiHbQUKglbSi1w==", + "dev": true, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.31.2.tgz", + "integrity": "sha512-ieBq8U9at6PvaC7/Z6oe8D3czeW5d//Fo1xkF/s9394VR0bg/UaMYPdARiWyKX+lLEjY3w/FNZJxitMsiWv+wA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.31.2", + "@typescript-eslint/visitor-keys": "4.31.2", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "4.31.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.31.2.tgz", + "integrity": "sha512-PrBId7EQq2Nibns7dd/ch6S6/M4/iwLM9McbgeEbCXfxdwRUNxJ4UNreJ6Gh3fI2GNKNrWnQxKL7oCPmngKBug==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.31.2", + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "dependencies": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", + "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", + "dev": true + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", + "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", + "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz", + "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/magic-string": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", + "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", + "dev": true, + "dependencies": { + "sourcemap-codec": "^1.4.4" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "dependencies": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "2.56.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.56.3.tgz", + "integrity": "sha512-Au92NuznFklgQCUcV96iXlxUbHuB1vQMaH76DHl5M11TotjOHwqk9CwcrT78+Tnv4FN9uTBxq6p4EJoYkpyekg==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-consts": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-consts/-/rollup-plugin-consts-1.0.2.tgz", + "integrity": "sha512-vsy9uyIGTXHsVVlD6c2f43xgiQQYRWY29ycC3ezewxc9AHySjQh5Oi3NEX/9c4OnRnnxe+PMwOtvYBMyP0993Q==", + "dev": true, + "peerDependencies": { + "rollup": ">=1.15.0 <3" + } + }, + "node_modules/rollup-plugin-dts": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-4.0.0.tgz", + "integrity": "sha512-tgUC8CxVgtlLDVloUEA9uACVaxjJHuYxlDSTp1LdCexA0bJx+RuMi45RjdLG9RTCgZlV5YBh3O7P2u6dS1KlnA==", + "dev": true, + "dependencies": { + "magic-string": "^0.25.7" + }, + "engines": { + "node": ">=v12.22.5" + }, + "funding": { + "url": "https://github.com/sponsors/Swatinem" + }, + "optionalDependencies": { + "@babel/code-frame": "^7.14.5" + }, + "peerDependencies": { + "rollup": "^2.56.3", + "typescript": "^4.4.2" + } + }, + "node_modules/rollup-plugin-terser": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz", + "integrity": "sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "jest-worker": "^26.2.1", + "serialize-javascript": "^4.0.0", + "terser": "^5.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-support": { + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", + "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/table": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", + "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", + "dev": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.6.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", + "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/terser": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.8.0.tgz", + "integrity": "sha512-f0JH+6yMpneYcRJN314lZrSwu9eKkUFEHLN/kNy8ceh8gaRiLgFPJqrB9HsXjhEGdv4e/ekjTOFxIlL6xlma8A==", + "dev": true, + "dependencies": { + "commander": "^2.20.0", + "source-map": "~0.7.2", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz", + "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + }, "dependencies": { "@babel/code-frame": { "version": "7.14.5", @@ -234,7 +2339,8 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true + "dev": true, + "requires": {} }, "ajv": { "version": "6.12.6", @@ -1198,7 +3304,8 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/rollup-plugin-consts/-/rollup-plugin-consts-1.0.2.tgz", "integrity": "sha512-vsy9uyIGTXHsVVlD6c2f43xgiQQYRWY29ycC3ezewxc9AHySjQh5Oi3NEX/9c4OnRnnxe+PMwOtvYBMyP0993Q==", - "dev": true + "dev": true, + "requires": {} }, "rollup-plugin-dts": { "version": "4.0.0", diff --git a/src/mono/wasm/runtime/package.json b/src/mono/wasm/runtime/package.json index c1ecc81f20dba2..423a5da14ca873 100644 --- a/src/mono/wasm/runtime/package.json +++ b/src/mono/wasm/runtime/package.json @@ -24,6 +24,7 @@ "@typescript-eslint/eslint-plugin": "4.31.2", "@typescript-eslint/parser": "4.31.2", "eslint": "7.32.0", + "fast-glob": "3.2.7", "rollup": "2.56.3", "rollup-plugin-consts": "1.0.2", "rollup-plugin-dts": "4.0.0", diff --git a/src/mono/wasm/runtime/rollup.config.js b/src/mono/wasm/runtime/rollup.config.js index f37712aa1556df..74684132c0e759 100644 --- a/src/mono/wasm/runtime/rollup.config.js +++ b/src/mono/wasm/runtime/rollup.config.js @@ -8,6 +8,7 @@ import { createHash } from "crypto"; import dts from "rollup-plugin-dts"; import consts from "rollup-plugin-consts"; import { createFilter } from "@rollup/pluginutils"; +import * as fast_glob from "fast-glob"; const configuration = process.env.Configuration; const isDebug = configuration !== "Release"; @@ -59,6 +60,8 @@ const inlineAssert = [ pattern: /^\s*mono_assert/gm, failure: "previous regexp didn't inline all mono_assert statements" }]; +const outputCodePlugins = [regexReplace(inlineAssert), consts({ productVersion, configuration }), typescript()]; + const iffeConfig = { treeshake: !isDebug, input: "exports.ts", @@ -85,7 +88,7 @@ const iffeConfig = { handler(warning); }, - plugins: [regexReplace(inlineAssert), consts({ productVersion, configuration }), typescript()] + plugins: outputCodePlugins }; const typesConfig = { input: "./export-types.ts", @@ -111,10 +114,30 @@ if (isDebug) { }); } -export default defineConfig([ +/* Web Workers */ +function makeWorkerConfig(workerName, workerInputSourcePath) { + const workerConfig = { + input: workerInputSourcePath, + output: [ + { + file: nativeBinDir + `/src/dotnet-${workerName}-worker.js`, + format: "iife", + banner, + plugins + }, + ], + plugins: outputCodePlugins, + }; + return workerConfig; +} + +const workerConfigs = findWebWorkerInputs ("./workers").map ((workerInput) => makeWorkerConfig (workerInput.workerName, workerInput.path)); + +const allConfigs = [ iffeConfig, - typesConfig -]); + typesConfig, +].concat(workerConfigs); +export default defineConfig(allConfigs); // this would create .sha256 file next to the output file, so that we do not touch datetime of the file if it's same -> faster incremental build. function writeOnChangePlugin() { @@ -216,3 +239,25 @@ function regexReplace(replacements = []) { return { code: fixed }; } } + +// Finds all files that look like a webworker toplevel input file in the given path. +// Does not look recursively in subdirectories. +// Returns an array of objects {"workerName": "foo", "path": "/path/dotnet-foo-worker.ts"} +// +// A file looks like a webworker toplevel input if it's `dotnet-{name}-worker.ts` or `.js` +function findWebWorkerInputs(basePath) { + const glob = "dotnet-*-worker.[tj]s"; + const files = fast_glob.sync(glob, { cwd: basePath }); + if (files.length == 0) { + return []; + } + const re = /^dotnet-(.*)-worker\.[tj]s$/; + let results = []; + for (const file of files) { + const match = file.match(re); + if (match) { + results.push ({"workerName": match[1], "path": path.join (basePath, file) }); + } + } + return results; +} diff --git a/src/mono/wasm/runtime/workers/README.md b/src/mono/wasm/runtime/workers/README.md new file mode 100644 index 00000000000000..762a1d301d0ad6 --- /dev/null +++ b/src/mono/wasm/runtime/workers/README.md @@ -0,0 +1,31 @@ +# .NET for WebAssembly Web Workers + +This directory contains the sources for web workers that support .NET for WebAssembly. + +The [`rollup.config.js`](../rollup.config.js) in the parent directory +defines the outputs (generally: `dotnet-xyz-worker.js`) + +As a matter of convention, each worker has a toplevel `xyz-worker.ts` +file (or `.js`) and a `xyz/` subdirectory with additional sources. + +To add a new web worker, add a definition here and modify the +`rollup.config.js` to add a new configuration. + +## Typescript modules + +Typescript workers can use the modules from [`..`](..) but bear in +mind that they will be rolled up into the worker which may increase +the size of the overall bundle. + +## Additional changes when adding a new worker + +There are additional changes that are needed beyond just adding a new `dotnet-*-worker.[tj]s` file in this directory. + +Some other places that may need to be modified include: +* [`../../wasm.proj`](../../wasm.proj) +* `eng/liveBuilds.targets` +* `src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.prop` +* [`../../build/WasmApp.targets`](../../build/WasmApp.targets) +* `src/tests/BuildWasmApps/Wasm.Build.Tests/BuildTestBase.cs` +* etc + diff --git a/src/mono/wasm/runtime/dotnet-crypto-worker.js b/src/mono/wasm/runtime/workers/dotnet-crypto-worker.js similarity index 98% rename from src/mono/wasm/runtime/dotnet-crypto-worker.js rename to src/mono/wasm/runtime/workers/dotnet-crypto-worker.js index 0110693a1a4728..329e6a48a761f7 100644 --- a/src/mono/wasm/runtime/dotnet-crypto-worker.js +++ b/src/mono/wasm/runtime/workers/dotnet-crypto-worker.js @@ -1,3 +1,7 @@ +// @ts-check +/// +/// +/// // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. diff --git a/src/mono/wasm/runtime/workers/tsconfig.json b/src/mono/wasm/runtime/workers/tsconfig.json new file mode 100644 index 00000000000000..4df100fcb1d86f --- /dev/null +++ b/src/mono/wasm/runtime/workers/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig", + "compilerOptions": { + "lib": [ + "esnext", + "webworker" + ], + }, + "exclude": [ + "../dotnet.d.ts", + "../bin" + ] +} diff --git a/src/mono/wasm/wasm.proj b/src/mono/wasm/wasm.proj index 3515a1113fec1f..f307b116184300 100644 --- a/src/mono/wasm/wasm.proj +++ b/src/mono/wasm/wasm.proj @@ -249,7 +249,6 @@ @@ -346,6 +345,8 @@ <_RollupInputs Include="$(MonoProjectRoot)wasm/runtime/*.ts"/> + <_RollupInputs Include="$(MonoProjectRoot)wasm/runtime/workers/**/*.js"/> + <_RollupInputs Include="$(MonoProjectRoot)wasm/runtime/workers/**/*.ts"/> <_RollupInputs Include="$(MonoProjectRoot)wasm/runtime/types/*.ts"/> <_RollupInputs Include="$(MonoProjectRoot)wasm/runtimetypes/*.d.ts"/> <_RollupInputs Include="$(MonoProjectRoot)wasm/runtime/*.json"/> From 0c3d5ad05754be529e470d7b0399f40a2bc8087d Mon Sep 17 00:00:00 2001 From: Vladimir Sadov Date: Thu, 9 Jun 2022 22:33:35 -0700 Subject: [PATCH 025/337] [NativeAOT] prevent reentering CreateThreadLocalContentionCountObject (#70456) * prevent reentering CreateThreadLocalContentionCountObject * do not call into type system on lock contentions --- .../src/System/Threading/ThreadInt64PersistentCounter.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadInt64PersistentCounter.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadInt64PersistentCounter.cs index 9eebb89c895f6d..2c39a5dd7cab30 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadInt64PersistentCounter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadInt64PersistentCounter.cs @@ -15,7 +15,10 @@ internal sealed class ThreadInt64PersistentCounter private static List? t_nodeFinalizationHelpers; private long _overflowCount; - private HashSet _nodes = new HashSet(); + + // we pass comparer explicitly so that in NativeAOT case we would not end up + // calling into the type system when lock contention increments its counter + private HashSet _nodes = new HashSet(ObjectEqualityComparer.Default); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Increment(object threadLocalCountObject) From 6c7d9359c271212416865c446ad0167cbdcd17e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Fri, 10 Jun 2022 16:56:49 +0900 Subject: [PATCH 026/337] Avoid calling into resource manager from the type loader (#70538) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sample stack: ``` System.Runtime.Tests.exe!S_P_CoreLib_System_SR__GetResourceString() Line 29 Unknown System.Runtime.Tests.exe!S_P_CoreLib_System_Exception__get_Message() Line 57 Unknown System.Runtime.Tests.exe!S_P_CoreLib_System_Exception__AppendExceptionStackFrame() Line 134 Unknown System.Runtime.Tests.exe!S_P_CoreLib_System_Runtime_EH__AppendExceptionStackFrameViaClasslib() Line 234 Unknown System.Runtime.Tests.exe!S_P_CoreLib_System_Runtime_EH__UpdateStackTrace() Line 735 Unknown System.Runtime.Tests.exe!S_P_CoreLib_System_Runtime_EH__DispatchEx() Line 630 Unknown System.Runtime.Tests.exe!S_P_CoreLib_System_Runtime_EH__RhThrowEx() Line 571 Unknown System.Runtime.Tests.exe!RhpThrowEx�() Unknown System.Runtime.Tests.exe!S_P_TypeLoader_Internal_TypeSystem_TypeDesc__ComputeTemplate_0() Line 241 Unknown System.Runtime.Tests.exe!S_P_TypeLoader_Internal_TypeSystem_TypeDesc__ComputeTemplate() Line 233 Unknown ``` --- .../src/Internal/Runtime/TypeLoader/TypeBuilder.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs index 9c1c186f66e86b..54e2ac88e08ab4 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs @@ -105,6 +105,10 @@ public TypeBuilder() // Helper exception to abort type building if we do not find the generic type template internal class MissingTemplateException : Exception { + public MissingTemplateException() + // Cannot afford calling into resource manager from here, even to get the default message for System.Exception. + // This exception is always caught and rethrown as something more user friendly. + : base("Template is missing") { } } From 9dfbc5bd7c8c9f0cb8a5973b7bdbe5d67070feac Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Fri, 10 Jun 2022 06:07:54 -0400 Subject: [PATCH 027/337] Remove unnecessary CA1052 suppressions (#70512) The analyzer bug was fixed. --- src/libraries/System.Data.Common/src/System/Data/XMLSchema.cs | 4 +--- .../src/System/Diagnostics/Activity.DateTime.corefx.cs | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/libraries/System.Data.Common/src/System/Data/XMLSchema.cs b/src/libraries/System.Data.Common/src/System/Data/XMLSchema.cs index 83434330b1a44e..b0bcf12107d64a 100644 --- a/src/libraries/System.Data.Common/src/System/Data/XMLSchema.cs +++ b/src/libraries/System.Data.Common/src/System/Data/XMLSchema.cs @@ -13,9 +13,7 @@ namespace System.Data { -#pragma warning disable CA1052 // TODO: https://github.com/dotnet/roslyn-analyzers/issues/4968 - internal class XMLSchema -#pragma warning restore CA1052 + internal abstract class XMLSchema { [RequiresUnreferencedCode("Generic TypeConverters may require the generic types to be annotated. For example, NullableConverter requires the underlying type to be DynamicallyAccessedMembers All.")] internal static TypeConverter GetConverter(Type type) diff --git a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.DateTime.corefx.cs b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.DateTime.corefx.cs index 85fc57b2a87886..4f66927dfd5d71 100644 --- a/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.DateTime.corefx.cs +++ b/src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Activity.DateTime.corefx.cs @@ -3,9 +3,7 @@ namespace System.Diagnostics { -#pragma warning disable CA1052 // make class static partial class Activity -#pragma warning restore CA1052 { /// /// Returns high resolution (~1 usec) current UTC DateTime. From bdc6cacdf619ae26c8f95c5465d98cfb5120dc81 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Fri, 10 Jun 2022 06:45:21 -0400 Subject: [PATCH 028/337] Remove params byte[] from System.Net.Mail (#70513) --- .../System.Net.Mail/src/System/Net/Mime/QEncoder.cs | 2 +- .../src/System/Net/Mime/QuotedPrintableStream.cs | 2 +- .../src/System/Net/Mime/WriteStateInfoBase.cs | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mime/QEncoder.cs b/src/libraries/System.Net.Mail/src/System/Net/Mime/QEncoder.cs index c831ea82e375dc..9ba70456d66567 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mime/QEncoder.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mime/QEncoder.cs @@ -21,7 +21,7 @@ internal QEncoder(WriteStateInfoBase wsi) protected override void AppendEncodedCRLF() { //the encoding for CRLF is =0D=0A - WriteState.Append((byte)'=', (byte)'0', (byte)'D', (byte)'=', (byte)'0', (byte)'A'); + WriteState.Append("=0D=0A"u8); } protected override bool LineBreakNeeded(byte b) diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mime/QuotedPrintableStream.cs b/src/libraries/System.Net.Mail/src/System/Net/Mime/QuotedPrintableStream.cs index db5da115b30879..6ce7c1cb7246f2 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mime/QuotedPrintableStream.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mime/QuotedPrintableStream.cs @@ -244,7 +244,7 @@ public int EncodeBytes(byte[] buffer, int offset, int count) if (_encodeCRLF) { // The encoding for CRLF is =0D=0A - WriteState.Append((byte)'=', (byte)'0', (byte)'D', (byte)'=', (byte)'0', (byte)'A'); + WriteState.Append("=0D=0A"u8); } else { diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mime/WriteStateInfoBase.cs b/src/libraries/System.Net.Mail/src/System/Net/Mime/WriteStateInfoBase.cs index 7ae907641a2097..dd7fbfbecb79a5 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mime/WriteStateInfoBase.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mime/WriteStateInfoBase.cs @@ -77,10 +77,10 @@ internal void Append(byte aByte) _currentLineLength++; } - internal void Append(params byte[] bytes) + internal void Append(ReadOnlySpan bytes) { EnsureSpaceInBuffer(bytes.Length); - bytes.CopyTo(_buffer, Length); + bytes.CopyTo(_buffer.AsSpan(Length)); _currentLineLength += bytes.Length; _currentBufferUsed += bytes.Length; } @@ -90,7 +90,7 @@ internal void AppendCRLF(bool includeSpace) AppendFooter(); //add soft line break - Append((byte)'\r', (byte)'\n'); + Append("\r\n"u8); _currentLineLength = 0; // New Line if (includeSpace) { From d6e8686e566efbf9e921581abbfb2dc114369168 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Fri, 10 Jun 2022 06:45:48 -0400 Subject: [PATCH 029/337] Enable IDE0036 (Modifers are not ordered) (#70502) --- eng/CodeAnalysis.src.globalconfig | 2 +- .../src/System/ValueType.cs | 2 +- .../src/Internal/Runtime/MethodTable.cs | 8 ++-- .../src/System/Runtime/RuntimeExports.cs | 2 +- .../Runtime/CompilerHelpers/InteropHelpers.cs | 2 +- .../src/System/MulticastDelegate.cs | 4 +- .../src/System/Runtime/RuntimeImports.cs | 26 ++++++------- .../Win32ThreadPoolPreAllocatedOverlapped.cs | 2 +- ...EnvironmentImplementation.MappingTables.cs | 30 +++++++-------- ...PointerTypeFieldAccessorForStaticFields.cs | 4 +- ...ferenceTypeFieldAccessorForStaticFields.cs | 4 +- .../ValueTypeFieldAccessorForStaticFields.cs | 4 +- .../Runtime/TypeLoader/GenericDictionary.cs | 2 +- .../TypeLoader/GenericDictionaryCell.cs | 18 ++++----- .../TypeLoader/NativeLayoutFieldAlgorithm.cs | 4 +- .../NoMetadataFieldLayoutAlgorithm.cs | 4 +- .../Runtime/TypeLoader/TypeBuilder.cs | 2 +- .../TypeLoaderEnvironment.NamedTypeLookup.cs | 8 ++-- .../src/System/Runtime/RuntimeImports.cs | 6 +-- .../Common/src/System/Text/DBCSDecoder.cs | 6 +-- .../Common/src/System/Text/OSEncoder.cs | 4 +- .../src/System/IO/Pipes/PipeStream.Windows.cs | 6 +-- .../System/IO/Ports/SerialStream.Windows.cs | 4 +- .../System/Dynamic/BinaryOperationBinder.cs | 4 +- .../src/System/Dynamic/ConvertBinder.cs | 4 +- .../System/Dynamic/CreateInstanceBinder.cs | 4 +- .../src/System/Dynamic/DeleteIndexBinder.cs | 4 +- .../src/System/Dynamic/DeleteMemberBinder.cs | 4 +- .../src/System/Dynamic/GetIndexBinder.cs | 4 +- .../src/System/Dynamic/GetMemberBinder.cs | 4 +- .../src/System/Dynamic/InvokeBinder.cs | 4 +- .../src/System/Dynamic/InvokeMemberBinder.cs | 4 +- .../src/System/Dynamic/SetIndexBinder.cs | 4 +- .../src/System/Dynamic/SetMemberBinder.cs | 4 +- .../System/Dynamic/UnaryOperationBinder.cs | 4 +- .../QueryOperators/BinaryQueryOperator.cs | 2 +- .../QueryOperators/UnaryQueryOperator.cs | 2 +- .../BsdIPGlobalProperties.cs | 2 +- .../SystemIPGlobalProperties.cs | 2 +- .../UnixIPGlobalProperties.cs | 2 +- .../Implementations/Mock/MockConnection.cs | 4 +- .../MsQuic/MsQuicConnection.cs | 2 +- .../src/System/DateTime.Windows.cs | 2 +- .../Enumeration/FileSystemEnumerator.Unix.cs | 2 +- .../FileSystemEnumerator.Windows.cs | 2 +- .../IO/Enumeration/FileSystemEnumerator.cs | 2 +- .../src/System/IO/FileStream.cs | 2 +- .../src/System/IO/Path.cs | 4 +- .../IO/Strategies/OSFileStreamStrategy.cs | 2 +- .../src/System/Random.cs | 2 +- .../Runtime/InteropServices/ComWrappers.cs | 2 +- .../src/System/Text/Latin1Encoding.cs | 16 ++++---- .../src/System/Text/Base64Encoding.cs | 6 +-- .../src/System/Text/BinHexEncoding.cs | 4 +- .../src/System/Xml/XmlBaseReader.cs | 2 +- .../src/System/Xml/XmlBinaryWriter.cs | 38 +++++++++---------- .../src/System/Xml/XmlUTF8TextWriter.cs | 6 +-- .../src/System/Xml/XPath/XPathNavigator.cs | 2 +- .../Context/Virtual/VirtualMethodBase.cs | 26 ++++++------- ...alPropertyBase.FuncPropertyAccessorBase.cs | 4 +- .../VirtualPropertyBase.PropertyGetterBase.cs | 4 +- .../VirtualPropertyBase.PropertySetterBase.cs | 4 +- .../Context/Virtual/VirtualPropertyBase.cs | 34 ++++++++--------- .../MemoryBlocks/AbstractMemoryBlock.cs | 4 +- .../MemoryBlocks/ByteArrayMemoryBlock.cs | 2 +- .../MemoryBlocks/NativeHeapMemoryBlock.cs | 2 +- .../ReadOnlyUnmanagedMemoryStream.cs | 2 +- .../Metadata/MetadataStringDecoder.cs | 2 +- .../Reflection/TypeLoading/Types/RoType.cs | 2 +- .../Cryptography/Pal/AnyOS/ManagedPal.Asn.cs | 2 +- .../Windows/DecryptorPalWindows.Decrypt.cs | 2 +- .../Pal/Windows/PkcsPalWindows.Encrypt.cs | 2 +- .../Security/Cryptography/CryptoStream.cs | 2 +- .../src/System/Text/DBCSCodePageEncoding.cs | 2 +- .../src/System/Text/EncodingNLS.cs | 10 ++--- .../src/System/Text/SBCSCodePageEncoding.cs | 2 +- .../System/Text/Encodings/Web/TextEncoder.cs | 4 +- .../Json/Serialization/JsonConverterOfT.cs | 6 +-- .../Reflection/Metadata/MetadataUpdater.cs | 2 +- 79 files changed, 216 insertions(+), 216 deletions(-) diff --git a/eng/CodeAnalysis.src.globalconfig b/eng/CodeAnalysis.src.globalconfig index 8104f96e9b3a03..18822fa4337714 100644 --- a/eng/CodeAnalysis.src.globalconfig +++ b/eng/CodeAnalysis.src.globalconfig @@ -1404,7 +1404,7 @@ dotnet_diagnostic.IDE0034.severity = suggestion dotnet_diagnostic.IDE0035.severity = suggestion # IDE0036: Order modifiers -dotnet_diagnostic.IDE0036.severity = suggestion +dotnet_diagnostic.IDE0036.severity = warning # IDE0037: Use inferred member name dotnet_diagnostic.IDE0037.severity = silent diff --git a/src/coreclr/System.Private.CoreLib/src/System/ValueType.cs b/src/coreclr/System.Private.CoreLib/src/System/ValueType.cs index 31c98a5bf254a0..64b547b699fb7f 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/ValueType.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/ValueType.cs @@ -24,7 +24,7 @@ public abstract class ValueType { [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2075:UnrecognizedReflectionPattern", Justification = "Trimmed fields don't make a difference for equality")] - public unsafe override bool Equals([NotNullWhen(true)] object? obj) + public override unsafe bool Equals([NotNullWhen(true)] object? obj) { if (null == obj) { diff --git a/src/coreclr/nativeaot/Common/src/Internal/Runtime/MethodTable.cs b/src/coreclr/nativeaot/Common/src/Internal/Runtime/MethodTable.cs index 07dd95f67c980a..6a56d48790efc9 100644 --- a/src/coreclr/nativeaot/Common/src/Internal/Runtime/MethodTable.cs +++ b/src/coreclr/nativeaot/Common/src/Internal/Runtime/MethodTable.cs @@ -1499,7 +1499,7 @@ public IntPtr Value // Wrapper around pointers [StructLayout(LayoutKind.Sequential)] - internal unsafe readonly struct Pointer where T : unmanaged + internal readonly unsafe struct Pointer where T : unmanaged { private readonly T* _value; @@ -1514,7 +1514,7 @@ public T* Value // Wrapper around pointers that might be indirected through IAT [StructLayout(LayoutKind.Sequential)] - internal unsafe readonly struct IatAwarePointer where T : unmanaged + internal readonly unsafe struct IatAwarePointer where T : unmanaged { private readonly T* _value; @@ -1546,7 +1546,7 @@ public unsafe IntPtr Value // Wrapper around relative pointers [StructLayout(LayoutKind.Sequential)] - internal unsafe readonly struct RelativePointer where T : unmanaged + internal readonly unsafe struct RelativePointer where T : unmanaged { private readonly int _value; @@ -1561,7 +1561,7 @@ public T* Value // Wrapper around relative pointers that might be indirected through IAT [StructLayout(LayoutKind.Sequential)] - internal unsafe readonly struct IatAwareRelativePointer where T : unmanaged + internal readonly unsafe struct IatAwareRelativePointer where T : unmanaged { private readonly int _value; diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs index 3b081e5d64cfcf..b277d80d79784b 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs @@ -303,7 +303,7 @@ public static unsafe int RhGetCurrentThreadStackTrace(IntPtr[] outputBuffer) // Use DllImport here instead of LibraryImport because this file is used by Test.CoreLib. [DllImport(Redhawk.BaseName)] [UnmanagedCallConv(CallConvs = new Type[] { typeof(CallConvCdecl) })] - private static unsafe extern int RhpGetCurrentThreadStackTrace(IntPtr* pOutputBuffer, uint outputBufferLength, UIntPtr addressInCurrentFrame); + private static extern unsafe int RhpGetCurrentThreadStackTrace(IntPtr* pOutputBuffer, uint outputBufferLength, UIntPtr addressInCurrentFrame); // Worker for RhGetCurrentThreadStackTrace. RhGetCurrentThreadStackTrace just allocates a transition // frame that will be used to seed the stack trace and this method does all the real work. diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs index 2ad758accd6292..4e8bfcd492dde1 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/CompilerHelpers/InteropHelpers.cs @@ -657,7 +657,7 @@ internal sealed class CustomMarshallerTable : ConcurrentUnifier AreTypesEquivalent(pType1.ToPointer(), pType2.ToPointer()); [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhTypeCast_AreTypesAssignable")] - private static unsafe extern bool AreTypesAssignable(MethodTable* pSourceType, MethodTable* pTargetType); + private static extern unsafe bool AreTypesAssignable(MethodTable* pSourceType, MethodTable* pTargetType); internal static unsafe bool AreTypesAssignable(EETypePtr pSourceType, EETypePtr pTargetType) => AreTypesAssignable(pSourceType.ToPointer(), pTargetType.ToPointer()); @@ -303,18 +303,18 @@ internal static unsafe bool AreTypesAssignable(EETypePtr pSourceType, EETypePtr [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhTypeCast_IsInstanceOf")] - private static unsafe extern object IsInstanceOf(MethodTable* pTargetType, object obj); + private static extern unsafe object IsInstanceOf(MethodTable* pTargetType, object obj); internal static unsafe object IsInstanceOf(EETypePtr pTargetType, object obj) => IsInstanceOf(pTargetType.ToPointer(), obj); [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhTypeCast_IsInstanceOfClass")] - private static unsafe extern object IsInstanceOfClass(MethodTable* pTargetType, object obj); + private static extern unsafe object IsInstanceOfClass(MethodTable* pTargetType, object obj); [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhTypeCast_IsInstanceOfInterface")] - internal static unsafe extern object IsInstanceOfInterface(MethodTable* pTargetType, object obj); + internal static extern unsafe object IsInstanceOfInterface(MethodTable* pTargetType, object obj); internal static unsafe object IsInstanceOfInterface(EETypePtr pTargetType, object obj) => IsInstanceOfInterface(pTargetType.ToPointer(), obj); @@ -327,28 +327,28 @@ internal static unsafe object IsInstanceOfInterface(EETypePtr pTargetType, objec // [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhBoxAny")] - private static unsafe extern object RhBoxAny(ref byte pData, MethodTable* pEEType); + private static extern unsafe object RhBoxAny(ref byte pData, MethodTable* pEEType); internal static unsafe object RhBoxAny(ref byte pData, EETypePtr pEEType) => RhBoxAny(ref pData, pEEType.ToPointer()); [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhNewObject")] - private static unsafe extern object RhNewObject(MethodTable* pEEType); + private static extern unsafe object RhNewObject(MethodTable* pEEType); internal static unsafe object RhNewObject(EETypePtr pEEType) => RhNewObject(pEEType.ToPointer()); [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhNewArray")] - private static unsafe extern Array RhNewArray(MethodTable* pEEType, int length); + private static extern unsafe Array RhNewArray(MethodTable* pEEType, int length); internal static unsafe Array RhNewArray(EETypePtr pEEType, int length) => RhNewArray(pEEType.ToPointer(), length); [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhNewString")] - internal static unsafe extern string RhNewString(MethodTable* pEEType, int length); + internal static extern unsafe string RhNewString(MethodTable* pEEType, int length); internal static unsafe string RhNewString(EETypePtr pEEType, int length) => RhNewString(pEEType.ToPointer(), length); @@ -535,19 +535,19 @@ internal static IntPtr RhGetModuleSection(TypeManagerHandle module, ReadyToRunSe [MethodImplAttribute(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhGetThreadStaticStorageForModule")] - internal static unsafe extern object[] RhGetThreadStaticStorageForModule(int moduleIndex); + internal static extern unsafe object[] RhGetThreadStaticStorageForModule(int moduleIndex); [MethodImplAttribute(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhSetThreadStaticStorageForModule")] - internal static unsafe extern bool RhSetThreadStaticStorageForModule(object[] storage, int moduleIndex); + internal static extern unsafe bool RhSetThreadStaticStorageForModule(object[] storage, int moduleIndex); [MethodImplAttribute(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhCurrentNativeThreadId")] - internal static unsafe extern IntPtr RhCurrentNativeThreadId(); + internal static extern unsafe IntPtr RhCurrentNativeThreadId(); [MethodImplAttribute(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhCurrentOSThreadId")] - internal static unsafe extern ulong RhCurrentOSThreadId(); + internal static extern unsafe ulong RhCurrentOSThreadId(); [MethodImplAttribute(MethodImplOptions.InternalCall)] [RuntimeImport("*", "RhGetCurrentThunkContext")] diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Win32ThreadPoolPreAllocatedOverlapped.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Win32ThreadPoolPreAllocatedOverlapped.cs index 21235042d42469..45568824391982 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Win32ThreadPoolPreAllocatedOverlapped.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Win32ThreadPoolPreAllocatedOverlapped.cs @@ -7,7 +7,7 @@ namespace System.Threading { public sealed class PreAllocatedOverlapped : IDisposable, IDeferredDisposable { - internal unsafe readonly Win32ThreadPoolNativeOverlapped* _overlapped; + internal readonly unsafe Win32ThreadPoolNativeOverlapped* _overlapped; private DeferredDisposableLifetime _lifetime; [CLSCompliant(false)] diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs index 4b867227bf3c99..7bbc2de4e88f1f 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs +++ b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs @@ -105,7 +105,7 @@ private static unsafe bool TryGetNativeReaderForBlob(NativeFormatModuleInfo modu /// /// Runtime handle of the type in question /// TypeDef handle for the type - public sealed unsafe override bool TryGetMetadataForNamedType(RuntimeTypeHandle runtimeTypeHandle, out QTypeDefinition qTypeDefinition) + public sealed override unsafe bool TryGetMetadataForNamedType(RuntimeTypeHandle runtimeTypeHandle, out QTypeDefinition qTypeDefinition) { Debug.Assert(!RuntimeAugments.IsGenericType(runtimeTypeHandle)); return TypeLoaderEnvironment.Instance.TryGetMetadataForNamedType(runtimeTypeHandle, out qTypeDefinition); @@ -117,7 +117,7 @@ public sealed unsafe override bool TryGetMetadataForNamedType(RuntimeTypeHandle // Preconditions: // runtimeTypeHandle is a typedef or a generic type instance (not a constructed type such as an array) // - public sealed unsafe override bool IsReflectionBlocked(RuntimeTypeHandle runtimeTypeHandle) + public sealed override unsafe bool IsReflectionBlocked(RuntimeTypeHandle runtimeTypeHandle) { // For generic types, use the generic type definition runtimeTypeHandle = GetTypeDefinition(runtimeTypeHandle); @@ -165,7 +165,7 @@ public sealed unsafe override bool IsReflectionBlocked(RuntimeTypeHandle runtime /// /// TypeDef handle for the type to look up /// Runtime type handle (MethodTable) for the given type - public sealed unsafe override bool TryGetNamedTypeForMetadata(QTypeDefinition qTypeDefinition, out RuntimeTypeHandle runtimeTypeHandle) + public sealed override unsafe bool TryGetNamedTypeForMetadata(QTypeDefinition qTypeDefinition, out RuntimeTypeHandle runtimeTypeHandle) { return TypeLoaderEnvironment.Instance.TryGetOrCreateNamedTypeForMetadata(qTypeDefinition, out runtimeTypeHandle); } @@ -182,7 +182,7 @@ public sealed unsafe override bool TryGetNamedTypeForMetadata(QTypeDefinition qT /// MethodTable of the type in question /// Metadata reader for the type /// Located TypeRef handle - public sealed unsafe override bool TryGetTypeReferenceForNamedType(RuntimeTypeHandle runtimeTypeHandle, out MetadataReader metadataReader, out TypeReferenceHandle typeRefHandle) + public sealed override unsafe bool TryGetTypeReferenceForNamedType(RuntimeTypeHandle runtimeTypeHandle, out MetadataReader metadataReader, out TypeReferenceHandle typeRefHandle) { return TypeLoaderEnvironment.TryGetTypeReferenceForNamedType(runtimeTypeHandle, out metadataReader, out typeRefHandle); } @@ -205,7 +205,7 @@ public sealed unsafe override bool TryGetTypeReferenceForNamedType(RuntimeTypeHa /// Metadata reader for module containing the type reference /// TypeRef handle to look up /// Resolved MethodTable for the type reference - public sealed unsafe override bool TryGetNamedTypeForTypeReference(MetadataReader metadataReader, TypeReferenceHandle typeRefHandle, out RuntimeTypeHandle runtimeTypeHandle) + public sealed override unsafe bool TryGetNamedTypeForTypeReference(MetadataReader metadataReader, TypeReferenceHandle typeRefHandle, out RuntimeTypeHandle runtimeTypeHandle) { return TypeLoaderEnvironment.TryGetNamedTypeForTypeReference(metadataReader, typeRefHandle, out runtimeTypeHandle); } @@ -219,7 +219,7 @@ public sealed unsafe override bool TryGetNamedTypeForTypeReference(MetadataReade // // This is not equivalent to calling TryGetMultiDimTypeForElementType() with a rank of 1! // - public sealed unsafe override bool TryGetArrayTypeForElementType(RuntimeTypeHandle elementTypeHandle, out RuntimeTypeHandle arrayTypeHandle) + public sealed override unsafe bool TryGetArrayTypeForElementType(RuntimeTypeHandle elementTypeHandle, out RuntimeTypeHandle arrayTypeHandle) { if (RuntimeAugments.IsGenericTypeDefinition(elementTypeHandle)) { @@ -240,7 +240,7 @@ public sealed unsafe override bool TryGetArrayTypeForElementType(RuntimeTypeHand // // This is not equivalent to calling TryGetMultiDimTypeElementType() with a rank of 1! // - public sealed unsafe override bool TryGetArrayTypeElementType(RuntimeTypeHandle arrayTypeHandle, out RuntimeTypeHandle elementTypeHandle) + public sealed override unsafe bool TryGetArrayTypeElementType(RuntimeTypeHandle arrayTypeHandle, out RuntimeTypeHandle elementTypeHandle) { elementTypeHandle = RuntimeAugments.GetRelatedParameterTypeHandle(arrayTypeHandle); return true; @@ -256,7 +256,7 @@ public sealed unsafe override bool TryGetArrayTypeElementType(RuntimeTypeHandle // // Calling this with rank 1 is not equivalent to calling TryGetArrayTypeForElementType()! // - public sealed unsafe override bool TryGetMultiDimArrayTypeForElementType(RuntimeTypeHandle elementTypeHandle, int rank, out RuntimeTypeHandle arrayTypeHandle) + public sealed override unsafe bool TryGetMultiDimArrayTypeForElementType(RuntimeTypeHandle elementTypeHandle, int rank, out RuntimeTypeHandle arrayTypeHandle) { if (RuntimeAugments.IsGenericTypeDefinition(elementTypeHandle)) { @@ -279,7 +279,7 @@ public sealed unsafe override bool TryGetMultiDimArrayTypeForElementType(Runtime // Preconditions: // targetTypeHandle is a valid RuntimeTypeHandle. // - public sealed unsafe override bool TryGetPointerTypeForTargetType(RuntimeTypeHandle targetTypeHandle, out RuntimeTypeHandle pointerTypeHandle) + public sealed override unsafe bool TryGetPointerTypeForTargetType(RuntimeTypeHandle targetTypeHandle, out RuntimeTypeHandle pointerTypeHandle) { return TypeLoaderEnvironment.Instance.TryGetPointerTypeForTargetType(targetTypeHandle, out pointerTypeHandle); } @@ -291,7 +291,7 @@ public sealed unsafe override bool TryGetPointerTypeForTargetType(RuntimeTypeHan // Preconditions: // pointerTypeHandle is a valid RuntimeTypeHandle of type pointer. // - public sealed unsafe override bool TryGetPointerTypeTargetType(RuntimeTypeHandle pointerTypeHandle, out RuntimeTypeHandle targetTypeHandle) + public sealed override unsafe bool TryGetPointerTypeTargetType(RuntimeTypeHandle pointerTypeHandle, out RuntimeTypeHandle targetTypeHandle) { targetTypeHandle = RuntimeAugments.GetRelatedParameterTypeHandle(pointerTypeHandle); return true; @@ -304,7 +304,7 @@ public sealed unsafe override bool TryGetPointerTypeTargetType(RuntimeTypeHandle // Preconditions: // targetTypeHandle is a valid RuntimeTypeHandle. // - public sealed unsafe override bool TryGetByRefTypeForTargetType(RuntimeTypeHandle targetTypeHandle, out RuntimeTypeHandle byRefTypeHandle) + public sealed override unsafe bool TryGetByRefTypeForTargetType(RuntimeTypeHandle targetTypeHandle, out RuntimeTypeHandle byRefTypeHandle) { return TypeLoaderEnvironment.Instance.TryGetByRefTypeForTargetType(targetTypeHandle, out byRefTypeHandle); } @@ -316,7 +316,7 @@ public sealed unsafe override bool TryGetByRefTypeForTargetType(RuntimeTypeHandl // Preconditions: // byRefTypeHandle is a valid RuntimeTypeHandle of a byref. // - public sealed unsafe override bool TryGetByRefTypeTargetType(RuntimeTypeHandle byRefTypeHandle, out RuntimeTypeHandle targetTypeHandle) + public sealed override unsafe bool TryGetByRefTypeTargetType(RuntimeTypeHandle byRefTypeHandle, out RuntimeTypeHandle targetTypeHandle) { targetTypeHandle = RuntimeAugments.GetRelatedParameterTypeHandle(byRefTypeHandle); return true; @@ -330,7 +330,7 @@ public sealed unsafe override bool TryGetByRefTypeTargetType(RuntimeTypeHandle b // runtimeTypeDefinitionHandle is a valid RuntimeTypeHandle for a generic type. // genericTypeArgumentHandles is an array of valid RuntimeTypeHandles. // - public sealed unsafe override bool TryGetConstructedGenericTypeForComponents(RuntimeTypeHandle genericTypeDefinitionHandle, RuntimeTypeHandle[] genericTypeArgumentHandles, out RuntimeTypeHandle runtimeTypeHandle) + public sealed override unsafe bool TryGetConstructedGenericTypeForComponents(RuntimeTypeHandle genericTypeDefinitionHandle, RuntimeTypeHandle[] genericTypeArgumentHandles, out RuntimeTypeHandle runtimeTypeHandle) { if (TypeLoaderEnvironment.Instance.TryLookupConstructedGenericTypeForComponents(genericTypeDefinitionHandle, genericTypeArgumentHandles, out runtimeTypeHandle)) { @@ -1400,7 +1400,7 @@ public sealed override FieldAccessor TryGetFieldAccessor( // // This resolves RuntimeMethodHandles for methods declared on non-generic types (declaringTypeHandle is an output of this method.) // - public sealed unsafe override bool TryGetMethodFromHandle(RuntimeMethodHandle runtimeMethodHandle, out RuntimeTypeHandle declaringTypeHandle, out QMethodDefinition methodHandle, out RuntimeTypeHandle[] genericMethodTypeArgumentHandles) + public sealed override unsafe bool TryGetMethodFromHandle(RuntimeMethodHandle runtimeMethodHandle, out RuntimeTypeHandle declaringTypeHandle, out QMethodDefinition methodHandle, out RuntimeTypeHandle[] genericMethodTypeArgumentHandles) { MethodNameAndSignature nameAndSignature; methodHandle = default(QMethodDefinition); @@ -1421,7 +1421,7 @@ public sealed override bool TryGetMethodFromHandleAndType(RuntimeMethodHandle ru // // This resolves RuntimeFieldHandles for fields declared on non-generic types (declaringTypeHandle is an output of this method.) // - public sealed unsafe override bool TryGetFieldFromHandle(RuntimeFieldHandle runtimeFieldHandle, out RuntimeTypeHandle declaringTypeHandle, out FieldHandle fieldHandle) + public sealed override unsafe bool TryGetFieldFromHandle(RuntimeFieldHandle runtimeFieldHandle, out RuntimeTypeHandle declaringTypeHandle, out FieldHandle fieldHandle) { fieldHandle = default(FieldHandle); diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/FieldAccessors/PointerTypeFieldAccessorForStaticFields.cs b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/FieldAccessors/PointerTypeFieldAccessorForStaticFields.cs index a9518275973621..224ad076cbce76 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/FieldAccessors/PointerTypeFieldAccessorForStaticFields.cs +++ b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/FieldAccessors/PointerTypeFieldAccessorForStaticFields.cs @@ -16,7 +16,7 @@ public PointerTypeFieldAccessorForStaticFields(IntPtr cctorContext, IntPtr stati { } - protected sealed unsafe override object GetFieldBypassCctor() + protected sealed override unsafe object GetFieldBypassCctor() { if (FieldBase == FieldTableFlags.GCStatic) { @@ -33,7 +33,7 @@ protected sealed unsafe override object GetFieldBypassCctor() return RuntimeAugments.LoadPointerTypeField(threadStaticRegion, FieldOffset, FieldTypeHandle); } - protected sealed unsafe override void UncheckedSetFieldBypassCctor(object value) + protected sealed override unsafe void UncheckedSetFieldBypassCctor(object value) { if (FieldBase == FieldTableFlags.GCStatic) { diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/FieldAccessors/ReferenceTypeFieldAccessorForStaticFields.cs b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/FieldAccessors/ReferenceTypeFieldAccessorForStaticFields.cs index ad9a193e860e1e..5233fe28d5dab8 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/FieldAccessors/ReferenceTypeFieldAccessorForStaticFields.cs +++ b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/FieldAccessors/ReferenceTypeFieldAccessorForStaticFields.cs @@ -16,7 +16,7 @@ public ReferenceTypeFieldAccessorForStaticFields(IntPtr cctorContext, IntPtr sta { } - protected sealed unsafe override object GetFieldBypassCctor() + protected sealed override unsafe object GetFieldBypassCctor() { if (FieldBase == FieldTableFlags.GCStatic) { @@ -33,7 +33,7 @@ protected sealed unsafe override object GetFieldBypassCctor() return RuntimeAugments.LoadReferenceTypeField(threadStaticRegion, FieldOffset); } - protected sealed unsafe override void UncheckedSetFieldBypassCctor(object value) + protected sealed override unsafe void UncheckedSetFieldBypassCctor(object value) { if (FieldBase == FieldTableFlags.GCStatic) { diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/FieldAccessors/ValueTypeFieldAccessorForStaticFields.cs b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/FieldAccessors/ValueTypeFieldAccessorForStaticFields.cs index ae90edc558c6d4..28765e89600dbb 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/FieldAccessors/ValueTypeFieldAccessorForStaticFields.cs +++ b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/FieldAccessors/ValueTypeFieldAccessorForStaticFields.cs @@ -16,7 +16,7 @@ public ValueTypeFieldAccessorForStaticFields(IntPtr cctorContext, IntPtr statics { } - protected sealed unsafe override object GetFieldBypassCctor() + protected sealed override unsafe object GetFieldBypassCctor() { if (FieldBase == FieldTableFlags.GCStatic) { @@ -33,7 +33,7 @@ protected sealed unsafe override object GetFieldBypassCctor() return RuntimeAugments.LoadValueTypeField(threadStaticRegion, FieldOffset, FieldTypeHandle); } - protected sealed unsafe override void UncheckedSetFieldBypassCctor(object value) + protected sealed override unsafe void UncheckedSetFieldBypassCctor(object value) { if (FieldBase == FieldTableFlags.GCStatic) { diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/GenericDictionary.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/GenericDictionary.cs index eed0b97d01e920..56a7fd8aa6e967 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/GenericDictionary.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/GenericDictionary.cs @@ -59,7 +59,7 @@ public GenericMethodDictionary(GenericDictionaryCell[] cells) : base(cells) { } - public unsafe override IntPtr Allocate() + public override unsafe IntPtr Allocate() { Debug.Assert(_addressOfFirstCellSlot == IntPtr.Zero); diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/GenericDictionaryCell.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/GenericDictionaryCell.cs index 68b8ffcf9b3a09..69df4c61d68df1 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/GenericDictionaryCell.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/GenericDictionaryCell.cs @@ -23,7 +23,7 @@ public abstract class GenericDictionaryCell { internal abstract void Prepare(TypeBuilder builder); internal abstract IntPtr Create(TypeBuilder builder); - internal unsafe virtual void WriteCellIntoDictionary(TypeBuilder typeBuilder, IntPtr* pDictionary, int slotIndex) + internal virtual unsafe void WriteCellIntoDictionary(TypeBuilder typeBuilder, IntPtr* pDictionary, int slotIndex) { pDictionary[slotIndex] = Create(typeBuilder); } @@ -57,7 +57,7 @@ internal override IntPtr Create(TypeBuilder builder) throw new NotSupportedException(); } - internal unsafe override void WriteCellIntoDictionary(TypeBuilder typeBuilder, IntPtr* pDictionary, int slotIndex) + internal override unsafe void WriteCellIntoDictionary(TypeBuilder typeBuilder, IntPtr* pDictionary, int slotIndex) { pDictionary[slotIndex] = new IntPtr(pDictionary + OtherDictionarySlot); } @@ -289,7 +289,7 @@ private class MethodDictionaryCell : GenericDictionaryCell { internal InstantiatedMethod GenericMethod; - internal unsafe override void Prepare(TypeBuilder builder) + internal override unsafe void Prepare(TypeBuilder builder) { if (GenericMethod.IsCanonicalMethod(CanonicalFormKind.Any)) Environment.FailFast("Method dictionaries of canonical methods do not exist"); @@ -312,7 +312,7 @@ private class FieldLdTokenCell : GenericDictionaryCell internal TypeDesc ContainingType; internal IntPtr FieldName; - internal unsafe override void Prepare(TypeBuilder builder) + internal override unsafe void Prepare(TypeBuilder builder) { if (ContainingType.IsCanonicalSubtype(CanonicalFormKind.Any)) Environment.FailFast("Ldtoken is not permitted for a canonical field"); @@ -336,7 +336,7 @@ private class MethodLdTokenCell : GenericDictionaryCell internal IntPtr MethodName; internal RuntimeSignature MethodSignature; - internal unsafe override void Prepare(TypeBuilder builder) + internal override unsafe void Prepare(TypeBuilder builder) { if (Method.IsCanonicalMethod(CanonicalFormKind.Any)) Environment.FailFast("Ldtoken is not permitted for a canonical method"); @@ -532,11 +532,11 @@ public static GenericDictionaryCell CreateIntPtrCell(IntPtr ptrValue) private class IntPtrCell : GenericDictionaryCell { internal IntPtr Value; - internal unsafe override void Prepare(TypeBuilder builder) + internal override unsafe void Prepare(TypeBuilder builder) { } - internal unsafe override IntPtr Create(TypeBuilder builder) + internal override unsafe IntPtr Create(TypeBuilder builder) { return Value; } @@ -567,7 +567,7 @@ private class MethodCell : GenericDictionaryCell private MethodDesc _methodToUseForInstantiatingParameters; private IntPtr _exactFunctionPointer; - internal unsafe override void Prepare(TypeBuilder builder) + internal override unsafe void Prepare(TypeBuilder builder) { _methodToUseForInstantiatingParameters = Method; @@ -761,7 +761,7 @@ private bool NeedsDictionaryParameterToCallCanonicalVersion(MethodDesc method) return Method.OwningType.IsValueType && !Method.UnboxingStub; } - internal unsafe override IntPtr Create(TypeBuilder builder) + internal override unsafe IntPtr Create(TypeBuilder builder) { if (_exactFunctionPointer != IntPtr.Zero) { diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/NativeLayoutFieldAlgorithm.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/NativeLayoutFieldAlgorithm.cs index 054a5ec9956db4..72609631283c25 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/NativeLayoutFieldAlgorithm.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/NativeLayoutFieldAlgorithm.cs @@ -19,7 +19,7 @@ internal class NativeLayoutFieldAlgorithm : FieldLayoutAlgorithm private NoMetadataFieldLayoutAlgorithm _noMetadataFieldLayoutAlgorithm = new NoMetadataFieldLayoutAlgorithm(); private const int InstanceAlignmentEntry = 4; - public unsafe override bool ComputeContainsGCPointers(DefType type) + public override unsafe bool ComputeContainsGCPointers(DefType type) { if (type.IsTemplateCanonical()) { @@ -430,7 +430,7 @@ internal void GetFieldSizeAlignment(TypeDesc fieldType, out LayoutInt size, out alignment = fieldDefType.InstanceFieldAlignment; } - public unsafe override ValueTypeShapeCharacteristics ComputeValueTypeShapeCharacteristics(DefType type) + public override unsafe ValueTypeShapeCharacteristics ComputeValueTypeShapeCharacteristics(DefType type) { // Use this constant to make the code below more laconic const ValueTypeShapeCharacteristics NotHA = ValueTypeShapeCharacteristics.None; diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/NoMetadataFieldLayoutAlgorithm.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/NoMetadataFieldLayoutAlgorithm.cs index 60ea543a3ff228..482e4243b8c970 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/NoMetadataFieldLayoutAlgorithm.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/NoMetadataFieldLayoutAlgorithm.cs @@ -19,7 +19,7 @@ internal class NoMetadataFieldLayoutAlgorithm : FieldLayoutAlgorithm #endif private static NativeLayoutFieldAlgorithm s_nativeLayoutFieldAlgorithm = new NativeLayoutFieldAlgorithm(); - public unsafe override bool ComputeContainsGCPointers(DefType type) + public override unsafe bool ComputeContainsGCPointers(DefType type) { return type.RuntimeTypeHandle.ToEETypePtr()->HasGCPointers; } @@ -28,7 +28,7 @@ public unsafe override bool ComputeContainsGCPointers(DefType type) /// Reads the minimal information about type layout encoded in the /// MethodTable. That doesn't include field information. /// - public unsafe override ComputedInstanceFieldLayout ComputeInstanceLayout(DefType type, InstanceLayoutKind layoutKind) + public override unsafe ComputedInstanceFieldLayout ComputeInstanceLayout(DefType type, InstanceLayoutKind layoutKind) { // If we need the field information, delegate to the native layout algorithm or metadata algorithm if (layoutKind != InstanceLayoutKind.TypeOnly) diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs index 54e2ac88e08ab4..1db84afc02197c 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs @@ -88,7 +88,7 @@ public TypeBuilder() /// The StaticClassConstructionContext for a type is encoded in the negative space /// of the NonGCStatic fields of a type. /// - public static unsafe readonly int ClassConstructorOffset = -sizeof(System.Runtime.CompilerServices.StaticClassConstructionContext); + public static readonly unsafe int ClassConstructorOffset = -sizeof(System.Runtime.CompilerServices.StaticClassConstructionContext); private LowLevelList _typesThatNeedTypeHandles = new LowLevelList(); diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.NamedTypeLookup.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.NamedTypeLookup.cs index 478a6faa10511b..c8aec12bc11d8f 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.NamedTypeLookup.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.NamedTypeLookup.cs @@ -41,7 +41,7 @@ private class NamedTypeLookupResult private class NamedTypeRuntimeTypeHandleToMetadataHashtable : LockFreeReaderHashtable { - protected unsafe override int GetKeyHashCode(RuntimeTypeHandle key) + protected override unsafe int GetKeyHashCode(RuntimeTypeHandle key) { return (int)key.ToEETypePtr()->HashCode; } @@ -50,7 +50,7 @@ protected override bool CompareKeyToValue(RuntimeTypeHandle key, NamedTypeLookup return key.Equals(value.RuntimeTypeHandle); } - protected unsafe override int GetValueHashCode(NamedTypeLookupResult value) + protected override unsafe int GetValueHashCode(NamedTypeLookupResult value) { return value.RuntimeTypeHandleHashcode; } @@ -122,7 +122,7 @@ private static int _rotl(int value, int shift) return (int)(((uint)value << shift) | ((uint)value >> (32 - shift))); } - protected unsafe override int GetKeyHashCode(QTypeDefinition key) + protected override unsafe int GetKeyHashCode(QTypeDefinition key) { return key.Token.GetHashCode() ^ _rotl(key.Reader.GetHashCode(), 8); } @@ -132,7 +132,7 @@ protected override bool CompareKeyToValue(QTypeDefinition key, NamedTypeLookupRe key.Reader.Equals(value.QualifiedTypeDefinition.Reader); } - protected unsafe override int GetValueHashCode(NamedTypeLookupResult value) + protected override unsafe int GetValueHashCode(NamedTypeLookupResult value) { return value.QualifiedTypeDefinition.Token.GetHashCode() ^ _rotl(value.QualifiedTypeDefinition.Reader.GetHashCode(), 8); } diff --git a/src/coreclr/nativeaot/Test.CoreLib/src/System/Runtime/RuntimeImports.cs b/src/coreclr/nativeaot/Test.CoreLib/src/System/Runtime/RuntimeImports.cs index b6901b1ce50c38..b1ffb46e39c9bf 100644 --- a/src/coreclr/nativeaot/Test.CoreLib/src/System/Runtime/RuntimeImports.cs +++ b/src/coreclr/nativeaot/Test.CoreLib/src/System/Runtime/RuntimeImports.cs @@ -73,20 +73,20 @@ internal static IntPtr RhGetModuleSection(TypeManagerHandle module, ReadyToRunSe // [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhNewObject")] - private static unsafe extern object RhNewObject(MethodTable* pEEType); + private static extern unsafe object RhNewObject(MethodTable* pEEType); internal static unsafe object RhNewObject(EETypePtr pEEType) => RhNewObject(pEEType.ToPointer()); [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhNewArray")] - private static unsafe extern Array RhNewArray(MethodTable* pEEType, int length); + private static extern unsafe Array RhNewArray(MethodTable* pEEType, int length); internal static unsafe Array RhNewArray(EETypePtr pEEType, int length) => RhNewArray(pEEType.ToPointer(), length); [DllImport(RuntimeLibrary)] - internal static unsafe extern void RhAllocateNewObject(IntPtr pEEType, uint flags, void* pResult); + internal static extern unsafe void RhAllocateNewObject(IntPtr pEEType, uint flags, void* pResult); [MethodImpl(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhpFallbackFailFast")] diff --git a/src/libraries/Common/src/System/Text/DBCSDecoder.cs b/src/libraries/Common/src/System/Text/DBCSDecoder.cs index b453e2187c68f8..5be9b0cef17463 100644 --- a/src/libraries/Common/src/System/Text/DBCSDecoder.cs +++ b/src/libraries/Common/src/System/Text/DBCSDecoder.cs @@ -93,7 +93,7 @@ private unsafe int ConvertWithLeftOverByte(byte* bytes, int count, char* chars, return result; } - public unsafe override int GetCharCount(byte* bytes, int count, bool flush) + public override unsafe int GetCharCount(byte* bytes, int count, bool flush) { ArgumentNullException.ThrowIfNull(bytes); @@ -156,7 +156,7 @@ public override unsafe int GetChars(byte[] bytes, int byteIndex, int byteCount, } } - public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount, bool flush) + public override unsafe int GetChars(byte* bytes, int byteCount, char* chars, int charCount, bool flush) { ArgumentNullException.ThrowIfNull(bytes); ArgumentNullException.ThrowIfNull(chars); @@ -231,7 +231,7 @@ public override unsafe void Convert(byte[] bytes, int byteIndex, int byteCount, } } - public unsafe override void Convert(byte* bytes, int byteCount, + public override unsafe void Convert(byte* bytes, int byteCount, char* chars, int charCount, bool flush, out int bytesUsed, out int charsUsed, out bool completed) { diff --git a/src/libraries/Common/src/System/Text/OSEncoder.cs b/src/libraries/Common/src/System/Text/OSEncoder.cs index fa14f565195a80..b8d17780409f0f 100644 --- a/src/libraries/Common/src/System/Text/OSEncoder.cs +++ b/src/libraries/Common/src/System/Text/OSEncoder.cs @@ -72,7 +72,7 @@ private unsafe int ConvertWithLeftOverChar(char* chars, int count, byte* bytes, return result; } - public unsafe override int GetByteCount(char* chars, int count, bool flush) + public override unsafe int GetByteCount(char* chars, int count, bool flush) { ArgumentNullException.ThrowIfNull(chars); @@ -130,7 +130,7 @@ public override unsafe int GetBytes(char[] chars, int charIndex, int charCount, } } - public unsafe override int GetBytes(char* chars, int charCount, byte* bytes, int byteCount, bool flush) + public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount, bool flush) { ArgumentNullException.ThrowIfNull(chars); ArgumentNullException.ThrowIfNull(bytes); diff --git a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Windows.cs b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Windows.cs index c4e404da1e7cfe..043ad40323515e 100644 --- a/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Windows.cs +++ b/src/libraries/System.IO.Pipes/src/System/IO/Pipes/PipeStream.Windows.cs @@ -457,7 +457,7 @@ public void WaitForPipeDrain() // Gets the transmission mode for the pipe. This is virtual so that subclassing types can // override this in cases where only one mode is legal (such as anonymous pipes) - public unsafe virtual PipeTransmissionMode TransmissionMode + public virtual unsafe PipeTransmissionMode TransmissionMode { get { @@ -488,7 +488,7 @@ public unsafe virtual PipeTransmissionMode TransmissionMode // Gets the buffer size in the inbound direction for the pipe. This checks if pipe has read // access. If that passes, call to GetNamedPipeInfo will succeed. - public unsafe virtual int InBufferSize + public virtual unsafe int InBufferSize { get { @@ -512,7 +512,7 @@ public unsafe virtual int InBufferSize // if it's an outbound only pipe because GetNamedPipeInfo requires read access to the pipe. // However, returning cached is good fallback, especially if user specified a value in // the ctor. - public unsafe virtual int OutBufferSize + public virtual unsafe int OutBufferSize { get { diff --git a/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Windows.cs b/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Windows.cs index fe3f97b6c5ea00..93ae56a26e9cee 100644 --- a/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Windows.cs +++ b/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Windows.cs @@ -853,7 +853,7 @@ internal void DiscardOutBuffer() // Async companion to BeginRead. // Note, assumed IAsyncResult argument is of derived type SerialStreamAsyncResult, // and throws an exception if untrue. - public unsafe override int EndRead(IAsyncResult asyncResult) + public override unsafe int EndRead(IAsyncResult asyncResult) { if (!_isAsync) return base.EndRead(asyncResult); @@ -928,7 +928,7 @@ public unsafe override int EndRead(IAsyncResult asyncResult) // Note, assumed IAsyncResult argument is of derived type SerialStreamAsyncResult, // and throws an exception if untrue. // Also fails if called in port's break state. - public unsafe override void EndWrite(IAsyncResult asyncResult) + public override unsafe void EndWrite(IAsyncResult asyncResult) { if (!_isAsync) { diff --git a/src/libraries/System.Linq.Expressions/src/System/Dynamic/BinaryOperationBinder.cs b/src/libraries/System.Linq.Expressions/src/System/Dynamic/BinaryOperationBinder.cs index 475a277183f974..400221c2b692c4 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Dynamic/BinaryOperationBinder.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Dynamic/BinaryOperationBinder.cs @@ -24,7 +24,7 @@ protected BinaryOperationBinder(ExpressionType operation) /// /// The result type of the operation. /// - public override sealed Type ReturnType => typeof(object); + public sealed override Type ReturnType => typeof(object); /// /// The binary operation kind. @@ -72,7 +72,7 @@ public sealed override DynamicMetaObject Bind(DynamicMetaObject target, DynamicM /// /// Always returns true because this is a standard . /// - internal override sealed bool IsStandardBinder => true; + internal sealed override bool IsStandardBinder => true; internal static bool OperationIsValid(ExpressionType operation) { diff --git a/src/libraries/System.Linq.Expressions/src/System/Dynamic/ConvertBinder.cs b/src/libraries/System.Linq.Expressions/src/System/Dynamic/ConvertBinder.cs index adf252cd6fe21b..3feb8bd630164b 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Dynamic/ConvertBinder.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Dynamic/ConvertBinder.cs @@ -68,11 +68,11 @@ public sealed override DynamicMetaObject Bind(DynamicMetaObject target, DynamicM /// /// Always returns true because this is a standard . /// - internal override sealed bool IsStandardBinder => true; + internal sealed override bool IsStandardBinder => true; /// /// The result type of the operation. /// - public override sealed Type ReturnType => Type; + public sealed override Type ReturnType => Type; } } diff --git a/src/libraries/System.Linq.Expressions/src/System/Dynamic/CreateInstanceBinder.cs b/src/libraries/System.Linq.Expressions/src/System/Dynamic/CreateInstanceBinder.cs index 0039c5845385d6..5fe0fbddc9708a 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Dynamic/CreateInstanceBinder.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Dynamic/CreateInstanceBinder.cs @@ -23,7 +23,7 @@ protected CreateInstanceBinder(CallInfo callInfo) /// /// The result type of the operation. /// - public override sealed Type ReturnType => typeof(object); + public sealed override Type ReturnType => typeof(object); /// /// Gets the signature of the arguments at the call site. @@ -67,6 +67,6 @@ public sealed override DynamicMetaObject Bind(DynamicMetaObject target, DynamicM /// /// Always returns true because this is a standard . /// - internal override sealed bool IsStandardBinder => true; + internal sealed override bool IsStandardBinder => true; } } diff --git a/src/libraries/System.Linq.Expressions/src/System/Dynamic/DeleteIndexBinder.cs b/src/libraries/System.Linq.Expressions/src/System/Dynamic/DeleteIndexBinder.cs index 02b0e5ec1056bf..b12295b8269700 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Dynamic/DeleteIndexBinder.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Dynamic/DeleteIndexBinder.cs @@ -23,7 +23,7 @@ protected DeleteIndexBinder(CallInfo callInfo) /// /// The result type of the operation. /// - public override sealed Type ReturnType => typeof(void); + public sealed override Type ReturnType => typeof(void); /// /// Gets the signature of the arguments at the call site. @@ -47,7 +47,7 @@ public sealed override DynamicMetaObject Bind(DynamicMetaObject target, DynamicM /// /// Always returns true because this is a standard . /// - internal override sealed bool IsStandardBinder => true; + internal sealed override bool IsStandardBinder => true; /// /// Performs the binding of the dynamic delete index operation if the target dynamic object cannot bind. diff --git a/src/libraries/System.Linq.Expressions/src/System/Dynamic/DeleteMemberBinder.cs b/src/libraries/System.Linq.Expressions/src/System/Dynamic/DeleteMemberBinder.cs index 263073a63ae8b3..60a7ab2d351e8c 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Dynamic/DeleteMemberBinder.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Dynamic/DeleteMemberBinder.cs @@ -36,7 +36,7 @@ protected DeleteMemberBinder(string name, bool ignoreCase) /// /// The result type of the operation. /// - public override sealed Type ReturnType => typeof(void); + public sealed override Type ReturnType => typeof(void); /// /// Performs the binding of the dynamic delete member operation if the target dynamic object cannot bind. @@ -73,6 +73,6 @@ public sealed override DynamicMetaObject Bind(DynamicMetaObject target, DynamicM /// /// Always returns true because this is a standard . /// - internal override sealed bool IsStandardBinder => true; + internal sealed override bool IsStandardBinder => true; } } diff --git a/src/libraries/System.Linq.Expressions/src/System/Dynamic/GetIndexBinder.cs b/src/libraries/System.Linq.Expressions/src/System/Dynamic/GetIndexBinder.cs index 33137b9e2d1f3d..93b086eeb4d9b8 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Dynamic/GetIndexBinder.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Dynamic/GetIndexBinder.cs @@ -23,7 +23,7 @@ protected GetIndexBinder(CallInfo callInfo) /// /// The result type of the operation. /// - public override sealed Type ReturnType => typeof(object); + public sealed override Type ReturnType => typeof(object); /// /// Gets the signature of the arguments at the call site. @@ -47,7 +47,7 @@ public sealed override DynamicMetaObject Bind(DynamicMetaObject target, DynamicM /// /// Always returns true because this is a standard . /// - internal override sealed bool IsStandardBinder => true; + internal sealed override bool IsStandardBinder => true; /// /// Performs the binding of the dynamic get index operation if the target dynamic object cannot bind. diff --git a/src/libraries/System.Linq.Expressions/src/System/Dynamic/GetMemberBinder.cs b/src/libraries/System.Linq.Expressions/src/System/Dynamic/GetMemberBinder.cs index dd8773e892acd5..25cc22354b0a3e 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Dynamic/GetMemberBinder.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Dynamic/GetMemberBinder.cs @@ -26,7 +26,7 @@ protected GetMemberBinder(string name, bool ignoreCase) /// /// The result type of the operation. /// - public override sealed Type ReturnType => typeof(object); + public sealed override Type ReturnType => typeof(object); /// /// Gets the name of the member to get. @@ -73,6 +73,6 @@ public sealed override DynamicMetaObject Bind(DynamicMetaObject target, params D /// /// Always returns true because this is a standard . /// - internal override sealed bool IsStandardBinder => true; + internal sealed override bool IsStandardBinder => true; } } diff --git a/src/libraries/System.Linq.Expressions/src/System/Dynamic/InvokeBinder.cs b/src/libraries/System.Linq.Expressions/src/System/Dynamic/InvokeBinder.cs index f02cc2802b0e21..1c9f895067d94d 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Dynamic/InvokeBinder.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Dynamic/InvokeBinder.cs @@ -23,7 +23,7 @@ protected InvokeBinder(CallInfo callInfo) /// /// The result type of the operation. /// - public override sealed Type ReturnType => typeof(object); + public sealed override Type ReturnType => typeof(object); /// /// Gets the signature of the arguments at the call site. @@ -67,6 +67,6 @@ public sealed override DynamicMetaObject Bind(DynamicMetaObject target, DynamicM /// /// Always returns true because this is a standard . /// - internal override sealed bool IsStandardBinder => true; + internal sealed override bool IsStandardBinder => true; } } diff --git a/src/libraries/System.Linq.Expressions/src/System/Dynamic/InvokeMemberBinder.cs b/src/libraries/System.Linq.Expressions/src/System/Dynamic/InvokeMemberBinder.cs index ccd26068cd9d0f..634d77b0ad36a2 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Dynamic/InvokeMemberBinder.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Dynamic/InvokeMemberBinder.cs @@ -29,7 +29,7 @@ protected InvokeMemberBinder(string name, bool ignoreCase, CallInfo callInfo) /// /// The result type of the operation. /// - public override sealed Type ReturnType => typeof(object); + public sealed override Type ReturnType => typeof(object); /// /// Gets the name of the member to invoke. @@ -63,7 +63,7 @@ public sealed override DynamicMetaObject Bind(DynamicMetaObject target, DynamicM /// /// Always returns true because this is a standard . /// - internal override sealed bool IsStandardBinder => true; + internal sealed override bool IsStandardBinder => true; /// /// Performs the binding of the dynamic invoke member operation if the target dynamic object cannot bind. diff --git a/src/libraries/System.Linq.Expressions/src/System/Dynamic/SetIndexBinder.cs b/src/libraries/System.Linq.Expressions/src/System/Dynamic/SetIndexBinder.cs index 1d75795f39ab34..8be0b539df48a2 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Dynamic/SetIndexBinder.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Dynamic/SetIndexBinder.cs @@ -23,7 +23,7 @@ protected SetIndexBinder(CallInfo callInfo) /// /// The result type of the operation. /// - public override sealed Type ReturnType => typeof(object); + public sealed override Type ReturnType => typeof(object); /// /// Gets the signature of the arguments at the call site. @@ -54,7 +54,7 @@ public sealed override DynamicMetaObject Bind(DynamicMetaObject target, DynamicM /// /// Always returns true because this is a standard . /// - internal override sealed bool IsStandardBinder => true; + internal sealed override bool IsStandardBinder => true; /// /// Performs the binding of the dynamic set index operation if the target dynamic object cannot bind. diff --git a/src/libraries/System.Linq.Expressions/src/System/Dynamic/SetMemberBinder.cs b/src/libraries/System.Linq.Expressions/src/System/Dynamic/SetMemberBinder.cs index 10089c45b9b401..4f0b805053c972 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Dynamic/SetMemberBinder.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Dynamic/SetMemberBinder.cs @@ -26,7 +26,7 @@ protected SetMemberBinder(string name, bool ignoreCase) /// /// The result type of the operation. /// - public override sealed Type ReturnType => typeof(object); + public sealed override Type ReturnType => typeof(object); /// /// Gets the name of the member to get. @@ -59,7 +59,7 @@ public sealed override DynamicMetaObject Bind(DynamicMetaObject target, DynamicM /// /// Always returns true because this is a standard . /// - internal override sealed bool IsStandardBinder => true; + internal sealed override bool IsStandardBinder => true; /// /// Performs the binding of the dynamic set member operation if the target dynamic object cannot bind. diff --git a/src/libraries/System.Linq.Expressions/src/System/Dynamic/UnaryOperationBinder.cs b/src/libraries/System.Linq.Expressions/src/System/Dynamic/UnaryOperationBinder.cs index 797eefd3295193..6d45ec4741ee4e 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Dynamic/UnaryOperationBinder.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Dynamic/UnaryOperationBinder.cs @@ -24,7 +24,7 @@ protected UnaryOperationBinder(ExpressionType operation) /// /// The result type of the operation. /// - public override sealed Type ReturnType + public sealed override Type ReturnType { get { @@ -79,7 +79,7 @@ public sealed override DynamicMetaObject Bind(DynamicMetaObject target, DynamicM /// /// Always returns true because this is a standard . /// - internal override sealed bool IsStandardBinder => true; + internal sealed override bool IsStandardBinder => true; internal static bool OperationIsValid(ExpressionType operation) { diff --git a/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/QueryOperators/BinaryQueryOperator.cs b/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/QueryOperators/BinaryQueryOperator.cs index dea0f4029c9465..88d1494b210621 100644 --- a/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/QueryOperators/BinaryQueryOperator.cs +++ b/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/QueryOperators/BinaryQueryOperator.cs @@ -54,7 +54,7 @@ internal QueryOperator RightChild get { return _rightChild; } } - internal override sealed OrdinalIndexState OrdinalIndexState + internal sealed override OrdinalIndexState OrdinalIndexState { get { return _indexState; } } diff --git a/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/QueryOperators/UnaryQueryOperator.cs b/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/QueryOperators/UnaryQueryOperator.cs index e8eb8d60e5b6ac..2972be36dabc15 100644 --- a/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/QueryOperators/UnaryQueryOperator.cs +++ b/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/QueryOperators/UnaryQueryOperator.cs @@ -62,7 +62,7 @@ internal QueryOperator Child get { return _child; } } - internal override sealed OrdinalIndexState OrdinalIndexState + internal sealed override OrdinalIndexState OrdinalIndexState { get { return _indexState; } } diff --git a/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/BsdIPGlobalProperties.cs b/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/BsdIPGlobalProperties.cs index 77fa68098f1e1b..b540490fb6a125 100644 --- a/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/BsdIPGlobalProperties.cs +++ b/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/BsdIPGlobalProperties.cs @@ -83,7 +83,7 @@ public override IPEndPoint[] GetActiveTcpListeners() return endPoints; } - public unsafe override IPEndPoint[] GetActiveUdpListeners() + public override unsafe IPEndPoint[] GetActiveUdpListeners() { int realCount = Interop.Sys.GetEstimatedUdpListenerCount(); int infoCount = realCount * 2; diff --git a/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemIPGlobalProperties.cs b/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemIPGlobalProperties.cs index 17213967c7f413..aece4dab54725d 100644 --- a/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemIPGlobalProperties.cs +++ b/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemIPGlobalProperties.cs @@ -211,7 +211,7 @@ private static unsafe List GetAllTcpConnections( } /// Gets the active UDP listeners. Uses the native GetUdpTable API. - public unsafe override IPEndPoint[] GetActiveUdpListeners() + public override unsafe IPEndPoint[] GetActiveUdpListeners() { uint size = 0; uint result; diff --git a/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/UnixIPGlobalProperties.cs b/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/UnixIPGlobalProperties.cs index eafa42ff3fec12..7a9be6b1ec3cc1 100644 --- a/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/UnixIPGlobalProperties.cs +++ b/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/UnixIPGlobalProperties.cs @@ -106,7 +106,7 @@ private static unsafe void ProcessIpv6Address(void* pContext, byte* ifaceName, I } } - public unsafe override UnicastIPAddressInformationCollection GetUnicastAddresses() + public override unsafe UnicastIPAddressInformationCollection GetUnicastAddresses() { Context context; context._collection = new UnicastIPAddressInformationCollection(); diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Mock/MockConnection.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Mock/MockConnection.cs index 930718974cedc8..63cf03e3d2ba63 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Mock/MockConnection.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/Mock/MockConnection.cs @@ -164,7 +164,7 @@ internal override ValueTask ConnectAsync(CancellationToken cancellationToken = d return ValueTask.CompletedTask; } - internal async override ValueTask OpenUnidirectionalStreamAsync(CancellationToken cancellationToken) + internal override async ValueTask OpenUnidirectionalStreamAsync(CancellationToken cancellationToken) { PeerStreamLimit? streamLimit = RemoteStreamLimit; if (streamLimit is null) @@ -187,7 +187,7 @@ internal async override ValueTask OpenUnidirectionalStreamAs return OpenStream(streamId, false); } - internal async override ValueTask OpenBidirectionalStreamAsync(CancellationToken cancellationToken) + internal override async ValueTask OpenBidirectionalStreamAsync(CancellationToken cancellationToken) { PeerStreamLimit? streamLimit = RemoteStreamLimit; if (streamLimit is null) diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs index 5bd20f4547c72f..0ee1c3917931af 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicConnection.cs @@ -497,7 +497,7 @@ internal override int GetRemoteAvailableBidirectionalStreamCount() return MsQuicParameterHelpers.GetUShortParam(MsQuicApi.Api, _state.Handle, QUIC_PARAM_CONN_LOCAL_BIDI_STREAM_COUNT); } - internal unsafe override ValueTask ConnectAsync(CancellationToken cancellationToken = default) + internal override unsafe ValueTask ConnectAsync(CancellationToken cancellationToken = default) { ThrowIfDisposed(); diff --git a/src/libraries/System.Private.CoreLib/src/System/DateTime.Windows.cs b/src/libraries/System.Private.CoreLib/src/System/DateTime.Windows.cs index f5de9ed1e93889..5ec5c7d0548a46 100644 --- a/src/libraries/System.Private.CoreLib/src/System/DateTime.Windows.cs +++ b/src/libraries/System.Private.CoreLib/src/System/DateTime.Windows.cs @@ -129,7 +129,7 @@ private static DateTime CreateDateTimeFromSystemTime(in Interop.Kernel32.SYSTEMT return new DateTime(ticks); } - private static unsafe readonly delegate* unmanaged[SuppressGCTransition] s_pfnGetSystemTimeAsFileTime = GetGetSystemTimeAsFileTimeFnPtr(); + private static readonly unsafe delegate* unmanaged[SuppressGCTransition] s_pfnGetSystemTimeAsFileTime = GetGetSystemTimeAsFileTimeFnPtr(); private static unsafe delegate* unmanaged[SuppressGCTransition] GetGetSystemTimeAsFileTimeFnPtr() { diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemEnumerator.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemEnumerator.Unix.cs index faf7bb8eee6969..430088be866d9a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemEnumerator.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemEnumerator.Unix.cs @@ -8,7 +8,7 @@ namespace System.IO.Enumeration { - public unsafe abstract partial class FileSystemEnumerator : CriticalFinalizerObject, IEnumerator + public abstract unsafe partial class FileSystemEnumerator : CriticalFinalizerObject, IEnumerator { // The largest supported path on Unix is 4K bytes of UTF-8 (most only support 1K) private const int StandardBufferSize = 4096; diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemEnumerator.Windows.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemEnumerator.Windows.cs index 265ac541bed12d..30f447a63cdd94 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemEnumerator.Windows.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemEnumerator.Windows.cs @@ -14,7 +14,7 @@ namespace System.IO.Enumeration { /// Enumerates the file system elements of the provided type that are being searched and filtered by a . - public unsafe abstract partial class FileSystemEnumerator : CriticalFinalizerObject, IEnumerator + public abstract unsafe partial class FileSystemEnumerator : CriticalFinalizerObject, IEnumerator { private const int StandardBufferSize = 4096; diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemEnumerator.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemEnumerator.cs index 7d774d7e51a8c3..bca11da56ee711 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemEnumerator.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Enumeration/FileSystemEnumerator.cs @@ -10,7 +10,7 @@ namespace System.IO.Enumeration { /// Enumerates the file system elements of the provided type that are being searched and filtered by a . /// The type of the result produced by this file system enumerator. - public unsafe abstract partial class FileSystemEnumerator : CriticalFinalizerObject, IEnumerator + public abstract unsafe partial class FileSystemEnumerator : CriticalFinalizerObject, IEnumerator { private int _remainingRecursionDepth; diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/FileStream.cs b/src/libraries/System.Private.CoreLib/src/System/IO/FileStream.cs index 9dcec98522b521..b86ba855be3b7e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/FileStream.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/FileStream.cs @@ -499,7 +499,7 @@ public override long Position // _strategy can be null only when ctor has thrown protected override void Dispose(bool disposing) => _strategy?.DisposeInternal(disposing); - public async override ValueTask DisposeAsync() + public override async ValueTask DisposeAsync() { await _strategy.DisposeAsync().ConfigureAwait(false); Dispose(false); diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Path.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Path.cs index 5b55e60a19d473..e7ed97c683a8b4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Path.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Path.cs @@ -696,7 +696,7 @@ private static unsafe string JoinInternal(ReadOnlySpan first, ReadOnlySpan string.Concat(first, PathInternal.DirectorySeparatorCharAsString, second); } - private unsafe readonly struct Join3Payload + private readonly unsafe struct Join3Payload { public Join3Payload(char* first, int firstLength, char* second, int secondLength, char* third, int thirdLength, byte separators) { @@ -750,7 +750,7 @@ private static unsafe string JoinInternal(ReadOnlySpan first, ReadOnlySpan } } - private unsafe readonly struct Join4Payload + private readonly unsafe struct Join4Payload { public Join4Payload(char* first, int firstLength, char* second, int secondLength, char* third, int thirdLength, char* fourth, int fourthLength, byte separators) { diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Strategies/OSFileStreamStrategy.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Strategies/OSFileStreamStrategy.cs index 912b6481cb3c21..9502490f590798 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Strategies/OSFileStreamStrategy.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Strategies/OSFileStreamStrategy.cs @@ -74,7 +74,7 @@ internal OSFileStreamStrategy(string path, FileMode mode, FileAccess access, Fil public sealed override bool CanWrite => !_fileHandle.IsClosed && (_access & FileAccess.Write) != 0; - public sealed unsafe override long Length => _fileHandle.GetFileLength(); + public sealed override unsafe long Length => _fileHandle.GetFileLength(); // in case of concurrent incomplete reads, there can be multiple threads trying to update the position // at the same time. That is why we are using Interlocked here. diff --git a/src/libraries/System.Private.CoreLib/src/System/Random.cs b/src/libraries/System.Private.CoreLib/src/System/Random.cs index 91070448823331..cc2363739465e1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Random.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Random.cs @@ -42,7 +42,7 @@ public Random(int Seed) => /// Constructor used by . /// Must be true. - protected private Random(bool isThreadSafeRandom) + private protected Random(bool isThreadSafeRandom) { Debug.Assert(isThreadSafeRandom); _impl = null!; // base implementation isn't used at all diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs index 7cb42d2a66ae7f..08769a6ab32fd0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs @@ -113,7 +113,7 @@ public partial struct ComInterfaceDispatch /// If the interface entries cannot be created and a negative or null and a non-zero are returned, /// the call to will throw a . /// - protected unsafe abstract ComInterfaceEntry* ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count); + protected abstract unsafe ComInterfaceEntry* ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count); /// /// Create a managed object for the object pointed at by respecting the values of . diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Latin1Encoding.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Latin1Encoding.cs index 8682764bb938ca..c2a61af56ba6a6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Latin1Encoding.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Latin1Encoding.cs @@ -192,7 +192,7 @@ public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int return GetBytesCommon(chars, charCount, bytes, byteCount); } - public unsafe override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) + public override unsafe int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) { if (chars is null || bytes is null) { @@ -391,7 +391,7 @@ public override int GetMaxCharCount(int byteCount) * We never consult the fallback mechanism during decoding. */ - public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount) + public override unsafe int GetChars(byte* bytes, int byteCount, char* chars, int charCount) { if (bytes is null || chars is null) { @@ -410,7 +410,7 @@ public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int return GetCharsCommon(bytes, byteCount, chars, charCount); } - public unsafe override char[] GetChars(byte[] bytes) + public override unsafe char[] GetChars(byte[] bytes) { if (bytes is null) { @@ -435,7 +435,7 @@ public unsafe override char[] GetChars(byte[] bytes) return chars; } - public unsafe override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) + public override unsafe int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) { if (bytes is null || chars is null) { @@ -468,7 +468,7 @@ public unsafe override int GetChars(byte[] bytes, int byteIndex, int byteCount, } } - public unsafe override char[] GetChars(byte[] bytes, int index, int count) + public override unsafe char[] GetChars(byte[] bytes, int index, int count) { if (bytes is null) { @@ -502,7 +502,7 @@ public unsafe override char[] GetChars(byte[] bytes, int index, int count) return chars; } - public unsafe override int GetChars(ReadOnlySpan bytes, Span chars) + public override unsafe int GetChars(ReadOnlySpan bytes, Span chars) { // It's ok for us to pass null pointers down to the workhorse below. @@ -513,7 +513,7 @@ public unsafe override int GetChars(ReadOnlySpan bytes, Span chars) } } - public unsafe override string GetString(byte[] bytes) + public override unsafe string GetString(byte[] bytes) { if (bytes is null) { @@ -532,7 +532,7 @@ public unsafe override string GetString(byte[] bytes) }); } - public unsafe override string GetString(byte[] bytes, int index, int count) + public override unsafe string GetString(byte[] bytes, int index, int count) { if (bytes is null) { diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Text/Base64Encoding.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Text/Base64Encoding.cs index 50b7fa46280a6a..7799953ac71b51 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Text/Base64Encoding.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Text/Base64Encoding.cs @@ -53,7 +53,7 @@ private static bool IsValidTailBytes(int v3, int v4) return !(v3 == 64 && v4 != 64); } - public unsafe override int GetByteCount(char[] chars, int index, int count) + public override unsafe int GetByteCount(char[] chars, int index, int count) { ArgumentNullException.ThrowIfNull(chars); @@ -107,7 +107,7 @@ public unsafe override int GetByteCount(char[] chars, int index, int count) } } - public unsafe override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) + public override unsafe int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) { ArgumentNullException.ThrowIfNull(chars); if (charIndex < 0) @@ -269,7 +269,7 @@ public override int GetCharCount(byte[] bytes, int index, int count) return GetMaxCharCount(count); } - public unsafe override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) + public override unsafe int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) { ArgumentNullException.ThrowIfNull(bytes); if (byteIndex < 0) diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Text/BinHexEncoding.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Text/BinHexEncoding.cs index be78f4037422be..7c2bdb7490b2dd 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Text/BinHexEncoding.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Text/BinHexEncoding.cs @@ -22,7 +22,7 @@ public override int GetByteCount(char[] chars, int index, int count) return GetMaxByteCount(count); } - public unsafe override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) + public override unsafe int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) { ArgumentNullException.ThrowIfNull(chars); if (charIndex < 0) @@ -64,7 +64,7 @@ public override int GetCharCount(byte[] bytes, int index, int count) return GetMaxCharCount(count); } - public unsafe override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) + public override unsafe int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) { ArgumentNullException.ThrowIfNull(bytes); if (byteIndex < 0) diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBaseReader.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBaseReader.cs index e48fbcc012eb17..928e571a7366ea 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBaseReader.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBaseReader.cs @@ -1014,7 +1014,7 @@ public override bool IsNamespaceUri(XmlDictionaryString namespaceUri) return _node.IsNamespaceUri(namespaceUri); } - public override sealed bool IsStartElement() + public sealed override bool IsStartElement() { XmlNodeType nodeType = _node.NodeType; if (nodeType == XmlNodeType.Element) diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBinaryWriter.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBinaryWriter.cs index 2abfda13f19fa5..7b060146400a68 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBinaryWriter.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBinaryWriter.cs @@ -602,7 +602,7 @@ public override void WriteText(XmlDictionaryString value) } } - public unsafe override void WriteText(string value) + public override unsafe void WriteText(string value) { if (_inAttribute) { @@ -624,7 +624,7 @@ public unsafe override void WriteText(string value) } } - public unsafe override void WriteText(char[] chars, int offset, int count) + public override unsafe void WriteText(char[] chars, int offset, int count) { if (_inAttribute) { @@ -746,7 +746,7 @@ public override void WriteCharEntity(int ch) } } - public unsafe override void WriteFloatText(float f) + public override unsafe void WriteFloatText(float f) { long l; if (f >= long.MinValue && f <= long.MaxValue && (l = (long)f) == f) @@ -767,7 +767,7 @@ public unsafe override void WriteFloatText(float f) } } - public unsafe override void WriteDoubleText(double d) + public override unsafe void WriteDoubleText(double d) { float f; if (d >= float.MinValue && d <= float.MaxValue && (f = (float)d) == d) @@ -792,7 +792,7 @@ public unsafe override void WriteDoubleText(double d) } } - public unsafe override void WriteDecimalText(decimal d) + public override unsafe void WriteDecimalText(decimal d) { int offset; byte[] buffer = GetTextNodeBuffer(1 + sizeof(decimal), out offset); @@ -1218,7 +1218,7 @@ private static void CheckArray(Array array, int offset, int count) throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(count), SR.Format(SR.SizeExceedsRemainingBufferSpace, array.Length - offset))); } - public unsafe override void WriteArray(string? prefix, string localName, string? namespaceUri, bool[] array, int offset, int count) + public override unsafe void WriteArray(string? prefix, string localName, string? namespaceUri, bool[] array, int offset, int count) { { CheckArray(array, offset, count); @@ -1232,7 +1232,7 @@ public unsafe override void WriteArray(string? prefix, string localName, string? } } - public unsafe override void WriteArray(string? prefix, XmlDictionaryString localName, XmlDictionaryString? namespaceUri, bool[] array, int offset, int count) + public override unsafe void WriteArray(string? prefix, XmlDictionaryString localName, XmlDictionaryString? namespaceUri, bool[] array, int offset, int count) { { CheckArray(array, offset, count); @@ -1246,7 +1246,7 @@ public unsafe override void WriteArray(string? prefix, XmlDictionaryString local } } - public unsafe override void WriteArray(string? prefix, string localName, string? namespaceUri, short[] array, int offset, int count) + public override unsafe void WriteArray(string? prefix, string localName, string? namespaceUri, short[] array, int offset, int count) { { CheckArray(array, offset, count); @@ -1260,7 +1260,7 @@ public unsafe override void WriteArray(string? prefix, string localName, string? } } - public unsafe override void WriteArray(string? prefix, XmlDictionaryString localName, XmlDictionaryString? namespaceUri, short[] array, int offset, int count) + public override unsafe void WriteArray(string? prefix, XmlDictionaryString localName, XmlDictionaryString? namespaceUri, short[] array, int offset, int count) { { CheckArray(array, offset, count); @@ -1274,7 +1274,7 @@ public unsafe override void WriteArray(string? prefix, XmlDictionaryString local } } - public unsafe override void WriteArray(string? prefix, string localName, string? namespaceUri, int[] array, int offset, int count) + public override unsafe void WriteArray(string? prefix, string localName, string? namespaceUri, int[] array, int offset, int count) { { CheckArray(array, offset, count); @@ -1288,7 +1288,7 @@ public unsafe override void WriteArray(string? prefix, string localName, string? } } - public unsafe override void WriteArray(string? prefix, XmlDictionaryString localName, XmlDictionaryString? namespaceUri, int[] array, int offset, int count) + public override unsafe void WriteArray(string? prefix, XmlDictionaryString localName, XmlDictionaryString? namespaceUri, int[] array, int offset, int count) { { CheckArray(array, offset, count); @@ -1302,7 +1302,7 @@ public unsafe override void WriteArray(string? prefix, XmlDictionaryString local } } - public unsafe override void WriteArray(string? prefix, string localName, string? namespaceUri, long[] array, int offset, int count) + public override unsafe void WriteArray(string? prefix, string localName, string? namespaceUri, long[] array, int offset, int count) { { CheckArray(array, offset, count); @@ -1316,7 +1316,7 @@ public unsafe override void WriteArray(string? prefix, string localName, string? } } - public unsafe override void WriteArray(string? prefix, XmlDictionaryString localName, XmlDictionaryString? namespaceUri, long[] array, int offset, int count) + public override unsafe void WriteArray(string? prefix, XmlDictionaryString localName, XmlDictionaryString? namespaceUri, long[] array, int offset, int count) { { CheckArray(array, offset, count); @@ -1330,7 +1330,7 @@ public unsafe override void WriteArray(string? prefix, XmlDictionaryString local } } - public unsafe override void WriteArray(string? prefix, string localName, string? namespaceUri, float[] array, int offset, int count) + public override unsafe void WriteArray(string? prefix, string localName, string? namespaceUri, float[] array, int offset, int count) { { CheckArray(array, offset, count); @@ -1344,7 +1344,7 @@ public unsafe override void WriteArray(string? prefix, string localName, string? } } - public unsafe override void WriteArray(string? prefix, XmlDictionaryString localName, XmlDictionaryString? namespaceUri, float[] array, int offset, int count) + public override unsafe void WriteArray(string? prefix, XmlDictionaryString localName, XmlDictionaryString? namespaceUri, float[] array, int offset, int count) { { CheckArray(array, offset, count); @@ -1358,7 +1358,7 @@ public unsafe override void WriteArray(string? prefix, XmlDictionaryString local } } - public unsafe override void WriteArray(string? prefix, string localName, string? namespaceUri, double[] array, int offset, int count) + public override unsafe void WriteArray(string? prefix, string localName, string? namespaceUri, double[] array, int offset, int count) { { CheckArray(array, offset, count); @@ -1372,7 +1372,7 @@ public unsafe override void WriteArray(string? prefix, string localName, string? } } - public unsafe override void WriteArray(string? prefix, XmlDictionaryString localName, XmlDictionaryString? namespaceUri, double[] array, int offset, int count) + public override unsafe void WriteArray(string? prefix, XmlDictionaryString localName, XmlDictionaryString? namespaceUri, double[] array, int offset, int count) { { CheckArray(array, offset, count); @@ -1386,7 +1386,7 @@ public unsafe override void WriteArray(string? prefix, XmlDictionaryString local } } - public unsafe override void WriteArray(string? prefix, string localName, string? namespaceUri, decimal[] array, int offset, int count) + public override unsafe void WriteArray(string? prefix, string localName, string? namespaceUri, decimal[] array, int offset, int count) { { CheckArray(array, offset, count); @@ -1400,7 +1400,7 @@ public unsafe override void WriteArray(string? prefix, string localName, string? } } - public unsafe override void WriteArray(string? prefix, XmlDictionaryString localName, XmlDictionaryString? namespaceUri, decimal[] array, int offset, int count) + public override unsafe void WriteArray(string? prefix, XmlDictionaryString localName, XmlDictionaryString? namespaceUri, decimal[] array, int offset, int count) { { CheckArray(array, offset, count); diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlUTF8TextWriter.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlUTF8TextWriter.cs index 5de6dd8b6785ea..936a4b4803c7bf 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlUTF8TextWriter.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlUTF8TextWriter.cs @@ -430,7 +430,7 @@ public override void WriteEscapedText(XmlDictionaryString s) WriteEscapedText(s.Value); } - public unsafe override void WriteEscapedText(string s) + public override unsafe void WriteEscapedText(string s) { int count = s.Length; if (count > 0) @@ -442,7 +442,7 @@ public unsafe override void WriteEscapedText(string s) } } - public unsafe override void WriteEscapedText(char[] s, int offset, int count) + public override unsafe void WriteEscapedText(char[] s, int offset, int count) { if (count > 0) { @@ -513,7 +513,7 @@ public override void WriteText(byte[] chars, int offset, int count) WriteUTF8Chars(chars, offset, count); } - public unsafe override void WriteText(char[] chars, int offset, int count) + public override unsafe void WriteText(char[] chars, int offset, int count) { if (count > 0) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNavigator.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNavigator.cs index 8baa5565a5ccc6..861960a71dd29b 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNavigator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathNavigator.cs @@ -36,7 +36,7 @@ public override string ToString() // XPathItem //----------------------------------------------- - public override sealed bool IsNode + public sealed override bool IsNode { get { return true; } } diff --git a/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Virtual/VirtualMethodBase.cs b/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Virtual/VirtualMethodBase.cs index f8a5e26d4b61f2..956021d1801d66 100644 --- a/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Virtual/VirtualMethodBase.cs +++ b/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Virtual/VirtualMethodBase.cs @@ -18,22 +18,22 @@ public override MethodAttributes Attributes get { return MethodAttributes.Public | MethodAttributes.HideBySig; } } - public override sealed CallingConventions CallingConvention + public sealed override CallingConventions CallingConvention { get { return CallingConventions.HasThis | CallingConventions.Standard; } } - public override sealed bool ContainsGenericParameters + public sealed override bool ContainsGenericParameters { get { return false; } } - public override sealed bool IsGenericMethod + public sealed override bool IsGenericMethod { get { return false; } } - public override sealed bool IsGenericMethodDefinition + public sealed override bool IsGenericMethodDefinition { get { return false; } } @@ -43,42 +43,42 @@ public override RuntimeMethodHandle MethodHandle get { throw new NotSupportedException(); } } - public override sealed Module Module + public sealed override Module Module { get { return DeclaringType!.Module; } } - public override sealed Type? ReflectedType + public sealed override Type? ReflectedType { get { return DeclaringType; } } - public override sealed ParameterInfo ReturnParameter + public sealed override ParameterInfo ReturnParameter { get { return _returnParameter ??= new VirtualReturnParameter(this); } } - public override sealed ICustomAttributeProvider ReturnTypeCustomAttributes + public sealed override ICustomAttributeProvider ReturnTypeCustomAttributes { get { return ReturnParameter; } } - public override sealed MethodInfo GetBaseDefinition() + public sealed override MethodInfo GetBaseDefinition() { return this; } - public override sealed Type[] GetGenericArguments() + public sealed override Type[] GetGenericArguments() { return CollectionServices.Empty(); } - public override sealed MethodInfo GetGenericMethodDefinition() + public sealed override MethodInfo GetGenericMethodDefinition() { throw new InvalidOperationException(); } - public override sealed MethodImplAttributes GetMethodImplementationFlags() + public sealed override MethodImplAttributes GetMethodImplementationFlags() { return MethodImplAttributes.IL; } @@ -89,7 +89,7 @@ public override ParameterInfo[] GetParameters() } [RequiresUnreferencedCode("If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), trimming can't validate that the requirements of those annotations are met.")] - public override sealed MethodInfo MakeGenericMethod(params Type[] typeArguments) + public sealed override MethodInfo MakeGenericMethod(params Type[] typeArguments) { throw new InvalidOperationException(SR.Format(SR.InvalidOperation_NotGenericMethodDefinition, this)); } diff --git a/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Virtual/VirtualPropertyBase.FuncPropertyAccessorBase.cs b/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Virtual/VirtualPropertyBase.FuncPropertyAccessorBase.cs index f6dab499a17356..5aed8a762ec7bd 100644 --- a/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Virtual/VirtualPropertyBase.FuncPropertyAccessorBase.cs +++ b/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Virtual/VirtualPropertyBase.FuncPropertyAccessorBase.cs @@ -21,12 +21,12 @@ public CustomReflectionContext ReflectionContext get { return DeclaringProperty.ReflectionContext; } } - public override sealed MethodAttributes Attributes + public sealed override MethodAttributes Attributes { get { return base.Attributes | MethodAttributes.SpecialName; } } - public override sealed Type? DeclaringType + public sealed override Type? DeclaringType { get { return DeclaringProperty.DeclaringType; } } diff --git a/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Virtual/VirtualPropertyBase.PropertyGetterBase.cs b/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Virtual/VirtualPropertyBase.PropertyGetterBase.cs index 252f8d63b32a52..4149a650b76b19 100644 --- a/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Virtual/VirtualPropertyBase.PropertyGetterBase.cs +++ b/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Virtual/VirtualPropertyBase.PropertyGetterBase.cs @@ -12,12 +12,12 @@ protected PropertyGetterBase(VirtualPropertyBase property) { } - public override sealed string Name + public sealed override string Name { get { return "get_" + DeclaringProperty.Name; } } - public override sealed Type ReturnType + public sealed override Type ReturnType { get { return DeclaringProperty.PropertyType; } } diff --git a/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Virtual/VirtualPropertyBase.PropertySetterBase.cs b/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Virtual/VirtualPropertyBase.PropertySetterBase.cs index 245b618bed6317..8642fef1619b99 100644 --- a/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Virtual/VirtualPropertyBase.PropertySetterBase.cs +++ b/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Virtual/VirtualPropertyBase.PropertySetterBase.cs @@ -14,12 +14,12 @@ protected PropertySetterBase(VirtualPropertyBase property) { } - public override sealed string Name + public sealed override string Name { get { return "set_" + DeclaringProperty.Name; } } - public override sealed Type ReturnType + public sealed override Type ReturnType { get { return DeclaringProperty.ReflectionContext.MapType(IntrospectionExtensions.GetTypeInfo(typeof(void))); } } diff --git a/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Virtual/VirtualPropertyBase.cs b/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Virtual/VirtualPropertyBase.cs index 279bd2947412b2..772f2d102a5da2 100644 --- a/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Virtual/VirtualPropertyBase.cs +++ b/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Virtual/VirtualPropertyBase.cs @@ -35,52 +35,52 @@ protected VirtualPropertyBase(Type propertyType, string name, CustomReflectionCo public CustomReflectionContext ReflectionContext { get; } - public override sealed PropertyAttributes Attributes + public sealed override PropertyAttributes Attributes { get { return PropertyAttributes.None; } } - public override sealed Type? DeclaringType + public sealed override Type? DeclaringType { get { return _declaringType; } } - public override sealed string Name + public sealed override string Name { get { return _name; } } - public override sealed Type PropertyType + public sealed override Type PropertyType { get { return _propertyType; } } - public override sealed bool CanRead + public sealed override bool CanRead { get { return GetGetMethod(true) != null; } } - public override sealed bool CanWrite + public sealed override bool CanWrite { get { return GetSetMethod(true) != null; } } - public override sealed int MetadataToken + public sealed override int MetadataToken { get { throw new InvalidOperationException(); } } - public override sealed Module Module + public sealed override Module Module { get { return DeclaringType!.Module; } } - public override sealed Type? ReflectedType + public sealed override Type? ReflectedType { get { return DeclaringType; } } - public override sealed MethodInfo[] GetAccessors(bool nonPublic) + public sealed override MethodInfo[] GetAccessors(bool nonPublic) { MethodInfo? getMethod = GetGetMethod(nonPublic); MethodInfo? setMethod = GetSetMethod(nonPublic); @@ -95,12 +95,12 @@ public override sealed MethodInfo[] GetAccessors(bool nonPublic) return new MethodInfo[] { getMethod, setMethod }; } - public override sealed ParameterInfo[] GetIndexParameters() + public sealed override ParameterInfo[] GetIndexParameters() { return (ParameterInfo[])GetIndexParametersNoCopy().Clone(); } - public override sealed object? GetValue(object? obj, BindingFlags invokeAttr, Binder? binder, object?[]? index, CultureInfo? culture) + public sealed override object? GetValue(object? obj, BindingFlags invokeAttr, Binder? binder, object?[]? index, CultureInfo? culture) { MethodInfo? getMethod = GetGetMethod(true); if (getMethod == null) @@ -109,7 +109,7 @@ public override sealed ParameterInfo[] GetIndexParameters() return getMethod.Invoke(obj, invokeAttr, binder, index, culture); } - public override sealed void SetValue(object? obj, object? value, BindingFlags invokeAttr, Binder? binder, object?[]? index, CultureInfo? culture) + public sealed override void SetValue(object? obj, object? value, BindingFlags invokeAttr, Binder? binder, object?[]? index, CultureInfo? culture) { MethodInfo? setMethod = GetSetMethod(true); if (setMethod == null) @@ -134,22 +134,22 @@ public override sealed void SetValue(object? obj, object? value, BindingFlags in setMethod.Invoke(obj, invokeAttr, binder, args, culture); } - public override sealed object GetConstantValue() + public sealed override object GetConstantValue() { throw new InvalidOperationException(SR.InvalidOperation_EnumLitValueNotFound); } - public override sealed object GetRawConstantValue() + public sealed override object GetRawConstantValue() { throw new InvalidOperationException(SR.InvalidOperation_EnumLitValueNotFound); } - public override sealed Type[] GetOptionalCustomModifiers() + public sealed override Type[] GetOptionalCustomModifiers() { return CollectionServices.Empty(); } - public override sealed Type[] GetRequiredCustomModifiers() + public sealed override Type[] GetRequiredCustomModifiers() { return CollectionServices.Empty(); } diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/MemoryBlocks/AbstractMemoryBlock.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/MemoryBlocks/AbstractMemoryBlock.cs index 249895308f8773..c53809dec36cab 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/MemoryBlocks/AbstractMemoryBlock.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/MemoryBlocks/AbstractMemoryBlock.cs @@ -14,7 +14,7 @@ internal abstract class AbstractMemoryBlock : IDisposable /// /// Pointer to the underlying data (not valid after disposal). /// - public unsafe abstract byte* Pointer { get; } + public abstract unsafe byte* Pointer { get; } /// /// Size of the block. @@ -32,7 +32,7 @@ internal abstract class AbstractMemoryBlock : IDisposable /// Only creates a copy of the data if they are not represented by a managed byte array, /// or if the specified range doesn't span the entire block. /// - public unsafe virtual ImmutableArray GetContentUnchecked(int start, int length) + public virtual unsafe ImmutableArray GetContentUnchecked(int start, int length) { var result = BlobUtilities.ReadImmutableBytes(Pointer + start, length); GC.KeepAlive(this); diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/MemoryBlocks/ByteArrayMemoryBlock.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/MemoryBlocks/ByteArrayMemoryBlock.cs index edcfe38bea0eb3..462a621ca5e6a8 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/MemoryBlocks/ByteArrayMemoryBlock.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/MemoryBlocks/ByteArrayMemoryBlock.cs @@ -27,7 +27,7 @@ public override void Dispose() _provider = null!; } - public unsafe override byte* Pointer => _provider.Pointer + _start; + public override unsafe byte* Pointer => _provider.Pointer + _start; public override int Size => _size; public override ImmutableArray GetContentUnchecked(int start, int length) diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/MemoryBlocks/NativeHeapMemoryBlock.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/MemoryBlocks/NativeHeapMemoryBlock.cs index b2e41470f5b32d..bbcd1a0e60b92c 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/MemoryBlocks/NativeHeapMemoryBlock.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/MemoryBlocks/NativeHeapMemoryBlock.cs @@ -64,7 +64,7 @@ internal NativeHeapMemoryBlock(int size) } public override void Dispose() => _data.Dispose(); - public unsafe override byte* Pointer => _data.Pointer; + public override unsafe byte* Pointer => _data.Pointer; public override int Size => _size; } } diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/ReadOnlyUnmanagedMemoryStream.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/ReadOnlyUnmanagedMemoryStream.cs index abb5c8ff1f6af5..2a31a96a154058 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/ReadOnlyUnmanagedMemoryStream.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/ReadOnlyUnmanagedMemoryStream.cs @@ -18,7 +18,7 @@ public ReadOnlyUnmanagedMemoryStream(byte* data, int length) _length = length; } - public unsafe override int ReadByte() + public override unsafe int ReadByte() { if (_position >= _length) { diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataStringDecoder.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataStringDecoder.cs index 73c63f5105987c..541c29a43f6377 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataStringDecoder.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataStringDecoder.cs @@ -65,7 +65,7 @@ public MetadataStringDecoder(Encoding encoding) /// Pointer to bytes to decode. /// Number of bytes to decode. /// The decoded string. - public unsafe virtual string GetString(byte* bytes, int byteCount) + public virtual unsafe string GetString(byte* bytes, int byteCount) { Debug.Assert(Encoding != null); diff --git a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoType.cs b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoType.cs index 278671ad58be56..57341e16a36d39 100644 --- a/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoType.cs +++ b/src/libraries/System.Reflection.MetadataLoadContext/src/System/Reflection/TypeLoading/Types/RoType.cs @@ -15,7 +15,7 @@ internal abstract partial class RoType : LeveledTypeInfo { private const TypeAttributes TypeAttributesSentinel = (TypeAttributes)(-1); - protected private RoType() + private protected RoType() : base() { } diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/AnyOS/ManagedPal.Asn.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/AnyOS/ManagedPal.Asn.cs index 8789701db674d4..b31f25b50824c9 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/AnyOS/ManagedPal.Asn.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/AnyOS/ManagedPal.Asn.cs @@ -11,7 +11,7 @@ namespace Internal.Cryptography.Pal.AnyOS { internal sealed partial class ManagedPkcsPal : PkcsPal { - public unsafe override Oid GetEncodedMessageType(ReadOnlySpan encodedMessage) + public override unsafe Oid GetEncodedMessageType(ReadOnlySpan encodedMessage) { fixed (byte* pin = encodedMessage) { diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/Windows/DecryptorPalWindows.Decrypt.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/Windows/DecryptorPalWindows.Decrypt.cs index cd237b194fa52a..0d0f2bb2eacf9a 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/Windows/DecryptorPalWindows.Decrypt.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/Windows/DecryptorPalWindows.Decrypt.cs @@ -16,7 +16,7 @@ namespace Internal.Cryptography.Pal.Windows { internal sealed partial class DecryptorPalWindows : DecryptorPal { - public sealed unsafe override ContentInfo? TryDecrypt( + public sealed override unsafe ContentInfo? TryDecrypt( RecipientInfo recipientInfo, X509Certificate2? cert, AsymmetricAlgorithm? privateKey, diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/Windows/PkcsPalWindows.Encrypt.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/Windows/PkcsPalWindows.Encrypt.cs index 47722aea4eea2a..177cccd0408194 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/Windows/PkcsPalWindows.Encrypt.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/Pal/Windows/PkcsPalWindows.Encrypt.cs @@ -19,7 +19,7 @@ namespace Internal.Cryptography.Pal.Windows { internal sealed partial class PkcsPalWindows : PkcsPal { - public sealed unsafe override byte[] Encrypt(CmsRecipientCollection recipients, ContentInfo contentInfo, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes) + public sealed override unsafe byte[] Encrypt(CmsRecipientCollection recipients, ContentInfo contentInfo, AlgorithmIdentifier contentEncryptionAlgorithm, X509Certificate2Collection originatorCerts, CryptographicAttributeObjectCollection unprotectedAttributes) { using (SafeCryptMsgHandle hCryptMsg = EncodeHelpers.CreateCryptMsgHandleToEncode(recipients, contentInfo.ContentType, contentEncryptionAlgorithm, originatorCerts, unprotectedAttributes)) { diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CryptoStream.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CryptoStream.cs index 00795d91213337..ee4a77f8ecbb12 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CryptoStream.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CryptoStream.cs @@ -659,7 +659,7 @@ unsafe static int TransformBlock(ICryptoTransform transform, ReadOnlyMemory - public unsafe override void CopyTo(Stream destination, int bufferSize) + public override unsafe void CopyTo(Stream destination, int bufferSize) { CheckCopyToArguments(destination, bufferSize); diff --git a/src/libraries/System.Text.Encoding.CodePages/src/System/Text/DBCSCodePageEncoding.cs b/src/libraries/System.Text.Encoding.CodePages/src/System/Text/DBCSCodePageEncoding.cs index 6815ec33448f26..bdfe2aaba74ec3 100644 --- a/src/libraries/System.Text.Encoding.CodePages/src/System/Text/DBCSCodePageEncoding.cs +++ b/src/libraries/System.Text.Encoding.CodePages/src/System/Text/DBCSCodePageEncoding.cs @@ -240,7 +240,7 @@ private static object InternalSyncObject } // Read in our best fit table - protected unsafe override void ReadBestFitTable() + protected override unsafe void ReadBestFitTable() { // Lock so we don't confuse ourselves. lock (InternalSyncObject) diff --git a/src/libraries/System.Text.Encoding.CodePages/src/System/Text/EncodingNLS.cs b/src/libraries/System.Text.Encoding.CodePages/src/System/Text/EncodingNLS.cs index 6109e97a436fb8..f13cae45c5907f 100644 --- a/src/libraries/System.Text.Encoding.CodePages/src/System/Text/EncodingNLS.cs +++ b/src/libraries/System.Text.Encoding.CodePages/src/System/Text/EncodingNLS.cs @@ -34,10 +34,10 @@ protected EncodingNLS(int codePage, EncoderFallback enc, DecoderFallback dec) { } - public unsafe abstract int GetByteCount(char* chars, int count, EncoderNLS? encoder); - public unsafe abstract int GetBytes(char* chars, int charCount, byte* bytes, int byteCount, EncoderNLS? encoder); - public unsafe abstract int GetCharCount(byte* bytes, int count, DecoderNLS? decoder); - public unsafe abstract int GetChars(byte* bytes, int byteCount, char* chars, int charCount, DecoderNLS? decoder); + public abstract unsafe int GetByteCount(char* chars, int count, EncoderNLS? encoder); + public abstract unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount, EncoderNLS? encoder); + public abstract unsafe int GetCharCount(byte* bytes, int count, DecoderNLS? decoder); + public abstract unsafe int GetChars(byte* bytes, int byteCount, char* chars, int charCount, DecoderNLS? decoder); // Returns the number of bytes required to encode a range of characters in // a character array. @@ -269,7 +269,7 @@ public override unsafe int GetChars(byte[] bytes, int byteIndex, int byteCount, // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS) // So if you fix this, fix the others. - public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount) + public override unsafe int GetChars(byte* bytes, int byteCount, char* chars, int charCount) { if (bytes is null) throw new ArgumentNullException(nameof(bytes)); diff --git a/src/libraries/System.Text.Encoding.CodePages/src/System/Text/SBCSCodePageEncoding.cs b/src/libraries/System.Text.Encoding.CodePages/src/System/Text/SBCSCodePageEncoding.cs index d0c0330f67a608..770dbffaa77985 100644 --- a/src/libraries/System.Text.Encoding.CodePages/src/System/Text/SBCSCodePageEncoding.cs +++ b/src/libraries/System.Text.Encoding.CodePages/src/System/Text/SBCSCodePageEncoding.cs @@ -144,7 +144,7 @@ private static object InternalSyncObject } // Read in our best fit table - protected unsafe override void ReadBestFitTable() + protected override unsafe void ReadBestFitTable() { // Lock so we don't confuse ourselves. lock (InternalSyncObject) diff --git a/src/libraries/System.Text.Encodings.Web/src/System/Text/Encodings/Web/TextEncoder.cs b/src/libraries/System.Text.Encodings.Web/src/System/Text/Encodings/Web/TextEncoder.cs index d08ed6ac033804..41b620e1beec02 100644 --- a/src/libraries/System.Text.Encodings.Web/src/System/Text/Encodings/Web/TextEncoder.cs +++ b/src/libraries/System.Text.Encodings.Web/src/System/Text/Encodings/Web/TextEncoder.cs @@ -36,7 +36,7 @@ public abstract class TextEncoder /// [CLSCompliant(false)] [EditorBrowsable(EditorBrowsableState.Never)] - public unsafe abstract bool TryEncodeUnicodeScalar(int unicodeScalar, char* buffer, int bufferLength, out int numberOfCharactersWritten); + public abstract unsafe bool TryEncodeUnicodeScalar(int unicodeScalar, char* buffer, int bufferLength, out int numberOfCharactersWritten); [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe bool TryEncodeUnicodeScalar(uint unicodeScalar, Span buffer, out int charsWritten) @@ -103,7 +103,7 @@ private bool TryEncodeUnicodeScalarUtf8(uint unicodeScalar, Span utf16Scra /// This method is seldom called directly. It's used by higher level helper APIs. [CLSCompliant(false)] [EditorBrowsable(EditorBrowsableState.Never)] - public unsafe abstract int FindFirstCharacterToEncode(char* text, int textLength); + public abstract unsafe int FindFirstCharacterToEncode(char* text, int textLength); /// /// Determines if a given Unicode scalar will be encoded. diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs index 6154983c61d2d5..98e477f95d398a 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverterOfT.cs @@ -59,7 +59,7 @@ internal sealed override JsonPropertyInfo CreateJsonPropertyInfo() return new JsonPropertyInfo(); } - internal override sealed JsonParameterInfo CreateJsonParameterInfo() + internal sealed override JsonParameterInfo CreateJsonParameterInfo() { return new JsonParameterInfo(); } @@ -246,14 +246,14 @@ internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSeriali return success; } - internal override sealed bool OnTryReadAsObject(ref Utf8JsonReader reader, JsonSerializerOptions options, ref ReadStack state, out object? value) + internal sealed override bool OnTryReadAsObject(ref Utf8JsonReader reader, JsonSerializerOptions options, ref ReadStack state, out object? value) { bool success = OnTryRead(ref reader, TypeToConvert, options, ref state, out T? typedValue); value = typedValue; return success; } - internal override sealed bool TryReadAsObject(ref Utf8JsonReader reader, JsonSerializerOptions options, ref ReadStack state, out object? value) + internal sealed override bool TryReadAsObject(ref Utf8JsonReader reader, JsonSerializerOptions options, ref ReadStack state, out object? value) { bool success = TryRead(ref reader, TypeToConvert, options, ref state, out T? typedValue); value = typedValue; diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/Metadata/MetadataUpdater.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/Metadata/MetadataUpdater.cs index a3c1517ee60274..d70267febc66cb 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/Metadata/MetadataUpdater.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/Metadata/MetadataUpdater.cs @@ -63,6 +63,6 @@ private static string InitializeApplyUpdateCapabilities() private static extern int ApplyUpdateEnabled (int justComponentCheck); [MethodImpl (MethodImplOptions.InternalCall)] - private static unsafe extern void ApplyUpdate_internal (IntPtr base_assm, byte* dmeta_bytes, int dmeta_length, byte *dil_bytes, int dil_length, byte *dpdb_bytes, int dpdb_length); + private static extern unsafe void ApplyUpdate_internal (IntPtr base_assm, byte* dmeta_bytes, int dmeta_length, byte *dil_bytes, int dil_length, byte *dpdb_bytes, int dpdb_length); } } From 5efc1bb8cab465ab5d0ff629b72ebaf0e70e96d0 Mon Sep 17 00:00:00 2001 From: "MSDN.WhiteKnight" <35516665+MSDN-WhiteKnight@users.noreply.github.com> Date: Fri, 10 Jun 2022 15:57:00 +0500 Subject: [PATCH 030/337] Add markdown Readme for System.Text.Json (#69015) * Update project * Create readme.md * Fix typo * Update src/libraries/System.Text.Json/src/readme.md Co-authored-by: Eirik Tsarpalis * Delete readme.md * Rename readme file * Add more docs links * Fix link * Update PackageDescription * Apply suggestions from code review Co-authored-by: Eirik Tsarpalis Co-authored-by: Viktor Hofer * Remove mentions of exact target framework versions Co-authored-by: Eirik Tsarpalis Co-authored-by: Viktor Hofer --- src/libraries/System.Text.Json/src/README.md | 11 +++++++++++ .../System.Text.Json/src/System.Text.Json.csproj | 13 +++---------- 2 files changed, 14 insertions(+), 10 deletions(-) create mode 100644 src/libraries/System.Text.Json/src/README.md diff --git a/src/libraries/System.Text.Json/src/README.md b/src/libraries/System.Text.Json/src/README.md new file mode 100644 index 00000000000000..892946041791ca --- /dev/null +++ b/src/libraries/System.Text.Json/src/README.md @@ -0,0 +1,11 @@ +## About + +Provides high-performance and low-allocating types that serialize objects to JavaScript Object Notation (JSON) text and deserialize JSON text to objects, with UTF-8 support built-in. Also provides types to read and write JSON text encoded as UTF-8, and to create an in-memory document object model (DOM), that is read-only, for random access of the JSON elements within a structured view of the data. + +The `System.Text.Json` library is built-in as part of the shared framework in .NET Runtime. The package can be installed when you need to use it in other target frameworks. + +For more information, see the documentation: + +- [JSON serialization and deserialization in .NET](https://docs.microsoft.com/dotnet/standard/serialization/system-text-json-overview) +- [How to serialize and deserialize JSON in .NET](https://docs.microsoft.com/dotnet/standard/serialization/system-text-json-how-to) +- [System.Text.Json API reference](https://docs.microsoft.com/dotnet/api/system.text.json) diff --git a/src/libraries/System.Text.Json/src/System.Text.Json.csproj b/src/libraries/System.Text.Json/src/System.Text.Json.csproj index 8ecdb514ad65bd..0e4522699262a0 100644 --- a/src/libraries/System.Text.Json/src/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/src/System.Text.Json.csproj @@ -12,16 +12,8 @@ true Provides high-performance and low-allocating types that serialize objects to JavaScript Object Notation (JSON) text and deserialize JSON text to objects, with UTF-8 support built-in. Also provides types to read and write JSON text encoded as UTF-8, and to create an in-memory document object model (DOM), that is read-only, for random access of the JSON elements within a structured view of the data. -Commonly Used Types: -System.Text.Json.JsonSerializer -System.Text.Json.JsonDocument -System.Text.Json.JsonElement -System.Text.Json.Utf8JsonWriter -System.Text.Json.Utf8JsonReader -System.Text.Json.Nodes.JsonNode -System.Text.Json.Nodes.JsonArray -System.Text.Json.Nodes.JsonObject -System.Text.Json.Nodes.JsonValue +The System.Text.Json library is built-in as part of the shared framework in .NET Runtime. The package can be installed when you need to use it in other target frameworks. + README.md @@ -319,6 +311,7 @@ System.Text.Json.Nodes.JsonValue + From 95e8cae134f6cb046e2967bdcb7d8a89ff79ddfe Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Fri, 10 Jun 2022 12:58:37 +0200 Subject: [PATCH 031/337] Add disasm comments for field data addresses and code addresses (#70437) * Fix impTokenToHandle when importing parent This was mistakenly creating a handle for the parent (always a class) but specifying the handle type of the child (e.g. constructor method handle). * Do not lie about critical sections being method handles --- src/coreclr/jit/codegenarm64.cpp | 13 +++++----- src/coreclr/jit/codegenxarch.cpp | 9 ++++--- src/coreclr/jit/compiler.h | 2 +- src/coreclr/jit/compiler.hpp | 5 ++-- src/coreclr/jit/emit.cpp | 44 ++++++++++++++++++++++---------- src/coreclr/jit/emit.h | 4 +-- src/coreclr/jit/emitarm64.cpp | 29 +++++++++++++++++---- src/coreclr/jit/emitarm64.h | 12 ++++++--- src/coreclr/jit/emitxarch.cpp | 29 ++++++++++++++++++--- src/coreclr/jit/emitxarch.h | 5 +++- src/coreclr/jit/flowgraph.cpp | 2 +- src/coreclr/jit/gentree.cpp | 12 ++++++--- src/coreclr/jit/gentree.h | 3 +-- src/coreclr/jit/importer.cpp | 8 +++--- src/coreclr/jit/morph.cpp | 18 ++++++------- 15 files changed, 134 insertions(+), 61 deletions(-) diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index 2b9d4be0abc7d9..b891e640cad592 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -2178,7 +2178,7 @@ void CodeGen::instGen_Set_Reg_To_Imm(emitAttr size, { if (emitter::emitIns_valid_imm_for_mov(imm, size)) { - GetEmitter()->emitIns_R_I(INS_mov, size, reg, imm); + GetEmitter()->emitIns_R_I(INS_mov, size, reg, imm, INS_OPTS_NONE DEBUGARG(targetHandle) DEBUGARG(gtFlags)); } else { @@ -2224,7 +2224,9 @@ void CodeGen::instGen_Set_Reg_To_Imm(emitAttr size, imm16 = ~imm16; } - GetEmitter()->emitIns_R_I_I(ins, size, reg, imm16, i, INS_OPTS_LSL); + GetEmitter()->emitIns_R_I_I(ins, size, reg, imm16, i, + INS_OPTS_LSL DEBUGARG(i == 0 ? targetHandle : 0) + DEBUGARG(i == 0 ? gtFlags : GTF_EMPTY)); // Once the initial movz/movn is emitted the remaining instructions will all use movk ins = INS_movk; @@ -2258,8 +2260,8 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre { case GT_CNS_INT: { - GenTreeIntConCommon* con = tree->AsIntConCommon(); - ssize_t cnsVal = con->IconValue(); + GenTreeIntCon* con = tree->AsIntCon(); + ssize_t cnsVal = con->IconValue(); emitAttr attr = emitActualTypeSize(targetType); // TODO-CQ: Currently we cannot do this for all handles because of @@ -2275,8 +2277,7 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre } instGen_Set_Reg_To_Imm(attr, targetReg, cnsVal, - INS_FLAGS_DONT_CARE DEBUGARG(tree->AsIntCon()->gtTargetHandle) - DEBUGARG(tree->AsIntCon()->gtFlags)); + INS_FLAGS_DONT_CARE DEBUGARG(con->gtTargetHandle) DEBUGARG(con->gtFlags)); regSet.verifyRegUsed(targetReg); } break; diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index 039d4c11185225..bb1206bfb5c5bf 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -442,7 +442,7 @@ void CodeGen::instGen_Set_Reg_To_Imm(emitAttr size, } else { - GetEmitter()->emitIns_R_I(INS_mov, size, reg, imm DEBUGARG(gtFlags)); + GetEmitter()->emitIns_R_I(INS_mov, size, reg, imm DEBUGARG(targetHandle) DEBUGARG(gtFlags)); } } regSet.verifyRegUsed(reg); @@ -462,8 +462,8 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre { // relocatable values tend to come down as a CNS_INT of native int type // so the line between these two opcodes is kind of blurry - GenTreeIntConCommon* con = tree->AsIntConCommon(); - ssize_t cnsVal = con->IconValue(); + GenTreeIntCon* con = tree->AsIntCon(); + ssize_t cnsVal = con->IconValue(); emitAttr attr = emitActualTypeSize(targetType); // Currently this cannot be done for all handles due to @@ -482,7 +482,8 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre attr = EA_SET_FLG(attr, EA_BYREF_FLG); } - instGen_Set_Reg_To_Imm(attr, targetReg, cnsVal, INS_FLAGS_DONT_CARE DEBUGARG(0) DEBUGARG(tree->gtFlags)); + instGen_Set_Reg_To_Imm(attr, targetReg, cnsVal, + INS_FLAGS_DONT_CARE DEBUGARG(con->gtTargetHandle) DEBUGARG(con->gtFlags)); regSet.verifyRegUsed(targetReg); } break; diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index b4c7eb375b4d22..363ec0b9a2f9ac 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -2269,7 +2269,7 @@ class Compiler GenTree* gtNewIndOfIconHandleNode(var_types indType, size_t value, GenTreeFlags iconFlags, bool isInvariant); - GenTree* gtNewIconHandleNode(size_t value, GenTreeFlags flags, FieldSeqNode* fields = nullptr); + GenTreeIntCon* gtNewIconHandleNode(size_t value, GenTreeFlags flags, FieldSeqNode* fields = nullptr); GenTreeFlags gtTokenToIconFlags(unsigned token); diff --git a/src/coreclr/jit/compiler.hpp b/src/coreclr/jit/compiler.hpp index 2fe7c10574c6b0..5499893630cbc6 100644 --- a/src/coreclr/jit/compiler.hpp +++ b/src/coreclr/jit/compiler.hpp @@ -902,9 +902,8 @@ inline GenTree* Compiler::gtNewLargeOperNode(genTreeOps oper, var_types type, Ge * that may need to be fixed up). */ -inline GenTree* Compiler::gtNewIconHandleNode(size_t value, GenTreeFlags flags, FieldSeqNode* fields) +inline GenTreeIntCon* Compiler::gtNewIconHandleNode(size_t value, GenTreeFlags flags, FieldSeqNode* fields) { - GenTree* node; assert((flags & (GTF_ICON_HDL_MASK | GTF_ICON_FIELD_OFF)) != 0); // Interpret "fields == NULL" as "not a field." @@ -913,6 +912,7 @@ inline GenTree* Compiler::gtNewIconHandleNode(size_t value, GenTreeFlags flags, fields = FieldSeqStore::NotAField(); } + GenTreeIntCon* node; #if defined(LATE_DISASM) node = new (this, LargeOpOpcode()) GenTreeIntCon(TYP_I_IMPL, value, fields DEBUGARG(/*largeNode*/ true)); #else @@ -1370,6 +1370,7 @@ inline void GenTree::SetOper(genTreeOps oper, ValueNumberUpdate vnUpdate) { case GT_CNS_INT: AsIntCon()->gtFieldSeq = FieldSeqStore::NotAField(); + INDEBUG(AsIntCon()->gtTargetHandle = 0); break; #if defined(TARGET_ARM) case GT_MUL_LONG: diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index ebd4f2120585af..a8777adc3ed9cb 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -4045,16 +4045,12 @@ void emitter::emitRecomputeIGoffsets() // // Arguments: // handle - a constant value to display a comment for +// cookie - the cookie stored with the handle // flags - a flag that the describes the handle // -void emitter::emitDispCommentForHandle(size_t handle, GenTreeFlags flag) +void emitter::emitDispCommentForHandle(size_t handle, size_t cookie, GenTreeFlags flag) { #ifdef DEBUG - if (handle == 0) - { - return; - } - #ifdef TARGET_XARCH const char* commentPrefix = " ;"; #else @@ -4062,8 +4058,35 @@ void emitter::emitDispCommentForHandle(size_t handle, GenTreeFlags flag) #endif flag &= GTF_ICON_HDL_MASK; - const char* str = nullptr; + if (cookie != 0) + { + if (flag == GTF_ICON_FTN_ADDR) + { + const char* className = nullptr; + const char* methName = + emitComp->eeGetMethodName(reinterpret_cast(cookie), &className); + printf("%s code for %s:%s", commentPrefix, className, methName); + return; + } + + if ((flag == GTF_ICON_STATIC_HDL) || (flag == GTF_ICON_STATIC_BOX_PTR)) + { + const char* className = nullptr; + const char* fieldName = + emitComp->eeGetFieldName(reinterpret_cast(cookie), &className); + printf("%s %s for %s%s%s", commentPrefix, flag == GTF_ICON_STATIC_HDL ? "data" : "box", className, + className != nullptr ? ":" : "", fieldName); + return; + } + } + + if (handle == 0) + { + return; + } + + const char* str = nullptr; if (flag == GTF_ICON_STR_HDL) { const WCHAR* wstr = emitComp->eeGetCPString(handle); @@ -4103,8 +4126,6 @@ void emitter::emitDispCommentForHandle(size_t handle, GenTreeFlags flag) { str = emitComp->eeGetClassName(reinterpret_cast(handle)); } -#ifndef TARGET_XARCH - // These are less useful for xarch: else if (flag == GTF_ICON_CONST_PTR) { str = "const ptr"; @@ -4133,11 +4154,6 @@ void emitter::emitDispCommentForHandle(size_t handle, GenTreeFlags flag) { str = "token handle"; } - else - { - str = "unknown"; - } -#endif // TARGET_XARCH if (str != nullptr) { diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index fc90bd96d6909e..042b50e7e37c57 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -523,7 +523,7 @@ class emitter void emitRecomputeIGoffsets(); - void emitDispCommentForHandle(size_t handle, GenTreeFlags flags); + void emitDispCommentForHandle(size_t handle, size_t cookie, GenTreeFlags flags); /************************************************************************/ /* The following describes a single instruction */ @@ -554,7 +554,7 @@ class emitter #endif // TARGET_XARCH -#ifdef DEBUG // This information is used in DEBUG builds to display the method name for call instructions +#ifdef DEBUG // This information is used in DEBUG builds for additional diagnostics struct instrDesc; diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 864ba862edddd7..3940f89302911a 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -3740,7 +3740,8 @@ void emitter::emitIns_R_I(instruction ins, emitAttr attr, regNumber reg, ssize_t imm, - insOpts opt /* = INS_OPTS_NONE */ DEBUGARG(GenTreeFlags gtFlags)) + insOpts opt /* = INS_OPTS_NONE */ + DEBUGARG(size_t targetHandle /* = 0 */) DEBUGARG(GenTreeFlags gtFlags /* = GTF_EMPTY */)) { emitAttr size = EA_SIZE(attr); emitAttr elemsize = EA_UNKNOWN; @@ -3990,7 +3991,11 @@ void emitter::emitIns_R_I(instruction ins, id->idInsOpt(opt); id->idReg1(reg); - INDEBUG(id->idDebugOnlyInfo()->idFlags = gtFlags); + +#ifdef DEBUG + id->idDebugOnlyInfo()->idMemCookie = targetHandle; + id->idDebugOnlyInfo()->idFlags = gtFlags; +#endif dispIns(id); appendToCurIG(id); @@ -4927,8 +4932,13 @@ void emitter::emitIns_R_R( * Add an instruction referencing a register and two constants. */ -void emitter::emitIns_R_I_I( - instruction ins, emitAttr attr, regNumber reg, ssize_t imm1, ssize_t imm2, insOpts opt /* = INS_OPTS_NONE */) +void emitter::emitIns_R_I_I(instruction ins, + emitAttr attr, + regNumber reg, + ssize_t imm1, + ssize_t imm2, + insOpts opt /* = INS_OPTS_NONE */ + DEBUGARG(size_t targetHandle /* = 0 */) DEBUGARG(GenTreeFlags gtFlags /* = 0 */)) { emitAttr size = EA_SIZE(attr); insFormat fmt = IF_NONE; @@ -5015,6 +5025,11 @@ void emitter::emitIns_R_I_I( id->idReg1(reg); +#ifdef DEBUG + id->idDebugOnlyInfo()->idFlags = gtFlags; + id->idDebugOnlyInfo()->idMemCookie = targetHandle; +#endif + dispIns(id); appendToCurIG(id); } @@ -12487,7 +12502,7 @@ void emitter::emitDispIns( } else { - emitDispCommentForHandle(id->idDebugOnlyInfo()->idMemCookie, id->idDebugOnlyInfo()->idFlags); + emitDispCommentForHandle(id->idDebugOnlyInfo()->idMemCookie, 0, id->idDebugOnlyInfo()->idFlags); } break; @@ -12623,6 +12638,7 @@ void emitter::emitDispIns( case IF_DI_1A: // DI_1A X.......shiiiiii iiiiiinnnnn..... Rn imm(i12,sh) emitDispReg(id->idReg1(), size, true); emitDispImmOptsLSL12(emitGetInsSC(id), id->idInsOpt()); + emitDispCommentForHandle(0, id->idDebugOnlyInfo()->idMemCookie, id->idDebugOnlyInfo()->idFlags); break; case IF_DI_1B: // DI_1B X........hwiiiii iiiiiiiiiiiddddd Rd imm(i16,hw) @@ -12641,18 +12657,21 @@ void emitter::emitDispIns( emitDispImm(hwi.immHW * 16, false); } } + emitDispCommentForHandle(0, id->idDebugOnlyInfo()->idMemCookie, id->idDebugOnlyInfo()->idFlags); break; case IF_DI_1C: // DI_1C X........Nrrrrrr ssssssnnnnn..... Rn imm(N,r,s) emitDispReg(id->idReg1(), size, true); bmi.immNRS = (unsigned)emitGetInsSC(id); emitDispImm(emitDecodeBitMaskImm(bmi, size), false); + emitDispCommentForHandle(0, id->idDebugOnlyInfo()->idMemCookie, id->idDebugOnlyInfo()->idFlags); break; case IF_DI_1D: // DI_1D X........Nrrrrrr ssssss.....ddddd Rd imm(N,r,s) emitDispReg(encodingZRtoSP(id->idReg1()), size, true); bmi.immNRS = (unsigned)emitGetInsSC(id); emitDispImm(emitDecodeBitMaskImm(bmi, size), false); + emitDispCommentForHandle(0, id->idDebugOnlyInfo()->idMemCookie, id->idDebugOnlyInfo()->idFlags); break; case IF_DI_2A: // DI_2A X.......shiiiiii iiiiiinnnnnddddd Rd Rn imm(i12,sh) diff --git a/src/coreclr/jit/emitarm64.h b/src/coreclr/jit/emitarm64.h index 8970c15b3c090c..c43f85292a4dc0 100644 --- a/src/coreclr/jit/emitarm64.h +++ b/src/coreclr/jit/emitarm64.h @@ -726,7 +726,8 @@ void emitIns_R_I(instruction ins, emitAttr attr, regNumber reg, ssize_t imm, - insOpts opt = INS_OPTS_NONE DEBUGARG(GenTreeFlags gtFlags = GTF_EMPTY)); + insOpts opt = INS_OPTS_NONE DEBUGARG(size_t targetHandle = 0) + DEBUGARG(GenTreeFlags gtFlags = GTF_EMPTY)); void emitIns_R_F(instruction ins, emitAttr attr, regNumber reg, double immDbl, insOpts opt = INS_OPTS_NONE); @@ -740,8 +741,13 @@ void emitIns_R_R(instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, emitIns_R_R(ins, attr, reg1, reg2); } -void emitIns_R_I_I( - instruction ins, emitAttr attr, regNumber reg1, ssize_t imm1, ssize_t imm2, insOpts opt = INS_OPTS_NONE); +void emitIns_R_I_I(instruction ins, + emitAttr attr, + regNumber reg1, + ssize_t imm1, + ssize_t imm2, + insOpts opt = INS_OPTS_NONE DEBUGARG(size_t targetHandle = 0) + DEBUGARG(GenTreeFlags gtFlags = GTF_EMPTY)); void emitIns_R_R_I( instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, ssize_t imm, insOpts opt = INS_OPTS_NONE); diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index 707c8fc25f7c38..bd5b2d0defe6a7 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -3219,6 +3219,11 @@ void emitter::emitHandleMemOp(GenTreeIndir* indir, instrDesc* id, insFormat fmt, id->idAddr()->iiaFieldHnd = fldHnd; id->idInsFmt(emitMapFmtForIns(emitMapFmtAtoM(fmt), ins)); + +#ifdef DEBUG + id->idDebugOnlyInfo()->idFlags = GTF_ICON_STATIC_HDL; + id->idDebugOnlyInfo()->idMemCookie = reinterpret_cast(fldHnd); +#endif } else if ((memBase != nullptr) && memBase->IsCnsIntOrI() && memBase->isContained()) { @@ -3279,6 +3284,14 @@ void emitter::emitHandleMemOp(GenTreeIndir* indir, instrDesc* id, insFormat fmt, // disp must have already been set in the instrDesc constructor. assert(emitGetInsAmdAny(id) == indir->Offset()); // make sure "disp" is stored properly } + +#ifdef DEBUG + if ((memBase != nullptr) && memBase->IsIconHandle() && memBase->isContained()) + { + id->idDebugOnlyInfo()->idFlags = memBase->gtFlags; + id->idDebugOnlyInfo()->idMemCookie = memBase->AsIntCon()->gtTargetHandle; + } +#endif } // Takes care of storing all incoming register parameters @@ -4126,7 +4139,10 @@ void emitter::emitIns_R(instruction ins, emitAttr attr, regNumber reg) * Add an instruction referencing a register and a constant. */ -void emitter::emitIns_R_I(instruction ins, emitAttr attr, regNumber reg, ssize_t val DEBUGARG(GenTreeFlags gtFlags)) +void emitter::emitIns_R_I(instruction ins, + emitAttr attr, + regNumber reg, + ssize_t val DEBUGARG(size_t targetHandle) DEBUGARG(GenTreeFlags gtFlags)) { emitAttr size = EA_SIZE(attr); @@ -4259,7 +4275,11 @@ void emitter::emitIns_R_I(instruction ins, emitAttr attr, regNumber reg, ssize_t id->idInsFmt(fmt); id->idReg1(reg); id->idCodeSize(sz); - INDEBUG(id->idDebugOnlyInfo()->idFlags = gtFlags); + +#ifdef DEBUG + id->idDebugOnlyInfo()->idFlags = gtFlags; + id->idDebugOnlyInfo()->idMemCookie = targetHandle; +#endif dispIns(id); emitCurIGsize += sz; @@ -9118,7 +9138,7 @@ void emitter::emitDispIns( { // (val < 0) printf("-0x%IX", -val); } - emitDispCommentForHandle(srcVal, id->idDebugOnlyInfo()->idFlags); + emitDispCommentForHandle(srcVal, id->idDebugOnlyInfo()->idMemCookie, id->idDebugOnlyInfo()->idFlags); } break; @@ -9189,6 +9209,9 @@ void emitter::emitDispIns( } printf("%s, %s", emitRegName(id->idReg1(), attr), sstr); emitDispAddrMode(id); + + emitDispCommentForHandle(emitGetInsAmdAny(id), id->idDebugOnlyInfo()->idMemCookie, + id->idDebugOnlyInfo()->idFlags); break; case IF_RRW_ARD_CNS: diff --git a/src/coreclr/jit/emitxarch.h b/src/coreclr/jit/emitxarch.h index 754632bb1c0896..c744e40dbd41ea 100644 --- a/src/coreclr/jit/emitxarch.h +++ b/src/coreclr/jit/emitxarch.h @@ -330,7 +330,10 @@ void emitIns_C(instruction ins, emitAttr attr, CORINFO_FIELD_HANDLE fdlHnd, int void emitIns_A(instruction ins, emitAttr attr, GenTreeIndir* indir); -void emitIns_R_I(instruction ins, emitAttr attr, regNumber reg, ssize_t val DEBUGARG(GenTreeFlags gtFlags = GTF_EMPTY)); +void emitIns_R_I(instruction ins, + emitAttr attr, + regNumber reg, + ssize_t val DEBUGARG(size_t targetHandle = 0) DEBUGARG(GenTreeFlags gtFlags = GTF_EMPTY)); void emitIns_Mov(instruction ins, emitAttr attr, regNumber dstReg, regNumber srgReg, bool canSkip); diff --git a/src/coreclr/jit/flowgraph.cpp b/src/coreclr/jit/flowgraph.cpp index da1bcd79595aa9..52399aa6c16929 100644 --- a/src/coreclr/jit/flowgraph.cpp +++ b/src/coreclr/jit/flowgraph.cpp @@ -1528,7 +1528,7 @@ GenTree* Compiler::fgGetCritSectOfStaticMethod() critSect = info.compCompHnd->getMethodSync(info.compMethodHnd, (void**)&pCrit); noway_assert((!critSect) != (!pCrit)); - tree = gtNewIconEmbHndNode(critSect, pCrit, GTF_ICON_METHOD_HDL, info.compMethodHnd); + tree = gtNewIconEmbHndNode(critSect, pCrit, GTF_ICON_GLOBAL_PTR, info.compMethodHnd); } else { diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index f6a167a50e1390..70384056e0709a 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -6745,8 +6745,8 @@ GenTree* Compiler::gtNewIndOfIconHandleNode(var_types indType, size_t addr, GenT GenTree* Compiler::gtNewIconEmbHndNode(void* value, void* pValue, GenTreeFlags iconFlags, void* compileTimeHandle) { - GenTree* iconNode; - GenTree* handleNode; + GenTreeIntCon* iconNode; + GenTree* handleNode; if (value != nullptr) { @@ -6779,7 +6779,13 @@ GenTree* Compiler::gtNewIconEmbHndNode(void* value, void* pValue, GenTreeFlags i handleNode->gtFlags |= GTF_IND_INVARIANT; } - iconNode->AsIntCon()->gtCompileTimeHandle = (size_t)compileTimeHandle; + iconNode->gtCompileTimeHandle = (size_t)compileTimeHandle; +#ifdef DEBUG + if (iconFlags == GTF_ICON_FTN_ADDR) + { + iconNode->gtTargetHandle = (size_t)compileTimeHandle; + } +#endif return handleNode; } diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index b9ba82532a5541..c0de433f8328f5 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -3056,8 +3056,7 @@ struct GenTreeIntCon : public GenTreeIntConCommon FieldSeqNode* gtFieldSeq; #ifdef DEBUG - // If the value represents target address, holds the method handle to that target which is used - // to fetch target method name and display in the disassembled code. + // If the value represents target address (for a field or call), holds the handle of the field (or call). size_t gtTargetHandle = 0; #endif diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 316ea1670e4edc..5ddc2eed4f144f 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -1938,8 +1938,8 @@ GenTree* Compiler::impTokenToHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken, } // Generate the full lookup tree. May be null if we're abandoning an inline attempt. - GenTree* result = impLookupToTree(pResolvedToken, &embedInfo.lookup, gtTokenToIconFlags(pResolvedToken->token), - embedInfo.compileTimeHandle); + GenTreeFlags handleType = importParent ? GTF_ICON_CLASS_HDL : gtTokenToIconFlags(pResolvedToken->token); + GenTree* result = impLookupToTree(pResolvedToken, &embedInfo.lookup, handleType, embedInfo.compileTimeHandle); // If we have a result and it requires runtime lookup, wrap it in a runtime lookup node. if ((result != nullptr) && embedInfo.lookup.lookupKind.needsRuntimeLookup) @@ -8853,9 +8853,7 @@ GenTree* Compiler::impImportStaticFieldAccess(CORINFO_RESOLVED_TOKEN* pResolvedT // Create the address node. GenTreeFlags handleKind = isBoxedStatic ? GTF_ICON_STATIC_BOX_PTR : GTF_ICON_STATIC_HDL; op1 = gtNewIconHandleNode((size_t)fldAddr, handleKind, innerFldSeq); -#ifdef DEBUG - op1->AsIntCon()->gtTargetHandle = op1->AsIntCon()->gtIconVal; -#endif + INDEBUG(op1->AsIntCon()->gtTargetHandle = reinterpret_cast(pResolvedToken->hField)); if (pFieldInfo->fieldFlags & CORINFO_FLG_FIELD_INITCLASS) { diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index ec5d602d5eb646..d41ad4babb6790 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -2107,9 +2107,7 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call size_t addrValue = (size_t)call->gtEntryPoint.addr; GenTree* indirectCellAddress = comp->gtNewIconHandleNode(addrValue, GTF_ICON_FTN_ADDR); -#ifdef DEBUG - indirectCellAddress->AsIntCon()->gtTargetHandle = (size_t)call->gtCallMethHnd; -#endif + INDEBUG(indirectCellAddress->AsIntCon()->gtTargetHandle = (size_t)call->gtCallMethHnd); indirectCellAddress->SetRegNum(REG_R2R_INDIRECT_PARAM); #ifdef TARGET_ARM // Issue #xxxx : Don't attempt to CSE this constant on ARM32 @@ -5494,7 +5492,8 @@ GenTree* Compiler::fgMorphField(GenTree* tree, MorphAddrContext* mac) { handleKind = GTF_ICON_STATIC_HDL; } - GenTree* addr = gtNewIconHandleNode((size_t)fldAddr, handleKind, fieldSeq); + GenTreeIntCon* addr = gtNewIconHandleNode((size_t)fldAddr, handleKind, fieldSeq); + INDEBUG(addr->gtTargetHandle = reinterpret_cast(symHnd)); // Translate GTF_FLD_INITCLASS to GTF_ICON_INITCLASS, if we need to. if (((tree->gtFlags & GTF_FLD_INITCLASS) != 0) && !isStaticReadOnlyInited) @@ -7933,9 +7932,7 @@ GenTree* Compiler::fgGetStubAddrArg(GenTreeCall* call) assert(call->gtCallMoreFlags & GTF_CALL_M_VIRTSTUB_REL_INDIRECT); ssize_t addr = ssize_t(call->gtStubCallStubAddr); stubAddrArg = gtNewIconHandleNode(addr, GTF_ICON_FTN_ADDR); -#ifdef DEBUG - stubAddrArg->AsIntCon()->gtTargetHandle = (size_t)call->gtCallMethHnd; -#endif + INDEBUG(stubAddrArg->AsIntCon()->gtTargetHandle = (size_t)call->gtCallMethHnd); } assert(stubAddrArg != nullptr); stubAddrArg->SetRegNum(virtualStubParamInfo->GetReg()); @@ -8822,7 +8819,8 @@ GenTree* Compiler::fgMorphLeaf(GenTree* tree) // target of a Delegate or a raw function pointer. bool isUnsafeFunctionPointer = !fptrValTree->gtFptrDelegateTarget; - CORINFO_CONST_LOOKUP addrInfo; + CORINFO_CONST_LOOKUP addrInfo; + CORINFO_METHOD_HANDLE funcHandle = fptrValTree->gtFptrMethod; #ifdef FEATURE_READYTORUN if (fptrValTree->gtEntryPoint.addr != nullptr) @@ -8832,7 +8830,7 @@ GenTree* Compiler::fgMorphLeaf(GenTree* tree) else #endif { - info.compCompHnd->getFunctionFixedEntryPoint(fptrValTree->gtFptrMethod, isUnsafeFunctionPointer, &addrInfo); + info.compCompHnd->getFunctionFixedEntryPoint(funcHandle, isUnsafeFunctionPointer, &addrInfo); } GenTree* indNode = nullptr; @@ -8851,6 +8849,7 @@ GenTree* Compiler::fgMorphLeaf(GenTree* tree) case IAT_PVALUE: indNode = gtNewIndOfIconHandleNode(TYP_I_IMPL, (size_t)addrInfo.handle, GTF_ICON_FTN_ADDR, true); + INDEBUG(indNode->gtGetOp1()->AsIntCon()->gtTargetHandle = reinterpret_cast(funcHandle)); break; case IAT_VALUE: @@ -8859,6 +8858,7 @@ GenTree* Compiler::fgMorphLeaf(GenTree* tree) tree->SetOper(GT_CNS_INT); tree->AsIntConCommon()->SetIconValue(ssize_t(addrInfo.handle)); tree->gtFlags |= GTF_ICON_FTN_ADDR; + INDEBUG(tree->AsIntCon()->gtTargetHandle = reinterpret_cast(funcHandle)); break; default: From 4d44308ea5540c363ef6022b29e9d7ed64b15f8c Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Fri, 10 Jun 2022 04:27:32 -0700 Subject: [PATCH 032/337] JIT: Do not propagate some constants (#70378) Co-authored-by: Tanner Gooding --- src/coreclr/jit/assertionprop.cpp | 58 +++++++++++++++++++++++++++++++ src/coreclr/jit/compiler.h | 1 + 2 files changed, 59 insertions(+) diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index ddee8ba3e6e1b4..5ea3ba568406a3 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -3177,6 +3177,15 @@ GenTree* Compiler::optVNConstantPropOnTree(BasicBlock* block, GenTree* tree) if (conValTree != nullptr) { + if (tree->OperIs(GT_LCL_VAR)) + { + if (!optIsProfitableToSubstitute(tree->AsLclVar(), block, conValTree)) + { + // Not profitable to substitute + return nullptr; + } + } + // Were able to optimize. conValTree->gtVNPair = vnPair; GenTree* sideEffList = optExtractSideEffListFromConst(tree); @@ -3199,6 +3208,55 @@ GenTree* Compiler::optVNConstantPropOnTree(BasicBlock* block, GenTree* tree) } } +//------------------------------------------------------------------------------ +// optIsProfitableToSubstitute: Checks if value worth substituting to lcl location +// +// Arguments: +// lcl - lcl to replace with value if profitable +// lclBlock - Basic block lcl located in +// value - value we plan to substitute to lcl +// +// Returns: +// False if it's likely not profitable to do substitution, True otherwise +// +bool Compiler::optIsProfitableToSubstitute(GenTreeLclVarCommon* lcl, BasicBlock* lclBlock, GenTree* value) +{ + // A simple heuristic: If the constant is defined outside of a loop (not far from its head) + // and is used inside it - don't propagate. + + // TODO: Extend on more kinds of trees + if (!value->OperIs(GT_CNS_VEC, GT_CNS_DBL)) + { + return true; + } + + gtPrepareCost(value); + + if ((value->GetCostEx() > 1) && (value->GetCostSz() > 1)) + { + // Try to find the block this constant was originally defined in + if (lcl->HasSsaName()) + { + BasicBlock* defBlock = lvaGetDesc(lcl)->GetPerSsaData(lcl->GetSsaNum())->GetBlock(); + if (defBlock != nullptr) + { + // Avoid propagating if the weighted use cost is significantly greater than the def cost. + // NOTE: this currently does not take "a float living across a call" case into account + // where we might end up with spill/restore on ABIs without callee-saved registers + const weight_t defBlockWeight = defBlock->getBBWeight(this); + const weight_t lclblockWeight = lclBlock->getBBWeight(this); + + if ((defBlockWeight > 0) && ((lclblockWeight / defBlockWeight) >= BB_LOOP_WEIGHT_SCALE)) + { + JITDUMP("Constant propagation inside loop " FMT_BB " is not profitable\n", lclBlock->bbNum); + return false; + } + } + } + } + return true; +} + //------------------------------------------------------------------------------ // optConstantAssertionProp: Possibly substitute a constant for a local use // diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 363ec0b9a2f9ac..c838b9e9c7268f 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -7264,6 +7264,7 @@ class Compiler GenTree* optConstantAssertionProp(AssertionDsc* curAssertion, GenTreeLclVarCommon* tree, Statement* stmt DEBUGARG(AssertionIndex index)); + bool optIsProfitableToSubstitute(GenTreeLclVarCommon* lcl, BasicBlock* lclBlock, GenTree* value); bool optZeroObjAssertionProp(GenTree* tree, ASSERT_VALARG_TP assertions); // Assertion propagation functions. From 9cda207dbdb3056aa994c4ff317dc28bb2c4f004 Mon Sep 17 00:00:00 2001 From: Jose Perez Rodriguez Date: Fri, 10 Jun 2022 06:32:17 -0700 Subject: [PATCH 033/337] Move analyzer and fixer tests into FunctionalTests project (#70406) * Move analyzer and fixer tests into FunctionalTests project * Don't use the live ref pack references infrastructure --- .../src/Resources/Strings.resx | 3 --- .../CSharpCodeFixVerifier`2.cs | 4 ++-- ...ystem.Text.RegularExpressions.Tests.csproj | 7 ++++++- .../UpgradeToRegexGeneratorAnalyzerTests.cs | 20 ++++++++++--------- .../tests/UnitTests/Stubs.cs | 15 -------------- ....Text.RegularExpressions.Unit.Tests.csproj | 12 ----------- 6 files changed, 19 insertions(+), 42 deletions(-) rename src/libraries/System.Text.RegularExpressions/tests/{UnitTests => FunctionalTests}/CSharpCodeFixVerifier`2.cs (96%) rename src/libraries/System.Text.RegularExpressions/tests/{UnitTests => FunctionalTests}/UpgradeToRegexGeneratorAnalyzerTests.cs (96%) diff --git a/src/libraries/System.Text.RegularExpressions/src/Resources/Strings.resx b/src/libraries/System.Text.RegularExpressions/src/Resources/Strings.resx index 57728c49e7b145..cf84d5a5a896d5 100644 --- a/src/libraries/System.Text.RegularExpressions/src/Resources/Strings.resx +++ b/src/libraries/System.Text.RegularExpressions/src/Resources/Strings.resx @@ -285,7 +285,4 @@ Searching an input span using a pre-compiled Regex assembly is not supported. Please use the string overloads or use a newer Regex implementation. - - Use the RegEx source generator. - diff --git a/src/libraries/System.Text.RegularExpressions/tests/UnitTests/CSharpCodeFixVerifier`2.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/CSharpCodeFixVerifier`2.cs similarity index 96% rename from src/libraries/System.Text.RegularExpressions/tests/UnitTests/CSharpCodeFixVerifier`2.cs rename to src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/CSharpCodeFixVerifier`2.cs index 648eaff1c202b3..471c02d564d311 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/UnitTests/CSharpCodeFixVerifier`2.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/CSharpCodeFixVerifier`2.cs @@ -14,7 +14,7 @@ using Microsoft.CodeAnalysis.Testing; using Microsoft.CodeAnalysis.Testing.Verifiers; -namespace System.Text.RegularExpressions.Unit.Tests +namespace System.Text.RegularExpressions.Tests { public static class CSharpCodeFixVerifier where TAnalyzer : DiagnosticAnalyzer, new() @@ -85,7 +85,7 @@ public Test(ReferenceAssemblies? references, bool usePreviewLanguageVersion, int // Clear out the default reference assemblies. We explicitly add references from the live ref pack, // so we don't want the Roslyn test infrastructure to resolve/add any default reference assemblies ReferenceAssemblies = new ReferenceAssemblies(string.Empty); - TestState.AdditionalReferences.AddRange(SourceGenerators.Tests.LiveReferencePack.GetMetadataReferences()); + TestState.AdditionalReferences.AddRange(RegexGeneratorHelper.References); } NumberOfFixAllIterations = numberOfIterations; diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/System.Text.RegularExpressions.Tests.csproj b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/System.Text.RegularExpressions.Tests.csproj index ceed4984ce0dfb..55e131ad7a3217 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/System.Text.RegularExpressions.Tests.csproj +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/System.Text.RegularExpressions.Tests.csproj @@ -1,4 +1,4 @@ - + true @@ -43,6 +43,8 @@ + + @@ -61,6 +63,9 @@ + + + diff --git a/src/libraries/System.Text.RegularExpressions/tests/UnitTests/UpgradeToRegexGeneratorAnalyzerTests.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/UpgradeToRegexGeneratorAnalyzerTests.cs similarity index 96% rename from src/libraries/System.Text.RegularExpressions/tests/UnitTests/UpgradeToRegexGeneratorAnalyzerTests.cs rename to src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/UpgradeToRegexGeneratorAnalyzerTests.cs index 5ffe667edd962e..6819ab96939d78 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/UnitTests/UpgradeToRegexGeneratorAnalyzerTests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/UpgradeToRegexGeneratorAnalyzerTests.cs @@ -10,15 +10,17 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.Testing; using Xunit; -using VerifyCS = System.Text.RegularExpressions.Unit.Tests.CSharpCodeFixVerifier< +using VerifyCS = System.Text.RegularExpressions.Tests.CSharpCodeFixVerifier< System.Text.RegularExpressions.Generator.UpgradeToRegexGeneratorAnalyzer, System.Text.RegularExpressions.Generator.UpgradeToRegexGeneratorCodeFixer>; -namespace System.Text.RegularExpressions.Unit.Tests +namespace System.Text.RegularExpressions.Tests { [ActiveIssue("https://github.com/dotnet/runtime/issues/69823", TestRuntimes.Mono)] public class UpgradeToRegexGeneratorAnalyzerTests { + private const string UseRegexSourceGeneratorDiagnosticId = @"SYSLIB1046"; + [Fact] public async Task NoDiagnosticsForEmpty() => await VerifyCS.VerifyAnalyzerAsync(source: string.Empty); @@ -237,7 +239,7 @@ public static void Main(string[] args) [MemberData(nameof(ConstantPatternTestData))] public async Task DiagnosticEmittedForConstantPattern(string test, string fixedSource) { - DiagnosticResult expectedDiagnostic = VerifyCS.Diagnostic(DiagnosticDescriptors.UseRegexSourceGeneration.Id).WithLocation(0); + DiagnosticResult expectedDiagnostic = VerifyCS.Diagnostic(UseRegexSourceGeneratorDiagnosticId).WithLocation(0); await VerifyCS.VerifyCodeFixAsync(test, expectedDiagnostic, fixedSource); } @@ -400,7 +402,7 @@ public static void Main(string[] args) [MemberData(nameof(ConstantOptionsTestData))] public async Task DiagnosticEmittedForConstantOptions(string test, string fixedSource) { - DiagnosticResult expected = VerifyCS.Diagnostic(DiagnosticDescriptors.UseRegexSourceGeneration.Id).WithLocation(0); + DiagnosticResult expected = VerifyCS.Diagnostic(UseRegexSourceGeneratorDiagnosticId).WithLocation(0); await VerifyCS.VerifyCodeFixAsync(test, expected, fixedSource); } @@ -503,7 +505,7 @@ public static void Main(string[] args) [RegexGenerator(""a|b"", RegexOptions.None)] private static partial Regex MyRegex(); }"; - DiagnosticResult expectedDiagnostic = VerifyCS.Diagnostic(DiagnosticDescriptors.UseRegexSourceGeneration.Id).WithLocation(0); + DiagnosticResult expectedDiagnostic = VerifyCS.Diagnostic(UseRegexSourceGeneratorDiagnosticId).WithLocation(0); const string testTemplateWithoutOptions = @"using System.Text.RegularExpressions; @@ -600,7 +602,7 @@ public async Task DiagnosticAndCodeFixForAllStaticMethods(string test, Diagnosti [Fact] public async Task CodeFixSupportsNesting() { - DiagnosticResult expectedDiagnostic = VerifyCS.Diagnostic(DiagnosticDescriptors.UseRegexSourceGeneration.Id).WithLocation(0); + DiagnosticResult expectedDiagnostic = VerifyCS.Diagnostic(UseRegexSourceGeneratorDiagnosticId).WithLocation(0); string test = @"using System.Text.RegularExpressions; public class A @@ -680,8 +682,8 @@ public static void Main() "; DiagnosticResult[] expectedDiagnostics = new[] { - VerifyCS.Diagnostic(DiagnosticDescriptors.UseRegexSourceGeneration.Id).WithLocation(0), - VerifyCS.Diagnostic(DiagnosticDescriptors.UseRegexSourceGeneration.Id).WithLocation(1) + VerifyCS.Diagnostic(UseRegexSourceGeneratorDiagnosticId).WithLocation(0), + VerifyCS.Diagnostic(UseRegexSourceGeneratorDiagnosticId).WithLocation(1) }; string fixedSource = @"using System.Text.RegularExpressions; @@ -716,7 +718,7 @@ static void Main(string[] args) Regex r = {|#0:new Regex(options: RegexOptions.None, pattern: ""a|b"")|}; } }"; - DiagnosticResult expectedDiagnostic = VerifyCS.Diagnostic(DiagnosticDescriptors.UseRegexSourceGeneration.Id).WithLocation(0); + DiagnosticResult expectedDiagnostic = VerifyCS.Diagnostic(UseRegexSourceGeneratorDiagnosticId).WithLocation(0); string fixedSource = @"using System.Text.RegularExpressions; diff --git a/src/libraries/System.Text.RegularExpressions/tests/UnitTests/Stubs.cs b/src/libraries/System.Text.RegularExpressions/tests/UnitTests/Stubs.cs index 9776dc3e38cd53..70594d4e08bb46 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/UnitTests/Stubs.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/UnitTests/Stubs.cs @@ -8,7 +8,6 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; -using Microsoft.CodeAnalysis; namespace System.Text.RegularExpressions { @@ -23,17 +22,3 @@ public RegexReplacement(string rep, RegexNode concat, Hashtable caps) { } public const int WholeString = -4; } } - -namespace System.Text.RegularExpressions.Generator -{ - internal static class DiagnosticDescriptors - { - public static DiagnosticDescriptor UseRegexSourceGeneration { get; } = new DiagnosticDescriptor( - id: "SYSLIB1046", - title: "Use the Regex source generator.", - messageFormat: "The inputs to your Regex are known at compile-time so you could be using the source generator to boost performance.", - category: "RegexGenerator", - DiagnosticSeverity.Info, - isEnabledByDefault: true); - } -} diff --git a/src/libraries/System.Text.RegularExpressions/tests/UnitTests/System.Text.RegularExpressions.Unit.Tests.csproj b/src/libraries/System.Text.RegularExpressions/tests/UnitTests/System.Text.RegularExpressions.Unit.Tests.csproj index 5a6bf287e165cf..eb35b0bcd294a2 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/UnitTests/System.Text.RegularExpressions.Unit.Tests.csproj +++ b/src/libraries/System.Text.RegularExpressions/tests/UnitTests/System.Text.RegularExpressions.Unit.Tests.csproj @@ -9,13 +9,9 @@ true true $(DefineConstants);DEBUG - true - - - @@ -48,9 +44,6 @@ - - - @@ -73,10 +66,5 @@ - - - - - From d84115f52fda79b1b72f5b2444ba0ae2c6569d4d Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Fri, 10 Jun 2022 09:33:19 -0400 Subject: [PATCH 034/337] Enable IDE0029 (Use coalesce expression) (#70506) * Enable IDE0029 (Use coalesce expression) * Address PR feedback and a few missed cases --- eng/CodeAnalysis.src.globalconfig | 2 +- .../DeveloperExperience.cs | 2 +- .../src/System/Type.Internal.cs | 6 +-- .../RuntimePlainConstructorInfo.cs | 2 +- .../TypeSystem/Common/InstantiatedType.cs | 2 +- .../RuntimeBinder/Semantics/Binding/Better.cs | 2 +- .../src/Sgen.cs | 2 +- .../Specialized/NameObjectCollectionBase.cs | 2 +- .../ConfigurationElementCollection.cs | 2 +- .../System/Data/Common/DBCommandBuilder.cs | 3 +- .../System/Data/Common/DbConnectionOptions.cs | 2 +- .../src/System/Data/DataColumn.cs | 4 +- .../src/System/Data/DataRelation.cs | 2 +- .../src/System/Data/DataTable.cs | 4 +- .../src/System/Data/DataView.cs | 2 +- .../src/System/Data/Filter/DataExpression.cs | 2 +- .../src/System/Data/LinqDataView.cs | 2 +- .../Data/ProviderBase/DataReaderContainer.cs | 2 +- .../src/System/Data/SQLTypes/SQLString.cs | 2 +- .../src/System/Data/XMLSchema.cs | 8 ++-- .../src/System/Data/XmlDataLoader.cs | 2 +- .../src/System/Data/xmlsaver.cs | 2 +- .../System/Data/Common/DBConnectionString.cs | 2 +- .../System/Data/Common/DbConnectionOptions.cs | 5 +-- .../src/System/Data/Odbc/OdbcCommand.cs | 3 +- .../src/System/Data/Odbc/OdbcError.cs | 4 +- .../src/System/Data/Odbc/OdbcParameter.cs | 3 +- .../System/Data/Odbc/OdbcParameterHelper.cs | 3 +- .../System.Data.OleDb/src/ColumnBinding.cs | 2 +- .../src/DbConnectionOptions.cs | 7 ++-- .../src/DbParameterHelper.cs | 3 +- .../System.Data.OleDb/src/OleDbCommand.cs | 3 +- .../System.Data.OleDb/src/OleDbConnection.cs | 3 +- .../System.Data.OleDb/src/OleDbDataReader.cs | 4 +- .../System.Data.OleDb/src/OleDbError.cs | 9 ++-- .../System.Data.OleDb/src/OleDbException.cs | 3 +- .../System.Data.OleDb/src/OleDbParameter.cs | 3 +- .../System.Data.OleDb/src/RowBinding.cs | 2 +- .../src/System/Diagnostics/Switch.cs | 6 +-- .../src/System/Diagnostics/TraceListener.cs | 4 +- .../AccountManagement/AD/ADDNLinkedAttrSet.cs | 4 +- .../AccountManagement/AD/ADStoreCtx.cs | 2 +- .../AD/ADStoreCtx_LoadStore.cs | 4 +- .../AccountManagement/AD/ADStoreCtx_Query.cs | 2 +- .../AccountManagement/AD/SidList.cs | 2 +- .../AccountManagement/Utils.cs | 4 +- .../ActiveDirectory/ConfigSet.cs | 4 +- .../ActiveDirectory/DomainController.cs | 2 +- .../ForestTrustRelationshipInformation.cs | 2 +- .../TrustRelationshipInformation.cs | 2 +- .../ActiveDirectory/Utils.cs | 2 +- .../src/System/IO/FileSystemWatcher.cs | 2 +- .../Parallel/QueryOperators/QuerySettings.cs | 2 +- .../src/System/Management/ManagementClass.cs | 2 +- .../System/Management/ManagementEventArgs.cs | 2 +- .../src/System/Management/ManagementObject.cs | 18 ++++---- .../System/Management/ManagementOptions.cs | 4 +- .../src/System/Management/ManagementQuery.cs | 36 ++++++++-------- .../src/System/Management/Method.cs | 2 +- .../src/System/Management/Property.cs | 2 +- .../src/System/Management/Qualifier.cs | 2 +- .../WebSockets/HttpWebSocket.Managed.cs | 2 +- .../Net/Windows/HttpListener.Windows.cs | 2 +- .../Windows/HttpListenerContext.Windows.cs | 2 +- .../src/System/Net/Mail/MailBnfHelper.cs | 4 +- .../src/System/Net/Mail/MailMessage.cs | 4 +- .../Net/Mail/SmtpFailedRecipientsException.cs | 2 +- .../src/System/Net/Cookie.cs | 8 ++-- .../src/System/Net/HttpWebResponse.cs | 2 +- .../Runtime/Serialization/SchemaExporter.cs | 2 +- .../XmlObjectSerializerWriteContext.cs | 4 +- .../src/System/Xml/Linq/XNodeReader.cs | 2 +- .../src/System/Xml/XPath/XNodeNavigator.cs | 2 +- .../src/System/Xml/Core/XmlParserContext.cs | 24 +++++------ .../src/System/Xml/Core/XmlTextReaderImpl.cs | 6 +-- .../System/Xml/Core/XmlTextReaderImplAsync.cs | 2 +- .../System/Xml/Core/XmlWellFormedWriter.cs | 2 +- .../System/Xml/Core/XsdValidatingReader.cs | 4 +- .../Xml/Core/XsdValidatingReaderAsync.cs | 2 +- .../src/System/Xml/Dom/XmlDeclaration.cs | 2 +- .../src/System/Xml/Dom/XmlElementList.cs | 2 +- .../src/System/Xml/Dom/XmlNode.cs | 3 +- .../src/System/Xml/Dom/XmlNodeReader.cs | 26 ++++++++---- .../src/System/Xml/Schema/Preprocessor.cs | 8 ++-- .../src/System/Xml/Schema/SchemaAttDef.cs | 2 +- .../Schema/SchemaCollectionpreProcessor.cs | 6 +-- .../src/System/Xml/Schema/SchemaDeclBase.cs | 4 +- .../src/System/Xml/Schema/SchemaEntity.cs | 4 +- .../System/Xml/Schema/XmlSchemaAttribute.cs | 4 +- .../Xml/Schema/XmlSchemaAttributeGroupref.cs | 2 +- .../System/Xml/Schema/XmlSchemaCollection.cs | 8 ++-- .../XmlSchemaComplexContentExtension.cs | 2 +- .../XmlSchemaComplexContentRestriction.cs | 2 +- .../src/System/Xml/Schema/XmlSchemaElement.cs | 6 +-- .../System/Xml/Schema/XmlSchemaException.cs | 2 +- .../System/Xml/Schema/XmlSchemaGroupRef.cs | 2 +- .../Xml/Schema/XmlSchemaIdEntityConstraint.cs | 2 +- .../src/System/Xml/Schema/XmlSchemaSet.cs | 4 +- .../Schema/XmlSchemaSimpleContentExtension.cs | 2 +- .../XmlSchemaSimpleContentRestriction.cs | 2 +- .../Xml/Schema/XmlSchemaSimpleTypeList.cs | 2 +- .../Schema/XmlSchemaSimpleTypeRestriction.cs | 2 +- .../System/Xml/Schema/XmlSchemaValidator.cs | 2 +- .../src/System/Xml/Schema/XsdValidator.cs | 2 +- .../src/System/Xml/Serialization/Mappings.cs | 12 +++--- .../Serialization/SoapAttributeAttribute.cs | 4 +- .../Xml/Serialization/SoapElementAttribute.cs | 4 +- .../Xml/Serialization/SoapEnumAttribute.cs | 2 +- .../Serialization/SoapReflectionImporter.cs | 4 +- .../Xml/Serialization/SoapSchemamember.cs | 2 +- .../Xml/Serialization/SoapTypeAttribute.cs | 2 +- .../Serialization/XmlAnyElementAttribute.cs | 2 +- .../Xml/Serialization/XmlArrayAttribute.cs | 2 +- .../Serialization/XmlArrayItemAttribute.cs | 4 +- .../Serialization/XmlAttributeAttribute.cs | 4 +- .../XmlChoiceIdentifierAttribute.cs | 2 +- .../Xml/Serialization/XmlElementAttribute.cs | 4 +- .../System/Xml/Serialization/XmlMapping.cs | 2 +- .../Serialization/XmlReflectionImporter.cs | 42 +++++++++---------- .../Xml/Serialization/XmlReflectionMember.cs | 2 +- .../Xml/Serialization/XmlRootAttribute.cs | 6 +-- .../Xml/Serialization/XmlSchemaExporter.cs | 6 +-- .../Xml/Serialization/XmlSchemaImporter.cs | 2 +- .../Serialization/XmlSerializationReader.cs | 2 +- .../XmlSerializationReaderILGen.cs | 2 +- .../Serialization/XmlSerializationWriter.cs | 2 +- .../Xml/Serialization/XmlTextAttribute.cs | 2 +- .../Xml/Serialization/XmlTypeAttribute.cs | 2 +- .../Xml/Serialization/Xmlcustomformatter.cs | 2 +- .../src/System/Xml/Serialization/_Events.cs | 4 +- .../src/System/Xml/XPath/XPathException.cs | 2 +- .../src/System/Xml/XmlException.cs | 2 +- .../src/System/Xml/XmlNamespacemanager.cs | 2 +- .../src/System/Xml/Xsl/QIL/QilCloneVisitor.cs | 2 +- .../Xml/Xsl/Runtime/WhitespaceRuleReader.cs | 2 +- .../System/Xml/Xsl/XmlQualifiedNameTest.cs | 2 +- .../System/Xml/Xsl/XsltOld/AttributeAction.cs | 2 +- .../System/Xml/Xsl/XsltOld/RecordBuilder.cs | 2 +- .../src/System/Xml/Xsl/XsltOld/SortAction.cs | 3 +- .../VirtualPropertyBase.PropertySetterBase.cs | 4 +- .../Formatters/Binary/BinaryObjectReader.cs | 12 ++---- .../Formatters/Binary/BinaryObjectWriter.cs | 5 +-- .../src/System/Security/AccessControl/ACL.cs | 2 +- .../Cryptography/Xml/SignedXmlDebugLog.cs | 2 +- .../Cryptography/CapiHelper.Windows.cs | 4 +- .../CertificatePal.Windows.cs | 2 +- .../Permissions/PrincipalPermission.cs | 4 +- .../src/Internal/ObjectToken/ObjectToken.cs | 2 +- .../System.Speech/src/Internal/RBList.cs | 4 +- .../src/Internal/SrgsCompiler/BackEnd.cs | 2 +- .../Internal/SrgsParser/SrgsDocumentParser.cs | 2 +- .../Synthesis/AudioFormatConverter.cs | 5 ++- .../src/Internal/Synthesis/SSmlParser.cs | 2 +- .../src/Internal/Synthesis/VoiceSynthesis.cs | 4 +- .../src/Synthesis/PromptBuilder.cs | 2 +- .../System.Speech/src/Synthesis/VoiceInfo.cs | 2 +- 156 files changed, 296 insertions(+), 316 deletions(-) diff --git a/eng/CodeAnalysis.src.globalconfig b/eng/CodeAnalysis.src.globalconfig index 18822fa4337714..51da5a2e70b974 100644 --- a/eng/CodeAnalysis.src.globalconfig +++ b/eng/CodeAnalysis.src.globalconfig @@ -1383,7 +1383,7 @@ dotnet_diagnostic.IDE0027.severity = silent dotnet_diagnostic.IDE0028.severity = suggestion # IDE0029: Use coalesce expression -dotnet_diagnostic.IDE0029.severity = suggestion +dotnet_diagnostic.IDE0029.severity = warning # IDE0030: Use coalesce expression dotnet_diagnostic.IDE0030.severity = suggestion diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/DeveloperExperience/DeveloperExperience.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/DeveloperExperience/DeveloperExperience.cs index 0499890c36ac62..a6d77cbedf7cdf 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/DeveloperExperience/DeveloperExperience.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/DeveloperExperience/DeveloperExperience.cs @@ -100,7 +100,7 @@ public virtual void TryGetMethodBase(IntPtr methodStartAddress, out MethodBase m public virtual bool OnContractFailure(string? stackTrace, ContractFailureKind contractFailureKind, string? displayMessage, string userMessage, string conditionText, Exception innerException) { - Debug.WriteLine("Assertion failed: " + (displayMessage == null ? "" : displayMessage)); + Debug.WriteLine("Assertion failed: " + (displayMessage ?? "")); if (Debugger.IsAttached) Debugger.Break(); return false; diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Type.Internal.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Type.Internal.cs index 53867b10b0f3ae..0d6ec98de9fecc 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Type.Internal.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Type.Internal.cs @@ -39,8 +39,7 @@ internal string NameOrDefault { get { - string name = InternalNameIfAvailable; - return name != null ? name : DefaultTypeNameWhenMissingMetadata; + return InternalNameIfAvailable ?? DefaultTypeNameWhenMissingMetadata; } } @@ -87,8 +86,7 @@ public string FormatTypeNameForReflection() rootElementType = rootElementType.GetElementType()!; if (rootElementType.IsNested) { - string name = InternalNameIfAvailable; - return name == null ? DefaultTypeNameWhenMissingMetadata : name; + return InternalNameIfAvailable ?? DefaultTypeNameWhenMissingMetadata; } // Legacy: why removing "System"? Is it just because C# has keywords for these types? diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimePlainConstructorInfo.cs b/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimePlainConstructorInfo.cs index 030759f35f5a2f..bd911ac844f621 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimePlainConstructorInfo.cs +++ b/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimePlainConstructorInfo.cs @@ -88,7 +88,7 @@ public sealed override object Invoke(BindingFlags invokeAttr, Binder binder, obj object newObject = ReflectionCoreExecution.ExecutionEnvironment.NewObject(this.DeclaringType.TypeHandle); object ctorAllocatedObject = this.MethodInvoker.Invoke(newObject, parameters, binder, invokeAttr, culture); System.Diagnostics.DebugAnnotations.PreviousCallContainsDebuggerStepInCode(); - return newObject != null ? newObject : ctorAllocatedObject; + return newObject ?? ctorAllocatedObject; } public sealed override MethodBase MetadataDefinitionMethod diff --git a/src/coreclr/tools/Common/TypeSystem/Common/InstantiatedType.cs b/src/coreclr/tools/Common/TypeSystem/Common/InstantiatedType.cs index f1164b677e20af..bed4e2388e92ae 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/InstantiatedType.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/InstantiatedType.cs @@ -273,7 +273,7 @@ public static T[] InstantiateTypeArray(T[] uninstantiatedTypes, Instantiation } } - return clone != null ? clone : uninstantiatedTypes; + return clone ?? uninstantiatedTypes; } // Strips instantiation. E.g C -> C diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Binding/Better.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Binding/Better.cs index c064a0f4170d82..9d85eb383732e4 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Binding/Better.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Binding/Better.cs @@ -216,7 +216,7 @@ private static TypeArray RearrangeNamedArguments(TypeArray pta, MethPropWithInst return pta; } - CType type = pTypeThrough != null ? pTypeThrough : mpwi.GetType(); + CType type = pTypeThrough ?? mpwi.GetType(); CType[] typeList = new CType[pta.Count]; MethodOrPropertySymbol methProp = GroupToArgsBinder.FindMostDerivedMethod(mpwi.MethProp(), type); diff --git a/src/libraries/Microsoft.XmlSerializer.Generator/src/Sgen.cs b/src/libraries/Microsoft.XmlSerializer.Generator/src/Sgen.cs index 4f4865753a1b4d..dc33ea08edceb5 100644 --- a/src/libraries/Microsoft.XmlSerializer.Generator/src/Sgen.cs +++ b/src/libraries/Microsoft.XmlSerializer.Generator/src/Sgen.cs @@ -319,7 +319,7 @@ private static void GenerateFile(List typeNames, string defaultNamespace var allMappings = mappings.ToArray(); bool gac = assembly.GlobalAssemblyCache; - outputDirectory = outputDirectory == null ? (gac ? Environment.CurrentDirectory : Path.GetDirectoryName(assembly.Location)) : outputDirectory; + outputDirectory = outputDirectory ?? (gac ? Environment.CurrentDirectory : Path.GetDirectoryName(assembly.Location)); if (!Directory.Exists(outputDirectory)) { diff --git a/src/libraries/System.Collections.Specialized/src/System/Collections/Specialized/NameObjectCollectionBase.cs b/src/libraries/System.Collections.Specialized/src/System/Collections/Specialized/NameObjectCollectionBase.cs index 4313a8661d7018..a27e42f36dbc0f 100644 --- a/src/libraries/System.Collections.Specialized/src/System/Collections/Specialized/NameObjectCollectionBase.cs +++ b/src/libraries/System.Collections.Specialized/src/System/Collections/Specialized/NameObjectCollectionBase.cs @@ -43,7 +43,7 @@ protected NameObjectCollectionBase() : this(s_defaultComparer) protected NameObjectCollectionBase(IEqualityComparer? equalityComparer) { - _keyComparer = (equalityComparer == null) ? s_defaultComparer : equalityComparer; + _keyComparer = equalityComparer ?? s_defaultComparer; Reset(); } diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationElementCollection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationElementCollection.cs index 7ef7a7270e3af2..34277ea16765c1 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationElementCollection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/ConfigurationElementCollection.cs @@ -1278,7 +1278,7 @@ bool IEnumerator.MoveNext() { Entry entry = (Entry)_itemsEnumerator.Current; if (entry.EntryType == EntryType.Removed) continue; - _current.Key = entry.GetKey(_thisCollection) != null ? entry.GetKey(_thisCollection) : "key"; + _current.Key = entry.GetKey(_thisCollection) ?? "key"; _current.Value = entry.Value; return true; } diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/DBCommandBuilder.cs b/src/libraries/System.Data.Common/src/System/Data/Common/DBCommandBuilder.cs index 756ca270b413f9..22639b9f82176f 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/DBCommandBuilder.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/DBCommandBuilder.cs @@ -477,8 +477,7 @@ public virtual string QuoteSuffix { get { - string? quoteSuffix = _quoteSuffix; - return ((null != quoteSuffix) ? quoteSuffix : string.Empty); + return (_quoteSuffix ?? string.Empty); } set { diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionOptions.cs b/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionOptions.cs index be176b8e756916..42082231ff87f6 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionOptions.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/DbConnectionOptions.cs @@ -37,7 +37,7 @@ public DbConnectionOptions(string? connectionString, Dictionary? { _useOdbcRules = useOdbcRules; _parsetable = new Dictionary(); - _usersConnectionString = ((null != connectionString) ? connectionString : ""); + _usersConnectionString = connectionString ?? ""; // first pass on parsing, initial syntax check if (0 < _usersConnectionString.Length) diff --git a/src/libraries/System.Data.Common/src/System/Data/DataColumn.cs b/src/libraries/System.Data.Common/src/System/Data/DataColumn.cs index 3cc5f403c1f97a..089db87b27567d 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataColumn.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataColumn.cs @@ -315,7 +315,7 @@ public long AutoIncrementStep [AllowNull] public string Caption { - get { return (_caption != null) ? _caption : _columnName; } + get { return _caption ?? _columnName; } set { if (value == null) @@ -695,7 +695,7 @@ public object DefaultValue throw ExceptionBuilder.DefaultValueAndAutoIncrement(); } - object newDefaultValue = (value == null) ? DBNull.Value : value; + object newDefaultValue = value ?? DBNull.Value; if (newDefaultValue != DBNull.Value && DataType != typeof(object)) { // If the DefualtValue is different from the Column DataType, we will coerce the value to the DataType diff --git a/src/libraries/System.Data.Common/src/System/Data/DataRelation.cs b/src/libraries/System.Data.Common/src/System/Data/DataRelation.cs index 9e7826856aea34..4154474effaf4d 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataRelation.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataRelation.cs @@ -707,7 +707,7 @@ private void Create(string? relationName, DataColumn[] parentColumns, DataColumn CheckState(); - _relationName = (relationName == null ? "" : relationName); + _relationName = relationName ?? ""; _createConstraints = createConstraints; } finally diff --git a/src/libraries/System.Data.Common/src/System/Data/DataTable.cs b/src/libraries/System.Data.Common/src/System/Data/DataTable.cs index c1ecaaf79318e1..9c3dc3192d114d 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataTable.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataTable.cs @@ -183,7 +183,7 @@ public DataTable() /// public DataTable(string? tableName) : this() { - _tableName = tableName == null ? "" : tableName; + _tableName = tableName ?? ""; } public DataTable(string? tableName, string? tableNamespace) : this(tableName) @@ -1904,7 +1904,7 @@ public string Namespace { if (_dataSet != null) { - string realNamespace = (value == null ? GetInheritedNamespace(new List()) : value); + string realNamespace = value ?? GetInheritedNamespace(new List()); if (realNamespace != Namespace) { // do this extra check only if the namespace is really going to change diff --git a/src/libraries/System.Data.Common/src/System/Data/DataView.cs b/src/libraries/System.Data.Common/src/System/Data/DataView.cs index 10d1470648ff2d..a9b240c6bfdb33 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataView.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataView.cs @@ -1702,7 +1702,7 @@ public DataTable ToTable(string? tableName, bool distinct, params string[] colum DataTable dt = new DataTable(); dt.Locale = _table!.Locale; dt.CaseSensitive = _table.CaseSensitive; - dt.TableName = ((null != tableName) ? tableName : _table.TableName); + dt.TableName = tableName ?? _table.TableName; dt.Namespace = _table.Namespace; dt.Prefix = _table.Prefix; diff --git a/src/libraries/System.Data.Common/src/System/Data/Filter/DataExpression.cs b/src/libraries/System.Data.Common/src/System/Data/Filter/DataExpression.cs index 79dc4a705ab7d8..a774254f3044b8 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Filter/DataExpression.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Filter/DataExpression.cs @@ -62,7 +62,7 @@ internal string Expression { get { - return (_originalExpression != null ? _originalExpression : ""); // CONSIDER: return optimized expression here (if bound) + return _originalExpression ?? ""; // CONSIDER: return optimized expression here (if bound) } } diff --git a/src/libraries/System.Data.Common/src/System/Data/LinqDataView.cs b/src/libraries/System.Data.Common/src/System/Data/LinqDataView.cs index 52083015f6525a..46bf364b58fc7b 100644 --- a/src/libraries/System.Data.Common/src/System/Data/LinqDataView.cs +++ b/src/libraries/System.Data.Common/src/System/Data/LinqDataView.cs @@ -63,7 +63,7 @@ internal LinqDataView( comparison, DataViewRowState.CurrentRows) { - this.sortExpressionBuilder = (sortExpressionBuilder == null) ? this.sortExpressionBuilder : sortExpressionBuilder; + this.sortExpressionBuilder = sortExpressionBuilder ?? this.sortExpressionBuilder; this.comparerKeyRow = comparerKeyRow; } diff --git a/src/libraries/System.Data.Common/src/System/Data/ProviderBase/DataReaderContainer.cs b/src/libraries/System.Data.Common/src/System/Data/ProviderBase/DataReaderContainer.cs index 1936388285da01..9d942c4af331ec 100644 --- a/src/libraries/System.Data.Common/src/System/Data/ProviderBase/DataReaderContainer.cs +++ b/src/libraries/System.Data.Common/src/System/Data/ProviderBase/DataReaderContainer.cs @@ -51,7 +51,7 @@ internal string GetName(int ordinal) { string fieldName = _dataReader.GetName(ordinal); Debug.Assert(null != fieldName, "null GetName"); - return ((null != fieldName) ? fieldName : ""); + return fieldName ?? ""; } internal DataTable? GetSchemaTable() { diff --git a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLString.cs b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLString.cs index 0c22570d2462d2..6b110831355528 100644 --- a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLString.cs +++ b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLString.cs @@ -351,7 +351,7 @@ internal int GetSQLCID() { throw new SqlTypeException(SQLResource.ConcatDiffCollationMessage); return new SqlString(x.m_lcid, x.m_flag, x.m_value + y.m_value, - (x.m_cmpInfo == null) ? y.m_cmpInfo : x.m_cmpInfo); + x.m_cmpInfo ?? y.m_cmpInfo); } // StringCompare: Common compare function which is used by Compare and CompareTo diff --git a/src/libraries/System.Data.Common/src/System/Data/XMLSchema.cs b/src/libraries/System.Data.Common/src/System/Data/XMLSchema.cs index b0bcf12107d64a..164b3731bdccba 100644 --- a/src/libraries/System.Data.Common/src/System/Data/XMLSchema.cs +++ b/src/libraries/System.Data.Common/src/System/Data/XMLSchema.cs @@ -678,9 +678,9 @@ public void LoadSchema(XmlSchemaSet schemaSet, DataSet ds) } ds.DataSetName = XmlConvert.DecodeName(_schemaName); string? ns = schemaRoot.TargetNamespace; - if (ds._namespaceURI == null || ds._namespaceURI.Length == 0) + if (string.IsNullOrEmpty(ds._namespaceURI)) {// set just one time, for backward compatibility - ds._namespaceURI = (ns == null) ? string.Empty : ns; // see fx\Data\XDO\ReadXml\SchemaM2.xml for more info + ds._namespaceURI = ns ?? string.Empty; // see fx\Data\XDO\ReadXml\SchemaM2.xml for more info } break; // we just need to take Name and NS from first schema [V1.0 & v1.1 semantics] } @@ -1540,12 +1540,12 @@ internal static string GetInstanceName(XmlSchemaAnnotated node) if (node is XmlSchemaElement) { XmlSchemaElement el = (XmlSchemaElement)node; - instanceName = el.Name != null ? el.Name : el.RefName.Name; + instanceName = el.Name ?? el.RefName.Name; } else if (node is XmlSchemaAttribute) { XmlSchemaAttribute el = (XmlSchemaAttribute)node; - instanceName = el.Name != null ? el.Name : el.RefName.Name; + instanceName = el.Name ?? el.RefName.Name; } Debug.Assert((instanceName != null) && (instanceName.Length != 0), "instanceName cannot be null or empty. There's an error in the XSD compiler"); diff --git a/src/libraries/System.Data.Common/src/System/Data/XmlDataLoader.cs b/src/libraries/System.Data.Common/src/System/Data/XmlDataLoader.cs index f8b4eae9bf74f4..ca41c924bdf604 100644 --- a/src/libraries/System.Data.Common/src/System/Data/XmlDataLoader.cs +++ b/src/libraries/System.Data.Common/src/System/Data/XmlDataLoader.cs @@ -1071,7 +1071,7 @@ private void LoadTable(DataTable table, bool isNested) // Check all columns c = collection[i]; // Get column for this index - c[row._tempRecord] = null != foundColumns[i] ? foundColumns[i] : DBNull.Value; + c[row._tempRecord] = foundColumns[i] ?? DBNull.Value; // Set column to loaded value of to // DBNull if value is missing. } diff --git a/src/libraries/System.Data.Common/src/System/Data/xmlsaver.cs b/src/libraries/System.Data.Common/src/System/Data/xmlsaver.cs index 538ced82fed4d1..32f72f51f01b15 100644 --- a/src/libraries/System.Data.Common/src/System/Data/xmlsaver.cs +++ b/src/libraries/System.Data.Common/src/System/Data/xmlsaver.cs @@ -1016,7 +1016,7 @@ internal XmlElement FillDataSetElement(XmlDocument xd, DataSet? ds, DataTable? d Debug.Assert(ds == null || dt == null); Debug.Assert(_dsElement != null); - DataSet? dataSet = (ds != null) ? ds : dt!.DataSet; + DataSet? dataSet = ds ?? dt!.DataSet; if (dataSet != null) { _dsElement.SetAttribute(Keywords.NAME, XmlConvert.EncodeLocalName(dataSet.DataSetName)); diff --git a/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/DBConnectionString.cs b/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/DBConnectionString.cs index b6f03f59116838..d916894edd0cd9 100644 --- a/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/DBConnectionString.cs +++ b/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/DBConnectionString.cs @@ -180,7 +180,7 @@ internal string Restrictions restrictions = builder.ToString(); } } - return ((null != restrictions) ? restrictions : ""); + return restrictions ?? ""; } } diff --git a/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/DbConnectionOptions.cs b/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/DbConnectionOptions.cs index 3aa0aa56b7f1b8..2ba41717dfc127 100644 --- a/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/DbConnectionOptions.cs +++ b/src/libraries/System.Data.Odbc/src/Common/System/Data/Common/DbConnectionOptions.cs @@ -45,7 +45,7 @@ public DbConnectionOptions(string connectionString, Dictionary? { _useOdbcRules = useOdbcRules; _parsetable = new Dictionary(); - _usersConnectionString = ((null != connectionString) ? connectionString : ""); + _usersConnectionString = connectionString ?? ""; // first pass on parsing, initial syntax check if (0 < _usersConnectionString.Length) @@ -248,8 +248,7 @@ internal static int ConvertToInt32Internal(string keyname, string stringValue) public string ConvertValueToString(string keyName, string defaultValue) { - string? value = _parsetable[keyName]; - return ((null != value) ? value : defaultValue); + return _parsetable[keyName] ?? defaultValue; } public bool ContainsKey(string keyword) diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcCommand.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcCommand.cs index 749c45d7f50ffb..ec050d499d7d9d 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcCommand.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcCommand.cs @@ -163,8 +163,7 @@ public override string CommandText { get { - string? value = _commandText; - return ((null != value) ? value : string.Empty); + return _commandText ?? string.Empty; } set { diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcError.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcError.cs index 564089c6904647..23f6b7bcf2f7ec 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcError.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcError.cs @@ -25,7 +25,7 @@ public string Message { get { - return ((null != _message) ? _message : string.Empty); + return _message ?? string.Empty; } } @@ -49,7 +49,7 @@ public string Source { get { - return ((null != _source) ? _source : string.Empty); + return _source ?? string.Empty; } } diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameter.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameter.cs index 088b2e5e8464e7..b23398fd291a44 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameter.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameter.cs @@ -225,8 +225,7 @@ public override string ParameterName { // V1.2.3300, XXXParameter V1.0.3300 get { - string? parameterName = _parameterName; - return ((null != parameterName) ? parameterName : string.Empty); + return _parameterName ?? string.Empty; } set { diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameterHelper.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameterHelper.cs index 450bf1d2d56bba..878237aa050cd9 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameterHelper.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcParameterHelper.cs @@ -139,8 +139,7 @@ public override string SourceColumn { get { - string? sourceColumn = _sourceColumn; - return ((null != sourceColumn) ? sourceColumn : string.Empty); + return _sourceColumn ?? string.Empty; } set { diff --git a/src/libraries/System.Data.OleDb/src/ColumnBinding.cs b/src/libraries/System.Data.OleDb/src/ColumnBinding.cs index 344ccae3b8ab1e..0e5c8083aa1003 100644 --- a/src/libraries/System.Data.OleDb/src/ColumnBinding.cs +++ b/src/libraries/System.Data.OleDb/src/ColumnBinding.cs @@ -684,7 +684,7 @@ private byte[] Value_ByRefBYTES() bindings.DangerousRelease(); } } - return ((null != value) ? value : Array.Empty()); + return value ?? Array.Empty(); } private void Value_ByRefBYTES(byte[] value) { diff --git a/src/libraries/System.Data.OleDb/src/DbConnectionOptions.cs b/src/libraries/System.Data.OleDb/src/DbConnectionOptions.cs index 8a51b5bdfe0a82..f7979d82f333ea 100644 --- a/src/libraries/System.Data.OleDb/src/DbConnectionOptions.cs +++ b/src/libraries/System.Data.OleDb/src/DbConnectionOptions.cs @@ -128,7 +128,7 @@ public DbConnectionOptions(string? connectionString, Hashtable? synonyms, bool u { UseOdbcRules = useOdbcRules; _parsetable = new Hashtable(); - _usersConnectionString = ((null != connectionString) ? connectionString : ""); + _usersConnectionString = connectionString ?? ""; // first pass on parsing, initial syntax check if (0 < _usersConnectionString.Length) @@ -151,7 +151,7 @@ private string UsersConnectionString(bool hidePassword, bool forceHidePassword) { ReplacePasswordPwd(out connectionString, false); } - return ((null != connectionString) ? connectionString : ""); + return connectionString ?? ""; } internal bool HasPersistablePassword @@ -307,8 +307,7 @@ internal static int ConvertToInt32Internal(string keyname, string stringValue) public string? ConvertValueToString(string keyName, string? defaultValue) { - string? value = (string?)_parsetable[keyName]; - return ((null != value) ? value : defaultValue); + return (string?)_parsetable[keyName] ?? defaultValue; } private static bool CompareInsensitiveInvariant(string strvalue, string strconst) diff --git a/src/libraries/System.Data.OleDb/src/DbParameterHelper.cs b/src/libraries/System.Data.OleDb/src/DbParameterHelper.cs index 0a25ac9fcc53c6..d70bff0d9376be 100644 --- a/src/libraries/System.Data.OleDb/src/DbParameterHelper.cs +++ b/src/libraries/System.Data.OleDb/src/DbParameterHelper.cs @@ -134,8 +134,7 @@ public override string SourceColumn { // V1.2.3300, XXXParameter V1.0.3300 get { - string? sourceColumn = _sourceColumn; - return ((null != sourceColumn) ? sourceColumn : string.Empty); + return _sourceColumn ?? string.Empty; } set { diff --git a/src/libraries/System.Data.OleDb/src/OleDbCommand.cs b/src/libraries/System.Data.OleDb/src/OleDbCommand.cs index 31a79543b79234..91049ef7039710 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbCommand.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbCommand.cs @@ -112,8 +112,7 @@ public override string CommandText { get { - string? value = _commandText; - return ((null != value) ? value : string.Empty); + return _commandText ?? string.Empty; } set { diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs index 6b33d5ca6b14f4..582f20230507d4 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs @@ -177,8 +177,7 @@ public string Provider get { OleDbConnectionString? constr = this.OleDbConnectionStringValue; - string? value = ((null != constr) ? constr.ConvertValueToString(ODB.Provider, null) : null); - return ((null != value) ? value : string.Empty); + return constr?.ConvertValueToString(ODB.Provider, null) ?? string.Empty; } } diff --git a/src/libraries/System.Data.OleDb/src/OleDbDataReader.cs b/src/libraries/System.Data.OleDb/src/OleDbDataReader.cs index cb2c9b06dc5edb..752fabd0f1b80e 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbDataReader.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbDataReader.cs @@ -1972,8 +1972,8 @@ private void AppendSchemaInfo() MetaData info = _metadata[i]; if ((null != info.baseTableName) && (0 < info.baseTableName.Length)) { - catalogName = ((null != info.baseCatalogName) ? info.baseCatalogName : ""); - schemaName = ((null != info.baseSchemaName) ? info.baseSchemaName : ""); + catalogName = info.baseCatalogName ?? ""; + schemaName = info.baseSchemaName ?? ""; if (null == baseTableName) { baseSchemaName = schemaName; diff --git a/src/libraries/System.Data.OleDb/src/OleDbError.cs b/src/libraries/System.Data.OleDb/src/OleDbError.cs index fe07229e52925f..db1968fb844ac0 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbError.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbError.cs @@ -74,8 +74,7 @@ public string Message { get { - string? message = this.message; - return ((null != message) ? message : string.Empty); + return this.message ?? string.Empty; } } @@ -91,8 +90,7 @@ public string Source { get { - string? source = this.source; - return ((null != source) ? source : string.Empty); + return this.source ?? string.Empty; } } @@ -100,8 +98,7 @@ public string SQLState { get { - string? sqlState = this.sqlState; - return ((null != sqlState) ? sqlState : string.Empty); + return this.sqlState ?? string.Empty; } } diff --git a/src/libraries/System.Data.OleDb/src/OleDbException.cs b/src/libraries/System.Data.OleDb/src/OleDbException.cs index 3a562dc7a80bcb..fa0747ad450b04 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbException.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbException.cs @@ -57,8 +57,7 @@ public OleDbErrorCollection Errors { get { - OleDbErrorCollection errors = this.oledbErrors; - return ((null != errors) ? errors : new OleDbErrorCollection(null)); + return this.oledbErrors ?? new OleDbErrorCollection(null); } } diff --git a/src/libraries/System.Data.OleDb/src/OleDbParameter.cs b/src/libraries/System.Data.OleDb/src/OleDbParameter.cs index dcd2c4f8526485..f3a69eded0b4f3 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbParameter.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbParameter.cs @@ -166,8 +166,7 @@ public override string ParameterName { // V1.2.3300, XXXParameter V1.0.3300 get { - string? parameterName = _parameterName; - return ((null != parameterName) ? parameterName : string.Empty); + return _parameterName ?? string.Empty; } set { diff --git a/src/libraries/System.Data.OleDb/src/RowBinding.cs b/src/libraries/System.Data.OleDb/src/RowBinding.cs index 828900bc5778b0..aece6b47d8819d 100644 --- a/src/libraries/System.Data.OleDb/src/RowBinding.cs +++ b/src/libraries/System.Data.OleDb/src/RowBinding.cs @@ -191,7 +191,7 @@ internal object GetVariantValue(int offset) } } - return ((null != value) ? value : DBNull.Value); + return value ?? DBNull.Value; } // translate to native diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Switch.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Switch.cs index 583d4cc1c8a050..d8b98d815ea316 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Switch.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/Switch.cs @@ -115,7 +115,7 @@ public string Description { get { - return (_description == null) ? string.Empty : _description; + return _description ?? string.Empty; } } @@ -124,9 +124,7 @@ public StringDictionary Attributes get { Initialize(); - if (_attributes == null) - _attributes = new StringDictionary(); - return _attributes; + return _attributes ??= new StringDictionary(); } } diff --git a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceListener.cs b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceListener.cs index 5a3265d5a95467..52e43b12b31585 100644 --- a/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceListener.cs +++ b/src/libraries/System.Diagnostics.TraceSource/src/System/Diagnostics/TraceListener.cs @@ -237,7 +237,7 @@ public virtual void Write(string? message, string? category) if (category == null) Write(message); else - Write(category + ": " + ((message == null) ? string.Empty : message)); + Write(category + ": " + (message ?? string.Empty)); } /// @@ -310,7 +310,7 @@ public virtual void WriteLine(string? message, string? category) if (category == null) WriteLine(message); else - WriteLine(category + ": " + ((message == null) ? string.Empty : message)); + WriteLine(category + ": " + (message ?? string.Empty)); } /// diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADDNLinkedAttrSet.cs b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADDNLinkedAttrSet.cs index 06fa26cc6eac0d..37a8ef59d2fecd 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADDNLinkedAttrSet.cs +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADDNLinkedAttrSet.cs @@ -44,7 +44,7 @@ internal ADDNLinkedAttrSet( "ADDNLinkedAttrSet", "ADDNLinkedAttrSet: groupDN={0}, primaryGroupDN={1}, recursive={2}, PG queryFilter={3}, PG queryBase={4}", groupDN, - (primaryGroupDN != null ? primaryGroupDN : "NULL"), + primaryGroupDN ?? "NULL", recursive, (primaryGroupMembersSearcher != null ? primaryGroupMembersSearcher.Filter : "NULL"), (primaryGroupMembersSearcher != null ? primaryGroupMembersSearcher.SearchRoot.Path : "NULL")); @@ -89,7 +89,7 @@ internal ADDNLinkedAttrSet( "ADDNLinkedAttrSet", "ADDNLinkedAttrSet: groupDN={0}, primaryGroupDN={1}, recursive={2}, M queryFilter={3}, M queryBase={4}, PG queryFilter={5}, PG queryBase={6}", groupDN, - (primaryGroupDN != null ? primaryGroupDN : "NULL"), + primaryGroupDN ?? "NULL", recursive, (membersSearcher != null ? membersSearcher[0].Filter : "NULL"), (membersSearcher != null ? membersSearcher[0].SearchRoot.Path : "NULL"), diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADStoreCtx.cs b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADStoreCtx.cs index 806b76fb9905e0..8d121d3789597a 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADStoreCtx.cs +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADStoreCtx.cs @@ -1445,7 +1445,7 @@ internal override ResultSet GetGroupsMemberOf(Principal foreignPrincipal, StoreC } } - ds = new DirectorySearcher((fspContainer != null) ? fspContainer : ((dncContainer != null ? dncContainer : this.ctxBase))); + ds = new DirectorySearcher(fspContainer ?? dncContainer ?? this.ctxBase); // Pick some reasonable default values ds.PageSize = 256; diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADStoreCtx_LoadStore.cs b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADStoreCtx_LoadStore.cs index 2d8eebfc84ee79..5137b5446ddba7 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADStoreCtx_LoadStore.cs +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADStoreCtx_LoadStore.cs @@ -465,8 +465,8 @@ private Principal FindPrincipalByIdentRefHelper( "ADStoreCtx", "FindPrincipalByIdentRefHelper: type={0}, scheme={1}, value={2}, useSidHistory={3}", principalType.ToString(), - (urnScheme != null ? urnScheme : "NULL"), - (urnValue != null ? urnValue : "NULL"), + urnScheme ?? "NULL", + urnValue ?? "NULL", useSidHistory); // diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADStoreCtx_Query.cs b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADStoreCtx_Query.cs index 25f3bb87f26923..5a274e3e7b9b14 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADStoreCtx_Query.cs +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/ADStoreCtx_Query.cs @@ -980,7 +980,7 @@ protected static string ExtensionCacheConverter(FilterBase filter, string sugges foreach (KeyValuePair kvp in ec.properties) { - Type type = kvp.Value.Type == null ? kvp.Value.Value.GetType() : kvp.Value.Type; + Type type = kvp.Value.Type ?? kvp.Value.Value.GetType(); GlobalDebug.WriteLineIf(GlobalDebug.Info, "ADStoreCtx", "ExtensionCacheConverter filter type " + type.ToString()); GlobalDebug.WriteLineIf(GlobalDebug.Info, "ADStoreCtx", "ExtensionCacheConverter match type " + kvp.Value.MatchType.ToString()); diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/SidList.cs b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/SidList.cs index 7ecdd631117247..da8670b4113653 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/SidList.cs +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/SidList.cs @@ -18,7 +18,7 @@ internal SidList(List sidListByteFormat) : this(sidListByteFormat, null, internal SidList(List sidListByteFormat, string target, NetCred credentials) { GlobalDebug.WriteLineIf(GlobalDebug.Info, "SidList", "SidList: processing {0} ByteFormat SIDs", sidListByteFormat.Count); - GlobalDebug.WriteLineIf(GlobalDebug.Info, "SidList", "SidList: Targetting {0} ", (target != null) ? target : "local store"); + GlobalDebug.WriteLineIf(GlobalDebug.Info, "SidList", "SidList: Targetting {0} ", target ?? "local store"); // Build the list of SIDs to resolve IntPtr hUser = IntPtr.Zero; diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/Utils.cs b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/Utils.cs index eb08e73efd2fe2..ba32590767bd94 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/Utils.cs +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/Utils.cs @@ -656,8 +656,8 @@ internal static Principal ConstructFakePrincipalFromSID( "Utils", "ConstructFakePrincipalFromSID: Build principal for SID={0}, server={1}, authority={2}", Utils.ByteArrayToString(sid), - (serverName != null ? serverName : "NULL"), - (authorityName != null ? authorityName : "NULL")); + serverName ?? "NULL", + authorityName ?? "NULL"); Debug.Assert(ClassifySID(sid) == SidType.FakeObject); diff --git a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ConfigSet.cs b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ConfigSet.cs index 6a812be37ee45f..689fda3a80d054 100644 --- a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ConfigSet.cs +++ b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ConfigSet.cs @@ -589,7 +589,7 @@ internal static AdamInstance FindAliveAdamInstance(string? configSetName, Direct { // if we are passed the timeout period, we should throw, else do nothing if (DateTime.UtcNow.Subtract(startTime) > s_locationTimeout) - throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.ADAMInstanceNotFoundInConfigSet, (configSetName != null) ? configSetName : context.Name), typeof(AdamInstance), null); + throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.ADAMInstanceNotFoundInConfigSet, configSetName ?? context.Name), typeof(AdamInstance), null); } else throw ExceptionHelper.GetExceptionFromCOMException(context, e); @@ -602,7 +602,7 @@ internal static AdamInstance FindAliveAdamInstance(string? configSetName, Direct } // if we reach here, we haven't found an adam instance - throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.ADAMInstanceNotFoundInConfigSet, (configSetName != null) ? configSetName : context.Name), typeof(AdamInstance), null); + throw new ActiveDirectoryObjectNotFoundException(SR.Format(SR.ADAMInstanceNotFoundInConfigSet, configSetName ?? context.Name), typeof(AdamInstance), null); } /// Returns a DomainController object for the DC that holds the specified FSMO role diff --git a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/DomainController.cs b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/DomainController.cs index 446ccf16e5052c..6591bd03e450aa 100644 --- a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/DomainController.cs +++ b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/DomainController.cs @@ -1050,7 +1050,7 @@ internal static DomainControllerCollection FindAllInternal(DirectoryContext cont { // get the dns name of the domain DomainControllerInfo domainControllerInfo; - int errorCode = Locator.DsGetDcNameWrapper(null, (domainName != null) ? domainName : DirectoryContext.GetLoggedOnDomain(), null, (long)PrivateLocatorFlags.DirectoryServicesRequired, out domainControllerInfo); + int errorCode = Locator.DsGetDcNameWrapper(null, domainName ?? DirectoryContext.GetLoggedOnDomain(), null, (long)PrivateLocatorFlags.DirectoryServicesRequired, out domainControllerInfo); if (errorCode == NativeMethods.ERROR_NO_SUCH_DOMAIN) { diff --git a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ForestTrustRelationshipInformation.cs b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ForestTrustRelationshipInformation.cs index 4e21c7b81b49ca..b49fd6173fe079 100644 --- a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ForestTrustRelationshipInformation.cs +++ b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ForestTrustRelationshipInformation.cs @@ -35,7 +35,7 @@ internal ForestTrustRelationshipInformation(DirectoryContext context, string sou if (unmanagedTrust.NetbiosDomainName != (IntPtr)0) tmpNetBIOSName = Marshal.PtrToStringUni(unmanagedTrust.NetbiosDomainName); - this.target = (tmpDNSName == null ? tmpNetBIOSName : tmpDNSName); + this.target = tmpDNSName ?? tmpNetBIOSName; // direction if ((unmanagedTrust.Flags & (int)DS_DOMAINTRUST_FLAG.DS_DOMAIN_DIRECT_OUTBOUND) != 0 && (unmanagedTrust.Flags & (int)DS_DOMAINTRUST_FLAG.DS_DOMAIN_DIRECT_INBOUND) != 0) diff --git a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/TrustRelationshipInformation.cs b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/TrustRelationshipInformation.cs index cc546f6684fb8c..5d21478c2846aa 100644 --- a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/TrustRelationshipInformation.cs +++ b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/TrustRelationshipInformation.cs @@ -38,7 +38,7 @@ internal TrustRelationshipInformation(DirectoryContext context, string? source, // source this.source = source; // target - this.target = (obj.DnsDomainName == null ? obj.NetbiosDomainName : obj.DnsDomainName); + this.target = obj.DnsDomainName ?? obj.NetbiosDomainName; // direction if ((obj.Flags & (int)DS_DOMAINTRUST_FLAG.DS_DOMAIN_DIRECT_OUTBOUND) != 0 && (obj.Flags & (int)DS_DOMAINTRUST_FLAG.DS_DOMAIN_DIRECT_INBOUND) != 0) diff --git a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/Utils.cs b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/Utils.cs index 1016f010bd5123..ed53edd0832480 100644 --- a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/Utils.cs +++ b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/Utils.cs @@ -705,7 +705,7 @@ internal static unsafe IntPtr GetDSHandle(string? domainControllerName, string? } if (result != 0) { - throw ExceptionHelper.GetExceptionFromErrorCode(result, (domainControllerName != null) ? domainControllerName : domainName); + throw ExceptionHelper.GetExceptionFromErrorCode(result, domainControllerName ?? domainName); } return handle; } diff --git a/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs b/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs index 1015cfebda5fb2..48d670ee0e8c4e 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs +++ b/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.cs @@ -250,7 +250,7 @@ public string Path } set { - value = (value == null) ? string.Empty : value; + value ??= string.Empty; if (!string.Equals(_directory, value, PathInternal.StringComparison)) { if (value.Length == 0) diff --git a/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/QueryOperators/QuerySettings.cs b/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/QueryOperators/QuerySettings.cs index ada7204cd5061f..d8fa01b695a3a0 100644 --- a/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/QueryOperators/QuerySettings.cs +++ b/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/QueryOperators/QuerySettings.cs @@ -123,7 +123,7 @@ internal QuerySettings Merge(QuerySettings settings2) throw new InvalidOperationException(SR.ParallelQuery_DuplicateMergeOptions); } - TaskScheduler? tm = (this.TaskScheduler == null) ? settings2.TaskScheduler : this.TaskScheduler; + TaskScheduler? tm = this.TaskScheduler ?? settings2.TaskScheduler; int? dop = this.DegreeOfParallelism.HasValue ? this.DegreeOfParallelism : settings2.DegreeOfParallelism; CancellationToken externalCancellationToken = (this.CancellationState.ExternalCancellationToken.CanBeCanceled) ? this.CancellationState.ExternalCancellationToken : settings2.CancellationState.ExternalCancellationToken; ParallelExecutionMode? executionMode = this.ExecutionMode.HasValue ? this.ExecutionMode : settings2.ExecutionMode; diff --git a/src/libraries/System.Management/src/System/Management/ManagementClass.cs b/src/libraries/System.Management/src/System/Management/ManagementClass.cs index e5c5f2c1d9258e..9161fd9695e71c 100644 --- a/src/libraries/System.Management/src/System/Management/ManagementClass.cs +++ b/src/libraries/System.Management/src/System/Management/ManagementClass.cs @@ -1230,7 +1230,7 @@ public ManagementObjectCollection GetRelationshipClasses( IEnumWbemClassObject enumWbem = null; - EnumerationOptions o = (null != options) ? options : new EnumerationOptions(); + EnumerationOptions o = options ?? new EnumerationOptions(); //Ensure EnumerateDeep flag is turned off as it's invalid for queries o.EnumerateDeep = true; diff --git a/src/libraries/System.Management/src/System/Management/ManagementEventArgs.cs b/src/libraries/System.Management/src/System/Management/ManagementEventArgs.cs index b858c1b430c8e6..c03727cde888aa 100644 --- a/src/libraries/System.Management/src/System/Management/ManagementEventArgs.cs +++ b/src/libraries/System.Management/src/System/Management/ManagementEventArgs.cs @@ -251,7 +251,7 @@ public string Message { get { - return (null != message) ? message : string.Empty; + return message ?? string.Empty; } } } diff --git a/src/libraries/System.Management/src/System/Management/ManagementObject.cs b/src/libraries/System.Management/src/System/Management/ManagementObject.cs index bd551dcee66c96..4bd2095392917f 100644 --- a/src/libraries/System.Management/src/System/Management/ManagementObject.cs +++ b/src/libraries/System.Management/src/System/Management/ManagementObject.cs @@ -565,7 +565,7 @@ public virtual ManagementPath Path } set { - ManagementPath newPath = (null != value) ? value : new ManagementPath(); + ManagementPath newPath = value ?? new ManagementPath(); //If the new path contains a namespace path and the scope is currently defaulted, //we want to set the scope to the new namespace path provided @@ -778,8 +778,7 @@ public void Get() throw new InvalidOperationException(); else { - ObjectGetOptions gOptions = - (null == options) ? new ObjectGetOptions() : options; + ObjectGetOptions gOptions = options ?? new ObjectGetOptions(); SecurityHandler securityHandler = null; int status = (int)ManagementStatus.NoError; @@ -1038,7 +1037,7 @@ public ManagementObjectCollection GetRelated( Initialize(false); IEnumWbemClassObject enumWbem = null; - EnumerationOptions o = (null != options) ? options : new EnumerationOptions(); + EnumerationOptions o = options ?? new EnumerationOptions(); RelatedObjectQuery q = new RelatedObjectQuery( path.Path, relatedClass, @@ -1276,8 +1275,7 @@ public ManagementObjectCollection GetRelationships( Initialize(false); IEnumWbemClassObject enumWbem = null; - EnumerationOptions o = - (null != options) ? options : new EnumerationOptions(); + EnumerationOptions o = options ?? new EnumerationOptions(); RelationshipQuery q = new RelationshipQuery(path.Path, relationshipClass, relationshipQualifier, thisRole, classDefinitionsOnly); @@ -1465,7 +1463,7 @@ public ManagementPath Put(PutOptions options) { ManagementPath newPath = null; Initialize(true); - PutOptions o = (null != options) ? options : new PutOptions(); + PutOptions o = options ?? new PutOptions(); IWbemServices wbemServices = scope.GetIWbemServices(); @@ -1761,7 +1759,7 @@ public ManagementPath CopyTo(ManagementPath path, PutOptions options) destinationScope = new ManagementScope(path, scope); destinationScope.Initialize(); - PutOptions o = (null != options) ? options : new PutOptions(); + PutOptions o = options ?? new PutOptions(); IWbemServices wbemServices = destinationScope.GetIWbemServices(); ManagementPath newPath = null; @@ -1966,7 +1964,7 @@ public void Delete(DeleteOptions options) throw new InvalidOperationException(); Initialize(false); - DeleteOptions o = (null != options) ? options : new DeleteOptions(); + DeleteOptions o = options ?? new DeleteOptions(); IWbemServices wbemServices = scope.GetIWbemServices(); SecurityHandler securityHandler = null; @@ -2303,7 +2301,7 @@ public ManagementBaseObject InvokeMethod( else { Initialize(false); - InvokeMethodOptions o = (null != options) ? options : new InvokeMethodOptions(); + InvokeMethodOptions o = options ?? new InvokeMethodOptions(); SecurityHandler securityHandler = null; int status = (int)ManagementStatus.NoError; diff --git a/src/libraries/System.Management/src/System/Management/ManagementOptions.cs b/src/libraries/System.Management/src/System/Management/ManagementOptions.cs index 42278c4f9b1719..71e7bbe6ecb3d5 100644 --- a/src/libraries/System.Management/src/System/Management/ManagementOptions.cs +++ b/src/libraries/System.Management/src/System/Management/ManagementOptions.cs @@ -1296,7 +1296,7 @@ public class ConnectionOptions : ManagementOptions /// public string Locale { - get { return (null != locale) ? locale : string.Empty; } + get { return locale ?? string.Empty; } set { if (locale != value) @@ -1444,7 +1444,7 @@ public SecureString SecurePassword /// public string Authority { - get { return (null != authority) ? authority : string.Empty; } + get { return authority ?? string.Empty; } set { if (authority != value) diff --git a/src/libraries/System.Management/src/System/Management/ManagementQuery.cs b/src/libraries/System.Management/src/System/Management/ManagementQuery.cs index f044ab25fe4088..4d37fdc4abcdb6 100644 --- a/src/libraries/System.Management/src/System/Management/ManagementQuery.cs +++ b/src/libraries/System.Management/src/System/Management/ManagementQuery.cs @@ -74,7 +74,7 @@ protected internal virtual void ParseQuery(string query) { } /// public virtual string QueryString { - get { return (null != queryString) ? queryString : string.Empty; } + get { return queryString ?? string.Empty; } set { if (queryString != value) @@ -96,7 +96,7 @@ public virtual string QueryString /// public virtual string QueryLanguage { - get { return (null != queryLanguage) ? queryLanguage : string.Empty; } + get { return queryLanguage ?? string.Empty; } set { if (queryLanguage != value) @@ -844,7 +844,7 @@ public bool IsSchemaQuery /// public string ClassName { - get { return (null != className) ? className : string.Empty; } + get { return className ?? string.Empty; } set { className = value; BuildQuery(); FireIdentifierChanged(); } } @@ -863,7 +863,7 @@ public string ClassName /// public string Condition { - get { return (null != condition) ? condition : string.Empty; } + get { return condition ?? string.Empty; } set { condition = value; BuildQuery(); FireIdentifierChanged(); } } @@ -1404,7 +1404,7 @@ public bool IsSchemaQuery /// public string SourceObject { - get { return (null != sourceObject) ? sourceObject : string.Empty; } + get { return sourceObject ?? string.Empty; } set { sourceObject = value; BuildQuery(); FireIdentifierChanged(); } } @@ -1432,7 +1432,7 @@ public string SourceObject /// public string RelatedClass { - get { return (null != relatedClass) ? relatedClass : string.Empty; } + get { return relatedClass ?? string.Empty; } set { relatedClass = value; BuildQuery(); FireIdentifierChanged(); } } @@ -1460,7 +1460,7 @@ public string RelatedClass /// public string RelationshipClass { - get { return (null != relationshipClass) ? relationshipClass : string.Empty; } + get { return relationshipClass ?? string.Empty; } set { relationshipClass = value; BuildQuery(); FireIdentifierChanged(); } } @@ -1478,7 +1478,7 @@ public string RelationshipClass /// public string RelatedQualifier { - get { return (null != relatedQualifier) ? relatedQualifier : string.Empty; } + get { return relatedQualifier ?? string.Empty; } set { relatedQualifier = value; BuildQuery(); FireIdentifierChanged(); } } @@ -1496,7 +1496,7 @@ public string RelatedQualifier /// public string RelationshipQualifier { - get { return (null != relationshipQualifier) ? relationshipQualifier : string.Empty; } + get { return relationshipQualifier ?? string.Empty; } set { relationshipQualifier = value; BuildQuery(); FireIdentifierChanged(); } } @@ -1514,7 +1514,7 @@ public string RelationshipQualifier /// public string RelatedRole { - get { return (null != relatedRole) ? relatedRole : string.Empty; } + get { return relatedRole ?? string.Empty; } set { relatedRole = value; BuildQuery(); FireIdentifierChanged(); } } @@ -1531,7 +1531,7 @@ public string RelatedRole /// public string ThisRole { - get { return (null != thisRole) ? thisRole : string.Empty; } + get { return thisRole ?? string.Empty; } set { thisRole = value; BuildQuery(); FireIdentifierChanged(); } } @@ -2014,7 +2014,7 @@ public bool IsSchemaQuery /// public string SourceObject { - get { return (null != sourceObject) ? sourceObject : string.Empty; } + get { return sourceObject ?? string.Empty; } set { sourceObject = value; BuildQuery(); FireIdentifierChanged(); } } @@ -2032,7 +2032,7 @@ public string SourceObject /// public string RelationshipClass { - get { return (null != relationshipClass) ? relationshipClass : string.Empty; } + get { return relationshipClass ?? string.Empty; } set { relationshipClass = value; BuildQuery(); FireIdentifierChanged(); } } @@ -2050,7 +2050,7 @@ public string RelationshipClass /// public string RelationshipQualifier { - get { return (null != relationshipQualifier) ? relationshipQualifier : string.Empty; } + get { return relationshipQualifier ?? string.Empty; } set { relationshipQualifier = value; BuildQuery(); FireIdentifierChanged(); } } @@ -2068,7 +2068,7 @@ public string RelationshipQualifier /// public string ThisRole { - get { return (null != thisRole) ? thisRole : string.Empty; } + get { return thisRole ?? string.Empty; } set { thisRole = value; BuildQuery(); FireIdentifierChanged(); } } @@ -2762,7 +2762,7 @@ public override string QueryString /// public string EventClassName { - get { return (null != eventClassName) ? eventClassName : string.Empty; } + get { return eventClassName ?? string.Empty; } set { eventClassName = value; BuildQuery(); } } @@ -2796,7 +2796,7 @@ public string EventClassName /// public string Condition { - get { return (null != condition) ? condition : string.Empty; } + get { return condition ?? string.Empty; } set { condition = value; BuildQuery(); } } @@ -2953,7 +2953,7 @@ public StringCollection GroupByPropertyList /// public string HavingCondition { - get { return (null != havingCondition) ? havingCondition : string.Empty; } + get { return havingCondition ?? string.Empty; } set { havingCondition = value; BuildQuery(); } } diff --git a/src/libraries/System.Management/src/System/Management/Method.cs b/src/libraries/System.Management/src/System/Management/Method.cs index fd000d104d5e7f..267ed847e47baa 100644 --- a/src/libraries/System.Management/src/System/Management/Method.cs +++ b/src/libraries/System.Management/src/System/Management/Method.cs @@ -144,7 +144,7 @@ private void RefreshMethodInfo() /// public string Name { - get { return methodName != null ? methodName : ""; } + get { return methodName ?? ""; } } /// diff --git a/src/libraries/System.Management/src/System/Management/Property.cs b/src/libraries/System.Management/src/System/Management/Property.cs index d86b5a043ab221..62acc0ece9591d 100644 --- a/src/libraries/System.Management/src/System/Management/Property.cs +++ b/src/libraries/System.Management/src/System/Management/Property.cs @@ -121,7 +121,7 @@ private void RefreshPropertyInfo() /// public string Name { //doesn't change for this object so we don't need to refresh - get { return propertyName != null ? propertyName : ""; } + get { return propertyName ?? ""; } } /// diff --git a/src/libraries/System.Management/src/System/Management/Qualifier.cs b/src/libraries/System.Management/src/System/Management/Qualifier.cs index 5784fca1efe039..fcc68f6ccf035a 100644 --- a/src/libraries/System.Management/src/System/Management/Qualifier.cs +++ b/src/libraries/System.Management/src/System/Management/Qualifier.cs @@ -148,7 +148,7 @@ private static object MapQualValueToWmiValue(object qualVal) /// public string Name { - get { return qualifierName != null ? qualifierName : ""; } + get { return qualifierName ?? ""; } } /// diff --git a/src/libraries/System.Net.HttpListener/src/System/Net/Managed/WebSockets/HttpWebSocket.Managed.cs b/src/libraries/System.Net.HttpListener/src/System/Net/Managed/WebSockets/HttpWebSocket.Managed.cs index 400ba18f688e28..e15457a40f9020 100644 --- a/src/libraries/System.Net.HttpListener/src/System/Net/Managed/WebSockets/HttpWebSocket.Managed.cs +++ b/src/libraries/System.Net.HttpListener/src/System/Net/Managed/WebSockets/HttpWebSocket.Managed.cs @@ -68,7 +68,7 @@ internal static async Task AcceptWebSocketAsyncCor request.IsLocal, request.IsSecureConnection, origin!, - secWebSocketProtocols != null ? secWebSocketProtocols : Array.Empty(), + secWebSocketProtocols ?? Array.Empty(), secWebSocketVersion!, secWebSocketKey!, webSocket); diff --git a/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListener.Windows.cs b/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListener.Windows.cs index ebf2b1e6e9dad3..c8e813205f38ed 100644 --- a/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListener.Windows.cs +++ b/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListener.Windows.cs @@ -848,7 +848,7 @@ public HttpListenerContext EndGetContext(IAsyncResult asyncResult) // See if we found an acceptable auth header if (headerScheme == AuthenticationSchemes.None) { - if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(this, SR.Format(SR.net_log_listener_unmatched_authentication_scheme, authenticationScheme.ToString(), (authorizationHeader == null ? "" : authorizationHeader))); + if (NetEventSource.Log.IsEnabled()) NetEventSource.Error(this, SR.Format(SR.net_log_listener_unmatched_authentication_scheme, authenticationScheme.ToString(), authorizationHeader ?? "")); // If anonymous is allowed, just return the context. Otherwise go for the 401. if ((authenticationScheme & AuthenticationSchemes.Anonymous) != AuthenticationSchemes.None) diff --git a/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListenerContext.Windows.cs b/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListenerContext.Windows.cs index f35ff98fc2e920..2a45381fc2262d 100644 --- a/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListenerContext.Windows.cs +++ b/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListenerContext.Windows.cs @@ -32,7 +32,7 @@ internal void SetIdentity(IPrincipal principal, string? mutualAuthentication) { _mutualAuthentication = mutualAuthentication; _user = principal; - if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"mutual: {(mutualAuthentication == null ? "" : mutualAuthentication)}, Principal: {principal}"); + if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"mutual: {mutualAuthentication ?? ""}, Principal: {principal}"); } // This can be used to cache the results of HttpListener.ExtendedProtectionSelectorDelegate. diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mail/MailBnfHelper.cs b/src/libraries/System.Net.Mail/src/System/Net/Mail/MailBnfHelper.cs index 125f93e1dcb474..49220b21488876 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mail/MailBnfHelper.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mail/MailBnfHelper.cs @@ -199,7 +199,7 @@ internal static void ValidateHeaderName(string data) ++offset; } int start = offset; - StringBuilder localBuilder = (builder != null ? builder : new StringBuilder()); + StringBuilder localBuilder = builder ?? new StringBuilder(); for (; offset < data.Length; offset++) { if (data[offset] == '\\') @@ -278,7 +278,7 @@ internal static string ReadToken(string data, ref int offset, StringBuilder? bui internal static string? GetDateTimeString(DateTime value, StringBuilder? builder) { - StringBuilder localBuilder = (builder != null ? builder : new StringBuilder()); + StringBuilder localBuilder = builder ?? new StringBuilder(); localBuilder.Append(value.Day); localBuilder.Append(' '); localBuilder.Append(s_months[value.Month]); diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mail/MailMessage.cs b/src/libraries/System.Net.Mail/src/System/Net/Mail/MailMessage.cs index 70d844575ead30..21b82f7b9a0a5e 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mail/MailMessage.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mail/MailMessage.cs @@ -165,7 +165,7 @@ public string Subject { get { - return (_message.Subject != null ? _message.Subject : string.Empty); + return _message.Subject ?? string.Empty; } set { @@ -210,7 +210,7 @@ public string Body { get { - return (_body != null ? _body : string.Empty); + return _body ?? string.Empty; } set diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpFailedRecipientsException.cs b/src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpFailedRecipientsException.cs index 11cadf451887cc..6cd03b0efcf99b 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpFailedRecipientsException.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mail/SmtpFailedRecipientsException.cs @@ -39,7 +39,7 @@ public SmtpFailedRecipientsException(string? message, SmtpFailedRecipientExcepti { ArgumentNullException.ThrowIfNull(innerExceptions); - _innerExceptions = innerExceptions == null ? Array.Empty() : innerExceptions; + _innerExceptions = innerExceptions ?? Array.Empty(); } internal SmtpFailedRecipientsException(List innerExceptions, bool allFailed) : diff --git a/src/libraries/System.Net.Primitives/src/System/Net/Cookie.cs b/src/libraries/System.Net.Primitives/src/System/Net/Cookie.cs index ece5a17973407c..39092082a31727 100644 --- a/src/libraries/System.Net.Primitives/src/System/Net/Cookie.cs +++ b/src/libraries/System.Net.Primitives/src/System/Net/Cookie.cs @@ -229,7 +229,7 @@ public string Name { if (string.IsNullOrEmpty(value) || !InternalSetName(value)) { - throw new CookieException(SR.Format(SR.net_cookie_attribute, "Name", value == null ? "" : value)); + throw new CookieException(SR.Format(SR.net_cookie_attribute, "Name", value ?? "")); } } } @@ -351,7 +351,7 @@ internal bool VerifySetDefaults(CookieVariant variant, Uri uri, bool isLocalDoma { if (shouldThrow) { - throw new CookieException(SR.Format(SR.net_cookie_attribute, "Name", m_name == null ? "" : m_name)); + throw new CookieException(SR.Format(SR.net_cookie_attribute, "Name", m_name ?? "")); } return false; } @@ -362,7 +362,7 @@ internal bool VerifySetDefaults(CookieVariant variant, Uri uri, bool isLocalDoma { if (shouldThrow) { - throw new CookieException(SR.Format(SR.net_cookie_attribute, "Value", m_value == null ? "" : m_value)); + throw new CookieException(SR.Format(SR.net_cookie_attribute, "Value", m_value ?? "")); } return false; } @@ -413,7 +413,7 @@ internal bool VerifySetDefaults(CookieVariant variant, Uri uri, bool isLocalDoma { if (shouldThrow) { - throw new CookieException(SR.Format(SR.net_cookie_attribute, CookieFields.DomainAttributeName, domain == null ? "" : domain)); + throw new CookieException(SR.Format(SR.net_cookie_attribute, CookieFields.DomainAttributeName, domain ?? "")); } return false; } diff --git a/src/libraries/System.Net.Requests/src/System/Net/HttpWebResponse.cs b/src/libraries/System.Net.Requests/src/System/Net/HttpWebResponse.cs index 73d7b923f2f2a1..bfd7aab4821a20 100644 --- a/src/libraries/System.Net.Requests/src/System/Net/HttpWebResponse.cs +++ b/src/libraries/System.Net.Requests/src/System/Net/HttpWebResponse.cs @@ -347,7 +347,7 @@ public string GetResponseHeader(string headerName) { CheckDisposed(); string? headerValue = Headers[headerName]; - return (headerValue == null) ? string.Empty : headerValue; + return headerValue ?? string.Empty; } public override void Close() diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/SchemaExporter.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/SchemaExporter.cs index 3b44b607be6095..d85097f17acb5a 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/SchemaExporter.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/SchemaExporter.cs @@ -777,7 +777,7 @@ private static void AddDefaultTypedDatasetType(XmlSchemaSet schemas, XmlSchema d type.Name = localName; type.Particle = new XmlSchemaSequence(); XmlSchemaAny any = new XmlSchemaAny(); - any.Namespace = (datasetSchema.TargetNamespace == null) ? string.Empty : datasetSchema.TargetNamespace; + any.Namespace = datasetSchema.TargetNamespace ?? string.Empty; ((XmlSchemaSequence)type.Particle).Items.Add(any); schemas.Add(datasetSchema); XmlSchema schema = SchemaHelper.GetSchema(ns, schemas); diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlObjectSerializerWriteContext.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlObjectSerializerWriteContext.cs index 437aea1d441fdf..4e7ebc9a4ac401 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlObjectSerializerWriteContext.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlObjectSerializerWriteContext.cs @@ -689,7 +689,7 @@ internal void WriteExtensionDataValue(XmlWriterDelegator xmlWriter, IDataNode? d } if (dataNode.PreservesReferences - && OnHandleReference(xmlWriter, (dataNode.Value == null ? dataNode : dataNode.Value), true /*canContainCyclicReference*/)) + && OnHandleReference(xmlWriter, dataNode.Value ?? dataNode, canContainCyclicReference: true)) return; Type dataType = dataNode.DataType; @@ -717,7 +717,7 @@ internal void WriteExtensionDataValue(XmlWriterDelegator xmlWriter, IDataNode? d xmlWriter.WriteExtensionData(dataNode); } if (dataNode.PreservesReferences) - OnEndHandleReference(xmlWriter, (dataNode.Value == null ? dataNode : dataNode.Value), true /*canContainCyclicReference*/); + OnEndHandleReference(xmlWriter, (dataNode.Value ?? dataNode), true /*canContainCyclicReference*/); } [RequiresUnreferencedCode(DataContract.SerializerTrimmerWarning)] diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNodeReader.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNodeReader.cs index b41ca22a939548..4540cee1c0336e 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNodeReader.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNodeReader.cs @@ -24,7 +24,7 @@ internal XNodeReader(XNode node, XmlNameTable? nameTable, ReaderOptions options) { _source = node; _root = node; - _nameTable = nameTable != null ? nameTable : CreateNameTable(); + _nameTable = nameTable ?? CreateNameTable(); _omitDuplicateNamespaces = (options & ReaderOptions.OmitDuplicateNamespaces) != 0 ? true : false; } diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/XPath/XNodeNavigator.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/XPath/XNodeNavigator.cs index 90b195833cb2a2..881ddb9a3b7b20 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/XPath/XNodeNavigator.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/XPath/XNodeNavigator.cs @@ -50,7 +50,7 @@ internal sealed class XNodeNavigator : XPathNavigator, IXmlLineInfo public XNodeNavigator(XNode node, XmlNameTable? nameTable) { _source = node; - _nameTable = nameTable != null ? nameTable : CreateNameTable(); + _nameTable = nameTable ?? CreateNameTable(); } public XNodeNavigator(XNodeNavigator other) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlParserContext.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlParserContext.cs index 0ec44b8775e8ae..620eedb67d8895 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlParserContext.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlParserContext.cs @@ -68,12 +68,12 @@ public XmlParserContext(XmlNameTable? nt, XmlNamespaceManager? nsMgr, string? do } _nsMgr = nsMgr; - _docTypeName = (null == docTypeName ? string.Empty : docTypeName); - _pubId = (null == pubId ? string.Empty : pubId); - _sysId = (null == sysId ? string.Empty : sysId); - _internalSubset = (null == internalSubset ? string.Empty : internalSubset); - _baseURI = (null == baseURI ? string.Empty : baseURI); - _xmlLang = (null == xmlLang ? string.Empty : xmlLang); + _docTypeName = docTypeName ?? string.Empty; + _pubId = pubId ?? string.Empty; + _sysId = sysId ?? string.Empty; + _internalSubset = internalSubset ?? string.Empty; + _baseURI = baseURI ?? string.Empty; + _xmlLang = xmlLang ?? string.Empty; _xmlSpace = xmlSpace; _encoding = enc; } @@ -111,7 +111,7 @@ public string DocTypeName } set { - _docTypeName = (null == value ? string.Empty : value); + _docTypeName = value ?? string.Empty; } } @@ -124,7 +124,7 @@ public string PublicId } set { - _pubId = (null == value ? string.Empty : value); + _pubId = value ?? string.Empty; } } @@ -137,7 +137,7 @@ public string SystemId } set { - _sysId = (null == value ? string.Empty : value); + _sysId = value ?? string.Empty; } } @@ -150,7 +150,7 @@ public string BaseURI } set { - _baseURI = (null == value ? string.Empty : value); + _baseURI = value ?? string.Empty; } } @@ -163,7 +163,7 @@ public string InternalSubset } set { - _internalSubset = (null == value ? string.Empty : value); + _internalSubset = value ?? string.Empty; } } @@ -176,7 +176,7 @@ public string XmlLang } set { - _xmlLang = (null == value ? string.Empty : value); + _xmlLang = value ?? string.Empty; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs index 45df890dc49d43..e7595f82e1cfaf 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs @@ -494,7 +494,7 @@ internal XmlTextReaderImpl(string? url, TextReader input, XmlNameTable nt) : thi { ConvertAbsoluteUnixPathToAbsoluteUri(ref url, resolver: null); _namespaceManager = new XmlNamespaceManager(nt); - _reportedBaseUri = (url != null) ? url : string.Empty; + _reportedBaseUri = url ?? string.Empty; InitTextReaderInput(_reportedBaseUri, input); _reportedEncoding = _ps.encoding; } @@ -2599,7 +2599,7 @@ private bool IsResolverNull private XmlResolver GetTempResolver() { - return _xmlResolver == null ? new XmlUrlResolver() : _xmlResolver; + return _xmlResolver ?? new XmlUrlResolver(); } internal bool DtdParserProxy_PushEntity(IDtdEntityInfo entity, out int entityId) @@ -8031,7 +8031,7 @@ private void PushExternalEntityOrSubset(string? publicId, string? systemId, Uri? if (entityName == null) { - ThrowWithoutLineInfo(SR.Xml_CannotResolveExternalSubset, new string?[] { (publicId != null ? publicId : string.Empty), systemId }, null); + ThrowWithoutLineInfo(SR.Xml_CannotResolveExternalSubset, new string?[] { publicId ?? string.Empty, systemId }, null); } else { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImplAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImplAsync.cs index a017a26ed71a8a..1f4672577e2c40 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImplAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImplAsync.cs @@ -5199,7 +5199,7 @@ private async Task PushExternalEntityOrSubsetAsync(string? publicId, string? sys if (entityName == null) { - ThrowWithoutLineInfo(SR.Xml_CannotResolveExternalSubset, new string?[] { (publicId != null ? publicId : string.Empty), systemId }, null); + ThrowWithoutLineInfo(SR.Xml_CannotResolveExternalSubset, new string?[] { publicId ?? string.Empty, systemId }, null); } else { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWellFormedWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWellFormedWriter.cs index 5a44dde1304f5c..e64a48898e8bfe 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWellFormedWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlWellFormedWriter.cs @@ -269,7 +269,7 @@ internal XmlWellFormedWriter(XmlWriter writer, XmlWriterSettings settings) else { string? defaultNs = _predefinedNamespaces.LookupNamespace(string.Empty); - _nsStack[2].Set(string.Empty, (defaultNs == null ? string.Empty : defaultNs), NamespaceKind.Implied); + _nsStack[2].Set(string.Empty, defaultNs ?? string.Empty, NamespaceKind.Implied); } _nsTop = 2; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReader.cs index 16d288c23a0691..c43f4b167153ba 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReader.cs @@ -2383,7 +2383,7 @@ private object InternalReadContentAsObject(bool unwrapTypedValue, out string ori if (_validationState == ValidatingReaderState.OnDefaultAttribute) { XmlSchemaAttribute schemaAttr = _attributePSVI.attributeSchemaInfo.SchemaAttribute!; - originalStringValue = (schemaAttr.DefaultValue != null) ? schemaAttr.DefaultValue : schemaAttr.FixedValue!; + originalStringValue = schemaAttr.DefaultValue ?? schemaAttr.FixedValue!; } return ReturnBoxedValue(_attributePSVI.typedAttributeValue, AttributeSchemaInfo.XmlType!, unwrapTypedValue); @@ -2796,7 +2796,7 @@ internal void CachingCallBack(XsdCachingReader cachingReader) XmlSchemaElement? schemaElem = _xmlSchemaInfo.SchemaElement; if (schemaElem != null) { - return (schemaElem.DefaultValue != null) ? schemaElem.DefaultValue : schemaElem.FixedValue; + return schemaElem.DefaultValue ?? schemaElem.FixedValue; } } else diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReaderAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReaderAsync.cs index e0225d0630ab5c..4794bfd78f6236 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReaderAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XsdValidatingReaderAsync.cs @@ -695,7 +695,7 @@ private async Task InternalReadContentAsObjectAsync(bool unwrapTypedValu if (_validationState == ValidatingReaderState.OnDefaultAttribute) { XmlSchemaAttribute schemaAttr = _attributePSVI.attributeSchemaInfo.SchemaAttribute!; - originalStringValue = (schemaAttr.DefaultValue != null) ? schemaAttr.DefaultValue : schemaAttr.FixedValue!; + originalStringValue = schemaAttr.DefaultValue ?? schemaAttr.FixedValue!; } return (originalStringValue, ReturnBoxedValue(_attributePSVI.typedAttributeValue, AttributeSchemaInfo.XmlType!, unwrapTypedValue)); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDeclaration.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDeclaration.cs index 184a92536a1659..14ce03ed0762ec 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDeclaration.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDeclaration.cs @@ -46,7 +46,7 @@ public string Encoding { get { return _encoding; } [MemberNotNull(nameof(_encoding))] - set { _encoding = ((value == null) ? string.Empty : value); } + set { _encoding = value ?? string.Empty; } } // Specifies the value of the standalone attribute. diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlElementList.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlElementList.cs index 1ba414135acae7..a0b9d9ec1542b4 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlElementList.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlElementList.cs @@ -208,7 +208,7 @@ private bool IsMatch(XmlNode curNode) { if (_empty == true) return null; - XmlNode node = (n == null) ? _rootNode : n; + XmlNode node = n ?? _rootNode; return GetMatchingNode(node, true); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNode.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNode.cs index 735023dd311a36..c5386af1823c64 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNode.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNode.cs @@ -1166,8 +1166,7 @@ public virtual string GetNamespaceOfPrefix(string prefix) // the prefix defined in that declaration. public virtual string GetPrefixOfNamespace(string namespaceURI) { - string? prefix = GetPrefixOfNamespaceStrict(namespaceURI); - return prefix != null ? prefix : string.Empty; + return GetPrefixOfNamespaceStrict(namespaceURI) ?? string.Empty; } internal string? GetPrefixOfNamespaceStrict(string namespaceURI) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeReader.cs index 15de351a67742e..437eaf974d942d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlNodeReader.cs @@ -228,34 +228,46 @@ public string Value { string? retValue; XmlNodeType nt = _curNode.NodeType; + if (_nAttrInd != -1) { //Pointing at the one of virtual attributes of Declaration or DocumentType nodes Debug.Assert(nt == XmlNodeType.XmlDeclaration || nt == XmlNodeType.DocumentType); Debug.Assert(_nAttrInd >= 0 && _nAttrInd < AttributeCount); - if (_curNode.NodeType == XmlNodeType.XmlDeclaration) - return decNodeAttributes[_nAttrInd].value!; - else - return docTypeNodeAttributes[_nAttrInd].value!; + return _curNode.NodeType == XmlNodeType.XmlDeclaration ? + decNodeAttributes[_nAttrInd].value! : + docTypeNodeAttributes[_nAttrInd].value!; } + if (nt == XmlNodeType.DocumentType) + { retValue = ((XmlDocumentType)_curNode).InternalSubset; //in this case nav.Value will be null + } else if (nt == XmlNodeType.XmlDeclaration) { StringBuilder strb = new StringBuilder(string.Empty); if (_nDeclarationAttrCount == -1) + { InitDecAttr(); + } + for (int i = 0; i < _nDeclarationAttrCount; i++) { strb.Append($"{decNodeAttributes[i].name}=\"{decNodeAttributes[i].value}\""); if (i != (_nDeclarationAttrCount - 1)) + { strb.Append(' '); + } } + retValue = strb.ToString(); } else + { retValue = _curNode.Value; - return (retValue == null) ? string.Empty : retValue; + } + + return retValue ?? string.Empty; } } @@ -1340,7 +1352,7 @@ public override int AttributeCount //if not on Attribute, only element node could have attributes if (!IsInReadingStates()) return null; - string ns = (namespaceURI == null) ? string.Empty : namespaceURI; + string ns = namespaceURI ?? string.Empty; return _readerNav.GetAttribute(name, ns); } @@ -1380,7 +1392,7 @@ public override bool MoveToAttribute(string name, string? namespaceURI) if (!IsInReadingStates()) return false; _readerNav.ResetMove(ref _curDepth, ref _nodeType); - string ns = (namespaceURI == null) ? string.Empty : namespaceURI; + string ns = namespaceURI ?? string.Empty; if (_readerNav.MoveToAttribute(name, ns)) { //, ref curDepth ) ) { _curDepth++; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/Preprocessor.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/Preprocessor.cs index 327f490d57f49c..723ee9d6a9b481 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/Preprocessor.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/Preprocessor.cs @@ -313,7 +313,7 @@ private void LoadExternals(XmlSchema schema) { XmlSchemaImport import = (include as XmlSchemaImport)!; Debug.Assert(import != null); - string importNS = import.Namespace != null ? import.Namespace : string.Empty; + string importNS = import.Namespace ?? string.Empty; if (!schema.ImportedNamespaces.Contains(importNS)) { schema.ImportedNamespaces.Add(importNS); @@ -666,7 +666,7 @@ private void Preprocess(XmlSchema schema, string? targetNamespace, ArrayList imp BuildRefNamespaces(schema); ValidateIdAttribute(schema); - _targetNamespace = targetNamespace == null ? string.Empty : targetNamespace; + _targetNamespace = targetNamespace ?? string.Empty; SetSchemaDefaults(schema); @@ -709,7 +709,7 @@ private void Preprocess(XmlSchema schema, string? targetNamespace, ArrayList imp if (includedSchema != _rootSchema) { XmlSchemaImport import = (external as XmlSchemaImport)!; - string importNS = import.Namespace != null ? import.Namespace : string.Empty; + string importNS = import.Namespace ?? string.Empty; if (!imports.Contains(includedSchema)) { imports.Add(includedSchema); @@ -854,7 +854,7 @@ private void PreprocessRedefine(RedefineEntry redefineEntry) XmlSchema schemaToUpdate = redefineEntry.schemaToUpdate; ArrayList includesOfRedefine = new ArrayList(); GetIncludedSet(originalSchema, includesOfRedefine); - string targetNS = schemaToUpdate.TargetNamespace == null ? string.Empty : schemaToUpdate.TargetNamespace; + string targetNS = schemaToUpdate.TargetNamespace ?? string.Empty; XmlSchemaObjectCollection items = redefine.Items; for (int i = 0; i < items.Count; ++i) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaAttDef.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaAttDef.cs index df43302695f781..bbd11cb2766a57 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaAttDef.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaAttDef.cs @@ -144,7 +144,7 @@ internal int ValueLineNumber [AllowNull] internal string DefaultValueExpanded { - get { return (_defExpanded != null) ? _defExpanded : string.Empty; } + get { return _defExpanded ?? string.Empty; } set { _defExpanded = value; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaCollectionpreProcessor.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaCollectionpreProcessor.cs index e011edae37964b..07bf38d05f56b6 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaCollectionpreProcessor.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaCollectionpreProcessor.cs @@ -164,7 +164,7 @@ private void LoadExternals(XmlSchema schema, XmlSchemaCollection? xsc) if (xsc != null && include is XmlSchemaImport) { //Added for SchemaCollection compatibility XmlSchemaImport import = (XmlSchemaImport)include; - string importNS = import.Namespace != null ? import.Namespace : string.Empty; + string importNS = import.Namespace ?? string.Empty; include.Schema = xsc[importNS]; //Fetch it from the collection if (include.Schema != null) { @@ -181,7 +181,7 @@ private void LoadExternals(XmlSchema schema, XmlSchemaCollection? xsc) if (subInc is XmlSchemaImport) { XmlSchemaImport subImp = (XmlSchemaImport)subInc; - subUri = subImp.BaseUri != null ? subImp.BaseUri : (subImp.Schema != null && subImp.Schema.BaseUri != null ? subImp.Schema.BaseUri : null); + subUri = subImp.BaseUri ?? (subImp.Schema != null && subImp.Schema.BaseUri != null ? subImp.Schema.BaseUri : null); if (subUri != null) { if (_schemaLocations![subUri] != null) @@ -430,7 +430,7 @@ private void Preprocess(XmlSchema schema, string? targetNamespace, Compositor co //Build the namespaces that can be referenced in the current schema BuildRefNamespaces(schema); - _targetNamespace = targetNamespace == null ? string.Empty : targetNamespace; + _targetNamespace = targetNamespace ?? string.Empty; if (schema.BlockDefault == XmlSchemaDerivationMethod.All) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaDeclBase.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaDeclBase.cs index bf96ba0a3c779c..25a8d739e1e7fc 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaDeclBase.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaDeclBase.cs @@ -55,7 +55,7 @@ internal XmlQualifiedName Name [AllowNull] internal string Prefix { - get { return (prefix == null) ? string.Empty : prefix; } + get { return prefix ?? string.Empty; } set { prefix = value; } } @@ -112,7 +112,7 @@ internal List? Values internal string DefaultValueRaw { - get { return (defaultValueRaw != null) ? defaultValueRaw : string.Empty; } + get { return defaultValueRaw ?? string.Empty; } set { defaultValueRaw = value; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaEntity.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaEntity.cs index a3810d9189ee36..755dd161e613c4 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaEntity.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaEntity.cs @@ -165,7 +165,7 @@ internal int Pos internal string BaseURI { - get { return (_baseURI == null) ? string.Empty : _baseURI; } + get { return _baseURI ?? string.Empty; } set { _baseURI = value; } } @@ -177,7 +177,7 @@ internal bool ParsingInProgress internal string DeclaredURI { - get { return (_declaredURI == null) ? string.Empty : _declaredURI; } + get { return _declaredURI ?? string.Empty; } set { _declaredURI = value; } } }; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaAttribute.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaAttribute.cs index ca5ce6244f6cd8..676d26a83e5b77 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaAttribute.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaAttribute.cs @@ -60,14 +60,14 @@ public string? Name public XmlQualifiedName RefName { get { return _refName; } - set { _refName = (value == null ? XmlQualifiedName.Empty : value); } + set { _refName = value ?? XmlQualifiedName.Empty; } } [XmlAttribute("type")] public XmlQualifiedName SchemaTypeName { get { return _typeName; } - set { _typeName = (value == null ? XmlQualifiedName.Empty : value); } + set { _typeName = value ?? XmlQualifiedName.Empty; } } [XmlElement("simpleType")] diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaAttributeGroupref.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaAttributeGroupref.cs index 873bcd693204c7..e68a769883249c 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaAttributeGroupref.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaAttributeGroupref.cs @@ -16,7 +16,7 @@ public class XmlSchemaAttributeGroupRef : XmlSchemaAnnotated public XmlQualifiedName RefName { get { return _refName; } - set { _refName = (value == null ? XmlQualifiedName.Empty : value); } + set { _refName = value ?? XmlQualifiedName.Empty; } } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaCollection.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaCollection.cs index 9381147780298c..39e4e68689e576 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaCollection.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaCollection.cs @@ -195,7 +195,7 @@ public XmlSchema? this[string? ns] { get { - XmlSchemaCollectionNode? node = (XmlSchemaCollectionNode?)_collection[(ns != null) ? ns : string.Empty]; + XmlSchemaCollectionNode? node = (XmlSchemaCollectionNode?)_collection[ns ?? string.Empty]; return (node != null) ? node.Schema : null; } } @@ -209,7 +209,7 @@ public bool Contains(XmlSchema schema) public bool Contains(string? ns) { - return _collection[(ns != null) ? ns : string.Empty] != null; + return _collection[ns ?? string.Empty] != null; } /// @@ -279,7 +279,7 @@ int ICollection.Count internal SchemaInfo? GetSchemaInfo(string? ns) { - XmlSchemaCollectionNode? node = (XmlSchemaCollectionNode?)_collection[(ns != null) ? ns : string.Empty]; + XmlSchemaCollectionNode? node = (XmlSchemaCollectionNode?)_collection[ns ?? string.Empty]; return (node != null) ? node.SchemaInfo : null; } @@ -316,7 +316,7 @@ internal SchemaNames GetSchemaNames(XmlNameTable nt) errorCount = 1; } - ns = schema.TargetNamespace == null ? string.Empty : schema.TargetNamespace; + ns = schema.TargetNamespace ?? string.Empty; } errorCount += schema.ErrorCount; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaComplexContentExtension.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaComplexContentExtension.cs index efbbc73fe88532..a0d4aaec7c1e49 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaComplexContentExtension.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaComplexContentExtension.cs @@ -17,7 +17,7 @@ public class XmlSchemaComplexContentExtension : XmlSchemaContent public XmlQualifiedName BaseTypeName { get { return _baseTypeName; } - set { _baseTypeName = (value == null ? XmlQualifiedName.Empty : value); } + set { _baseTypeName = value ?? XmlQualifiedName.Empty; } } [XmlElement("group", typeof(XmlSchemaGroupRef)), diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaComplexContentRestriction.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaComplexContentRestriction.cs index 0b382791dcf65b..972e0329cfa59e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaComplexContentRestriction.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaComplexContentRestriction.cs @@ -17,7 +17,7 @@ public class XmlSchemaComplexContentRestriction : XmlSchemaContent public XmlQualifiedName BaseTypeName { get { return _baseTypeName; } - set { _baseTypeName = (value == null ? XmlQualifiedName.Empty : value); } + set { _baseTypeName = value ?? XmlQualifiedName.Empty; } } [XmlElement("group", typeof(XmlSchemaGroupRef)), diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaElement.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaElement.cs index c7c3961a3ce1dd..aa22f5ecf25e24 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaElement.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaElement.cs @@ -115,7 +115,7 @@ internal bool HasAbstractAttribute public XmlQualifiedName RefName { get { return _refName; } - set { _refName = (value == null ? XmlQualifiedName.Empty : value); } + set { _refName = value ?? XmlQualifiedName.Empty; } } [XmlAttribute("substitutionGroup")] @@ -123,7 +123,7 @@ public XmlQualifiedName RefName public XmlQualifiedName SubstitutionGroup { get { return _substitutionGroup; } - set { _substitutionGroup = (value == null ? XmlQualifiedName.Empty : value); } + set { _substitutionGroup = value ?? XmlQualifiedName.Empty; } } [XmlAttribute("type")] @@ -131,7 +131,7 @@ public XmlQualifiedName SubstitutionGroup public XmlQualifiedName SchemaTypeName { get { return _typeName; } - set { _typeName = (value == null ? XmlQualifiedName.Empty : value); } + set { _typeName = value ?? XmlQualifiedName.Empty; } } [XmlElement("complexType", typeof(XmlSchemaComplexType)), diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaException.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaException.cs index a31ca1f82c63c8..4e90c684de605a 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaException.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaException.cs @@ -213,7 +213,7 @@ public override string Message { get { - return (_message == null) ? base.Message : _message; + return _message ?? base.Message; } } }; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaGroupRef.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaGroupRef.cs index b69998b260b455..4d081121cb3ba0 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaGroupRef.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaGroupRef.cs @@ -15,7 +15,7 @@ public class XmlSchemaGroupRef : XmlSchemaParticle public XmlQualifiedName RefName { get { return _refName; } - set { _refName = (value == null ? XmlQualifiedName.Empty : value); } + set { _refName = value ?? XmlQualifiedName.Empty; } } [XmlIgnore] diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaIdEntityConstraint.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaIdEntityConstraint.cs index 9b29480ef8898f..0c3fe22b8b39ed 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaIdEntityConstraint.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaIdEntityConstraint.cs @@ -89,7 +89,7 @@ public class XmlSchemaKeyref : XmlSchemaIdentityConstraint public XmlQualifiedName Refer { get { return _refer; } - set { _refer = (value == null ? XmlQualifiedName.Empty : value); } + set { _refer = value ?? XmlQualifiedName.Empty; } } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSet.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSet.cs index 5c9011e1aea6fa..7737fa93ef9699 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSet.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSet.cs @@ -946,7 +946,7 @@ internal void Add(string? targetNamespace, XmlReader reader, Hashtable validated if (schema != null) { Debug.Assert(ns != null); - string tns = schema.TargetNamespace == null ? string.Empty : schema.TargetNamespace; + string tns = schema.TargetNamespace ?? string.Empty; if (tns == ns) { return schema; @@ -1383,7 +1383,7 @@ internal bool GetSchemaByUri(Uri schemaUri, [NotNullWhen(true)] out XmlSchema? s internal static string GetTargetNamespace(XmlSchema schema) { - return schema.TargetNamespace == null ? string.Empty : schema.TargetNamespace; + return schema.TargetNamespace ?? string.Empty; } internal SortedList SortedSchemas diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSimpleContentExtension.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSimpleContentExtension.cs index 01fb7ade1b21b5..e12b079bde8672 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSimpleContentExtension.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSimpleContentExtension.cs @@ -15,7 +15,7 @@ public class XmlSchemaSimpleContentExtension : XmlSchemaContent public XmlQualifiedName BaseTypeName { get { return _baseTypeName; } - set { _baseTypeName = (value == null ? XmlQualifiedName.Empty : value); } + set { _baseTypeName = value ?? XmlQualifiedName.Empty; } } [XmlElement("attribute", typeof(XmlSchemaAttribute)), diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSimpleContentRestriction.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSimpleContentRestriction.cs index f4b5ba9dcf25de..41f23fadcff86f 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSimpleContentRestriction.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSimpleContentRestriction.cs @@ -17,7 +17,7 @@ public class XmlSchemaSimpleContentRestriction : XmlSchemaContent public XmlQualifiedName BaseTypeName { get { return _baseTypeName; } - set { _baseTypeName = (value == null ? XmlQualifiedName.Empty : value); } + set { _baseTypeName = value ?? XmlQualifiedName.Empty; } } [XmlElement("simpleType", typeof(XmlSchemaSimpleType))] diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSimpleTypeList.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSimpleTypeList.cs index 4ae0dbec2a694a..fa326e15e435c3 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSimpleTypeList.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSimpleTypeList.cs @@ -15,7 +15,7 @@ public class XmlSchemaSimpleTypeList : XmlSchemaSimpleTypeContent public XmlQualifiedName ItemTypeName { get { return _itemTypeName; } - set { _itemTypeName = (value == null ? XmlQualifiedName.Empty : value); } + set { _itemTypeName = value ?? XmlQualifiedName.Empty; } } [XmlElement("simpleType", typeof(XmlSchemaSimpleType))] diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSimpleTypeRestriction.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSimpleTypeRestriction.cs index a00192dbb6d1f4..f0e9d74ffd0455 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSimpleTypeRestriction.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaSimpleTypeRestriction.cs @@ -16,7 +16,7 @@ public class XmlSchemaSimpleTypeRestriction : XmlSchemaSimpleTypeContent public XmlQualifiedName BaseTypeName { get { return _baseTypeName; } - set { _baseTypeName = (value == null ? XmlQualifiedName.Empty : value); } + set { _baseTypeName = value ?? XmlQualifiedName.Empty; } } [XmlElement("simpleType", typeof(XmlSchemaSimpleType))] diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidator.cs index a41ef94dd7d5db..25bfa8dd5303f8 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidator.cs @@ -1238,7 +1238,7 @@ internal string GetConcatenatedValue() // for each level in the stack, endchildren and fill value from element if (HasIdentityConstraints) { - XmlSchemaType xmlType = memberType == null ? contextElementDecl.SchemaType! : memberType; + XmlSchemaType xmlType = memberType ?? contextElementDecl.SchemaType!; EndElementIdentityConstraints(typedValue!, stringValue, xmlType.Datatype!); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XsdValidator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XsdValidator.cs index 4e33a421969910..5412bad32aaec3 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XsdValidator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XsdValidator.cs @@ -149,7 +149,7 @@ private void ProcessInlineSchema() { SchemaInfo inlineSchemaInfo = new SchemaInfo(); inlineSchemaInfo.SchemaType = SchemaType.XSD; - inlineNS = schema.TargetNamespace == null ? string.Empty : schema.TargetNamespace; + inlineNS = schema.TargetNamespace ?? string.Empty; if (!SchemaInfo!.TargetNamespaces.ContainsKey(inlineNS)) { if (SchemaCollection!.Add(inlineNS, inlineSchemaInfo, schema, true) != null) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Mappings.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Mappings.cs index ab5b7c27ee8a1d..3610588efded77 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Mappings.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Mappings.cs @@ -54,7 +54,7 @@ internal bool HasDefault [AllowNull] internal virtual string Name { - get { return _name == null ? string.Empty : _name; } + get { return _name ?? string.Empty; } set { _name = value; } } @@ -132,7 +132,7 @@ internal string ToString(string? defaultNs) { if (Any) { - return $"{(Namespace == null ? "##any" : Namespace)}:{Name}"; + return $"{Namespace ?? "##any"}:{Name}"; } else { @@ -446,14 +446,14 @@ internal sealed class ConstantMapping : Mapping [AllowNull] internal string XmlName { - get { return _xmlName == null ? string.Empty : _xmlName; } + get { return _xmlName ?? string.Empty; } set { _xmlName = value; } } [AllowNull] internal string Name { - get { return _name == null ? string.Empty : _name; } + get { return _name ?? string.Empty; } set { _name = value; } } @@ -953,7 +953,7 @@ internal SpecifiedAccessor CheckSpecified internal string Name { - get { return _name == null ? string.Empty : _name; } + get { return _name ?? string.Empty; } set { _name = value; } } @@ -1358,7 +1358,7 @@ private void RetrieveSerializableSchema() { throw new InvalidOperationException(SR.Format(SR.XmlGetSchemaTypeMissing, _getSchemaMethod.DeclaringType!.FullName, _getSchemaMethod.Name, _xsiType.Name, _xsiType.Namespace)); } - _xsdType = _xsdType.Redefined != null ? _xsdType.Redefined : _xsdType; + _xsdType = _xsdType.Redefined ?? _xsdType; } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapAttributeAttribute.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapAttributeAttribute.cs index d1922c1d6222ce..ac54b7c6a6f492 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapAttributeAttribute.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapAttributeAttribute.cs @@ -25,7 +25,7 @@ public SoapAttributeAttribute(string attributeName) [AllowNull] public string AttributeName { - get { return _attributeName == null ? string.Empty : _attributeName; } + get { return _attributeName ?? string.Empty; } set { _attributeName = value; } } @@ -38,7 +38,7 @@ public string? Namespace [AllowNull] public string DataType { - get { return _dataType == null ? string.Empty : _dataType; } + get { return _dataType ?? string.Empty; } set { _dataType = value; } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapElementAttribute.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapElementAttribute.cs index 5aa2be39ae0f0b..166e7cfa719c54 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapElementAttribute.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapElementAttribute.cs @@ -25,14 +25,14 @@ public SoapElementAttribute(string? elementName) [AllowNull] public string ElementName { - get { return _elementName == null ? string.Empty : _elementName; } + get { return _elementName ?? string.Empty; } set { _elementName = value; } } [AllowNull] public string DataType { - get { return _dataType == null ? string.Empty : _dataType; } + get { return _dataType ?? string.Empty; } set { _dataType = value; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapEnumAttribute.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapEnumAttribute.cs index 018558456b1fce..54a74af1be20ce 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapEnumAttribute.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapEnumAttribute.cs @@ -23,7 +23,7 @@ public SoapEnumAttribute(string name) [AllowNull] public string Name { - get { return _name == null ? string.Empty : _name; } + get { return _name ?? string.Empty; } set { _name = value; } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapReflectionImporter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapReflectionImporter.cs index 462d4a7afe1186..cb81d6e8c0c095 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapReflectionImporter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapReflectionImporter.cs @@ -89,7 +89,7 @@ public XmlTypeMapping ImportTypeMapping(Type type, string? defaultNamespace) element.IsSoap = true; element.Mapping = ImportTypeMapping(_modelScope.GetTypeModel(type), new RecursionLimiter()); element.Name = element.Mapping.DefaultElementName; - element.Namespace = element.Mapping.Namespace == null ? defaultNamespace : element.Mapping.Namespace; + element.Namespace = element.Mapping.Namespace ?? defaultNamespace; element.Form = XmlSchemaForm.Qualified; XmlTypeMapping xmlMapping = new XmlTypeMapping(_typeScope, element); xmlMapping.SetKeyInternal(XmlMapping.GenerateKey(type, null, defaultNamespace)); @@ -125,7 +125,7 @@ public XmlMembersMapping ImportMembersMapping(string? elementName, string? ns, X element.Mapping = ImportMembersMapping(members, ns, hasWrapperElement, writeAccessors, validate, new RecursionLimiter()); element.Mapping.TypeName = elementName; - element.Namespace = element.Mapping.Namespace == null ? ns : element.Mapping.Namespace; + element.Namespace = element.Mapping.Namespace ?? ns; element.Form = XmlSchemaForm.Qualified; XmlMembersMapping xmlMapping = new XmlMembersMapping(_typeScope, element, access); xmlMapping.IsSoap = true; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapSchemamember.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapSchemamember.cs index 4623bf56bf7dc1..74e9b4a6567ee5 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapSchemamember.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapSchemamember.cs @@ -21,7 +21,7 @@ public XmlQualifiedName? MemberType [AllowNull] public string MemberName { - get { return _memberName == null ? string.Empty : _memberName; } + get { return _memberName ?? string.Empty; } set { _memberName = value; } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapTypeAttribute.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapTypeAttribute.cs index 778fb01ab2b899..0d31f1523476da 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapTypeAttribute.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapTypeAttribute.cs @@ -37,7 +37,7 @@ public bool IncludeInSchema [AllowNull] public string TypeName { - get { return _typeName == null ? string.Empty : _typeName; } + get { return _typeName ?? string.Empty; } set { _typeName = value; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlAnyElementAttribute.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlAnyElementAttribute.cs index d58e05a7298b06..77938f5d24aaca 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlAnyElementAttribute.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlAnyElementAttribute.cs @@ -49,7 +49,7 @@ public XmlAnyElementAttribute(string? name, string? ns) [AllowNull] public string Name { - get { return _name == null ? string.Empty : _name; } + get { return _name ?? string.Empty; } set { _name = value; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlArrayAttribute.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlArrayAttribute.cs index ebad8fd02d3466..9bb144750a6184 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlArrayAttribute.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlArrayAttribute.cs @@ -40,7 +40,7 @@ public XmlArrayAttribute(string? elementName) [AllowNull] public string ElementName { - get { return _elementName == null ? string.Empty : _elementName; } + get { return _elementName ?? string.Empty; } set { _elementName = value; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlArrayItemAttribute.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlArrayItemAttribute.cs index c6f836b736aa83..f741637d21ca2b 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlArrayItemAttribute.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlArrayItemAttribute.cs @@ -69,7 +69,7 @@ public Type? Type [AllowNull] public string ElementName { - get { return _elementName == null ? string.Empty : _elementName; } + get { return _elementName ?? string.Empty; } set { _elementName = value; } } @@ -94,7 +94,7 @@ public int NestingLevel [AllowNull] public string DataType { - get { return _dataType == null ? string.Empty : _dataType; } + get { return _dataType ?? string.Empty; } set { _dataType = value; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlAttributeAttribute.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlAttributeAttribute.cs index 37db81c763a1d0..b1ad042227f67e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlAttributeAttribute.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlAttributeAttribute.cs @@ -66,7 +66,7 @@ public Type? Type [AllowNull] public string AttributeName { - get { return _attributeName == null ? string.Empty : _attributeName; } + get { return _attributeName ?? string.Empty; } set { _attributeName = value; } } @@ -85,7 +85,7 @@ public string? Namespace [AllowNull] public string DataType { - get { return _dataType == null ? string.Empty : _dataType; } + get { return _dataType ?? string.Empty; } set { _dataType = value; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlChoiceIdentifierAttribute.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlChoiceIdentifierAttribute.cs index e29a96cf8579f6..f8d7695be09b8a 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlChoiceIdentifierAttribute.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlChoiceIdentifierAttribute.cs @@ -38,7 +38,7 @@ public XmlChoiceIdentifierAttribute(string? name) [AllowNull] public string MemberName { - get { return _name == null ? string.Empty : _name; } + get { return _name ?? string.Empty; } set { _name = value; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlElementAttribute.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlElementAttribute.cs index a5bfbedaee8f82..7277efd2f097a8 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlElementAttribute.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlElementAttribute.cs @@ -69,7 +69,7 @@ public Type? Type [AllowNull] public string ElementName { - get { return _elementName == null ? string.Empty : _elementName; } + get { return _elementName ?? string.Empty; } set { _elementName = value; } } @@ -88,7 +88,7 @@ public string? Namespace [AllowNull] public string DataType { - get { return _dataType == null ? string.Empty : _dataType; } + get { return _dataType ?? string.Empty; } set { _dataType = value; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlMapping.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlMapping.cs index 3911d54099085e..771dfb76825744 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlMapping.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlMapping.cs @@ -117,7 +117,7 @@ internal static string GenerateKey(Type type, XmlRootAttribute? root, string? ns { root = (XmlRootAttribute?)XmlAttributes.GetAttr(type, typeof(XmlRootAttribute)); } - return $"{type.FullName}:{(root == null ? string.Empty : root.GetKey())}:{(ns == null ? string.Empty : ns)}"; + return $"{type.FullName}:{(root == null ? string.Empty : root.GetKey())}:{ns ?? string.Empty}"; } internal string? Key { get { return _key; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlReflectionImporter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlReflectionImporter.cs index e947009ac7d934..f3fb4eb9fb230b 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlReflectionImporter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlReflectionImporter.cs @@ -594,7 +594,7 @@ internal void SetBase(SerializableMapping mapping, XmlQualifiedName baseQname) XmlSchema s = (XmlSchema)srcSchemas[0]!; XmlSchemaType t = (XmlSchemaType)s.SchemaTypes[baseQname]!; - t = t.Redefined != null ? t.Redefined : t; + t = t.Redefined ?? t; if (_serializables![baseQname] == null) { @@ -1094,7 +1094,7 @@ private ArrayMapping ImportArrayLikeMapping(ArrayModel model, string? ns, Recurs _savedArrayItemAttributes = new XmlArrayItemAttributes(); if (CountAtLevel(_savedArrayItemAttributes, _arrayNestingLevel) == 0) _savedArrayItemAttributes.Add(CreateArrayItemAttribute(_typeScope.GetTypeDesc(model.Element.Type), _arrayNestingLevel)); - CreateArrayElementsFromAttributes(mapping, _savedArrayItemAttributes, model.Element.Type, _savedArrayNamespace == null ? ns : _savedArrayNamespace, limiter); + CreateArrayElementsFromAttributes(mapping, _savedArrayItemAttributes, model.Element.Type, _savedArrayNamespace ?? ns, limiter); SetArrayMappingType(mapping, ns, model.Type); // reconcile accessors now that we have the ArrayMapping namespace @@ -1233,7 +1233,7 @@ private EnumMapping ImportEnumMapping(EnumModel model, string? ns, bool repeats) a.XmlEnum = new XmlEnumAttribute(); ConstantMapping constant = new ConstantMapping(); - constant.XmlName = a.XmlEnum.Name == null ? model.Name : a.XmlEnum.Name; + constant.XmlName = a.XmlEnum.Name ?? model.Name; constant.Name = model.Name; constant.Value = model.Value; return constant; @@ -1502,10 +1502,10 @@ private void CreateArrayElementsFromAttributes(ArrayMapping arrayMapping, XmlArr XmlArrayItemAttribute xmlArrayItem = attributes[i]!; if (xmlArrayItem.NestingLevel != _arrayNestingLevel) continue; - Type targetType = xmlArrayItem.Type != null ? xmlArrayItem.Type : arrayElementType; + Type targetType = xmlArrayItem.Type ?? arrayElementType; TypeDesc targetTypeDesc = _typeScope.GetTypeDesc(targetType); ElementAccessor arrayItemElement = new ElementAccessor(); - arrayItemElement.Namespace = xmlArrayItem.Namespace == null ? arrayElementNs : xmlArrayItem.Namespace; + arrayItemElement.Namespace = xmlArrayItem.Namespace ?? arrayElementNs; arrayItemElement.Mapping = ImportTypeMapping(_modelScope.GetTypeModel(targetType), arrayItemElement.Namespace, ImportContext.Element, xmlArrayItem.DataType, null, limiter); arrayItemElement.Name = xmlArrayItem.ElementName.Length == 0 ? arrayItemElement.Mapping.DefaultElementName : XmlConvert.EncodeLocalName(xmlArrayItem.ElementName); arrayItemElement.IsNullable = xmlArrayItem.GetIsNullableSpecified() ? xmlArrayItem.IsNullable : targetTypeDesc.IsNullable || targetTypeDesc.IsOptionalValue; @@ -1590,7 +1590,7 @@ private void ImportAccessorMapping(MemberMapping accessor, FieldModel model, Xml Type targetType = a.XmlAttribute!.Type == null ? arrayElementType : a.XmlAttribute.Type!; TypeDesc targetTypeDesc = _typeScope.GetTypeDesc(targetType); attribute.Name = Accessor.EscapeQName(a.XmlAttribute.AttributeName.Length == 0 ? accessorName : a.XmlAttribute.AttributeName); - attribute.Namespace = a.XmlAttribute.Namespace == null ? ns : a.XmlAttribute.Namespace; + attribute.Namespace = a.XmlAttribute.Namespace ?? ns; attribute.Form = a.XmlAttribute.Form; if (attribute.Form == XmlSchemaForm.None && ns != attribute.Namespace) { @@ -1618,7 +1618,7 @@ private void ImportAccessorMapping(MemberMapping accessor, FieldModel model, Xml if (a.XmlText != null) { TextAccessor text = new TextAccessor(); - Type targetType = a.XmlText.Type == null ? arrayElementType : a.XmlText.Type; + Type targetType = a.XmlText.Type ?? arrayElementType; TypeDesc targetTypeDesc = _typeScope.GetTypeDesc(targetType); text.Name = accessorName; // unused except to make more helpful error messages text.Mapping = ImportTypeMapping(_modelScope.GetTypeModel(targetType), ns, ImportContext.Text, a.XmlText.DataType, null, true, false, limiter); @@ -1633,11 +1633,11 @@ private void ImportAccessorMapping(MemberMapping accessor, FieldModel model, Xml for (int i = 0; i < a.XmlElements.Count; i++) { XmlElementAttribute xmlElement = a.XmlElements[i]!; - Type targetType = xmlElement.Type == null ? arrayElementType : xmlElement.Type; + Type targetType = xmlElement.Type ?? arrayElementType; TypeDesc targetTypeDesc = _typeScope.GetTypeDesc(targetType); TypeModel typeModel = _modelScope.GetTypeModel(targetType); ElementAccessor element = new ElementAccessor(); - element.Namespace = rpc ? null : xmlElement.Namespace == null ? ns : xmlElement.Namespace; + element.Namespace = rpc ? null : xmlElement.Namespace ?? ns; element.Mapping = ImportTypeMapping(typeModel, rpc ? ns : element.Namespace, ImportContext.Element, xmlElement.DataType, null, limiter); if (a.XmlElements.Count == 1) { @@ -1685,13 +1685,13 @@ private void ImportAccessorMapping(MemberMapping accessor, FieldModel model, Xml continue; } anys[anyName, anyNs] = xmlAnyElement; - if (elements[anyName, (anyNs == null ? ns : anyNs)] != null) + if (elements[anyName, anyNs ?? ns] != null) { - throw new InvalidOperationException(SR.Format(SR.XmlAnyElementDuplicate, accessorName, xmlAnyElement.Name, xmlAnyElement.Namespace == null ? "null" : xmlAnyElement.Namespace)); + throw new InvalidOperationException(SR.Format(SR.XmlAnyElementDuplicate, accessorName, xmlAnyElement.Name, xmlAnyElement.Namespace ?? "null")); } ElementAccessor element = new ElementAccessor(); element.Name = anyName; - element.Namespace = anyNs == null ? ns : anyNs; + element.Namespace = anyNs ?? ns; element.Any = true; element.AnyNamespaces = anyNs; TypeDesc targetTypeDesc = _typeScope.GetTypeDesc(targetType); @@ -1734,7 +1734,7 @@ private void ImportAccessorMapping(MemberMapping accessor, FieldModel model, Xml a.XmlArrayItems.Add(CreateArrayItemAttribute(arrayElementTypeDesc, _arrayNestingLevel)); ElementAccessor arrayElement = new ElementAccessor(); arrayElement.Name = XmlConvert.EncodeLocalName(a.XmlArray.ElementName.Length == 0 ? accessorName : a.XmlArray.ElementName); - arrayElement.Namespace = rpc ? null : a.XmlArray.Namespace == null ? ns : a.XmlArray.Namespace; + arrayElement.Namespace = rpc ? null : a.XmlArray.Namespace ?? ns; _savedArrayItemAttributes = a.XmlArrayItems; _savedArrayNamespace = arrayElement.Namespace; ArrayMapping arrayMapping = ImportArrayLikeMapping(_modelScope.GetArrayModel(accessorType), ns, limiter); @@ -1771,7 +1771,7 @@ private void ImportAccessorMapping(MemberMapping accessor, FieldModel model, Xml if (a.XmlAttribute.Type != null) throw new InvalidOperationException(SR.Format(SR.XmlIllegalType, "XmlAttribute")); AttributeAccessor attribute = new AttributeAccessor(); attribute.Name = Accessor.EscapeQName(a.XmlAttribute.AttributeName.Length == 0 ? accessorName : a.XmlAttribute.AttributeName); - attribute.Namespace = a.XmlAttribute.Namespace == null ? ns : a.XmlAttribute.Namespace; + attribute.Namespace = a.XmlAttribute.Namespace ?? ns; attribute.Form = a.XmlAttribute.Form; if (attribute.Form == XmlSchemaForm.None && ns != attribute.Namespace) { @@ -1816,7 +1816,7 @@ private void ImportAccessorMapping(MemberMapping accessor, FieldModel model, Xml } ElementAccessor element = new ElementAccessor(); element.Name = XmlConvert.EncodeLocalName(xmlElement.ElementName.Length == 0 ? accessorName : xmlElement.ElementName); - element.Namespace = rpc ? null : xmlElement.Namespace == null ? ns : xmlElement.Namespace; + element.Namespace = rpc ? null : xmlElement.Namespace ?? ns; TypeModel typeModel = _modelScope.GetTypeModel(accessorType); element.Mapping = ImportTypeMapping(typeModel, rpc ? ns : element.Namespace, ImportContext.Element, xmlElement.DataType, null, limiter); if (element.Mapping.TypeDesc!.Kind == TypeKind.Node) @@ -1877,11 +1877,11 @@ private void ImportAccessorMapping(MemberMapping accessor, FieldModel model, Xml for (int i = 0; i < a.XmlElements.Count; i++) { XmlElementAttribute xmlElement = a.XmlElements[i]!; - Type targetType = xmlElement.Type == null ? accessorType : xmlElement.Type; + Type targetType = xmlElement.Type ?? accessorType; TypeDesc targetTypeDesc = _typeScope.GetTypeDesc(targetType); ElementAccessor element = new ElementAccessor(); TypeModel typeModel = _modelScope.GetTypeModel(targetType); - element.Namespace = rpc ? null : xmlElement.Namespace == null ? ns : xmlElement.Namespace; + element.Namespace = rpc ? null : xmlElement.Namespace ?? ns; element.Mapping = ImportTypeMapping(typeModel, rpc ? ns : element.Namespace, ImportContext.Element, xmlElement.DataType, null, false, openModel, limiter); if (a.XmlElements.Count == 1) { @@ -1929,13 +1929,13 @@ private void ImportAccessorMapping(MemberMapping accessor, FieldModel model, Xml continue; } anys[anyName, anyNs] = xmlAnyElement; - if (elements[anyName, (anyNs == null ? ns : anyNs)] != null) + if (elements[anyName, anyNs ?? ns] != null) { - throw new InvalidOperationException(SR.Format(SR.XmlAnyElementDuplicate, accessorName, xmlAnyElement.Name, xmlAnyElement.Namespace == null ? "null" : xmlAnyElement.Namespace)); + throw new InvalidOperationException(SR.Format(SR.XmlAnyElementDuplicate, accessorName, xmlAnyElement.Name, xmlAnyElement.Namespace ?? "null")); } ElementAccessor element = new ElementAccessor(); element.Name = anyName; - element.Namespace = anyNs == null ? ns : anyNs; + element.Namespace = anyNs ?? ns; element.Any = true; element.AnyNamespaces = anyNs; TypeDesc targetTypeDesc = _typeScope.GetTypeDesc(targetType); @@ -1991,7 +1991,7 @@ private void ImportAccessorMapping(MemberMapping accessor, FieldModel model, Xml if (element.Any && element.Name.Length == 0) { - string anyNs = element.AnyNamespaces == null ? "##any" : element.AnyNamespaces; + string anyNs = element.AnyNamespaces ?? "##any"; if (xmlName.Substring(0, xmlName.Length - 1) == anyNs) { accessor.ChoiceIdentifier.MemberIds[i] = choiceMapping.Constants[j].Name; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlReflectionMember.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlReflectionMember.cs index d713fbd38e6afa..91164d63e3c5c2 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlReflectionMember.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlReflectionMember.cs @@ -51,7 +51,7 @@ public SoapAttributes SoapAttributes /// public string MemberName { - get { return _memberName == null ? string.Empty : _memberName; } + get { return _memberName ?? string.Empty; } set { _memberName = value; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlRootAttribute.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlRootAttribute.cs index 2813d23ea30eb0..91d58691f85bfe 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlRootAttribute.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlRootAttribute.cs @@ -44,7 +44,7 @@ public XmlRootAttribute(string elementName) /// public string ElementName { - get { return _elementName == null ? string.Empty : _elementName; } + get { return _elementName ?? string.Empty; } set { _elementName = value; } } @@ -63,7 +63,7 @@ public string? Namespace [AllowNull] public string DataType { - get { return _dataType == null ? string.Empty : _dataType; } + get { return _dataType ?? string.Empty; } set { _dataType = value; } } @@ -92,7 +92,7 @@ internal bool GetIsNullableSpecified() internal string Key { - get { return $"{(_ns == null ? string.Empty : _ns)}:{ElementName}:{_nullable}"; } + get { return $"{_ns ?? string.Empty}:{ElementName}:{_nullable}"; } } internal string GetKey() diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemaExporter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemaExporter.cs index 3acfad40a188de..69a156058d0d5d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemaExporter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemaExporter.cs @@ -513,7 +513,7 @@ private XmlQualifiedName ExportNonXsdPrimitiveMapping(PrimitiveMapping mapping, seq.Items.Add(any); type.Particle = seq; string? anyNs = serializableMapping.Schema.TargetNamespace; - any.Namespace = anyNs == null ? "" : anyNs; + any.Namespace = anyNs ?? ""; XmlSchema? existingSchema = _schemas[anyNs]; if (existingSchema == null) { @@ -786,7 +786,7 @@ private void ExportAttributeAccessor(XmlSchemaComplexType type, AttributeAccesso } else { - list.ItemTypeName = ExportPrimitiveMapping(pm, accessor.Namespace == null ? ns : accessor.Namespace); + list.ItemTypeName = ExportPrimitiveMapping(pm, accessor.Namespace ?? ns); } dataType.Content = list; attribute.SchemaType = dataType; @@ -799,7 +799,7 @@ private void ExportAttributeAccessor(XmlSchemaComplexType type, AttributeAccesso } else { - attribute.SchemaTypeName = ExportPrimitiveMapping(pm, accessor.Namespace == null ? ns : accessor.Namespace); + attribute.SchemaTypeName = ExportPrimitiveMapping(pm, accessor.Namespace ?? ns); } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemaImporter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemaImporter.cs index 56591b5d92eadd..fbc15d44dc3754 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemaImporter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemaImporter.cs @@ -1545,7 +1545,7 @@ private void ImportXmlnsDeclarationsMember(XmlSchemaType type, CodeIdentifiers m MemberMapping member = new MemberMapping(); member.Elements = new ElementAccessor[] { xmlns }; - member.Name = CodeIdentifier.MakeValid(xmlnsMemberName == null ? "Namespaces" : xmlnsMemberName); + member.Name = CodeIdentifier.MakeValid(xmlnsMemberName ?? "Namespaces"); member.Name = membersScope.AddUnique(member.Name, member); members.Add(member.Name, member); member.TypeDesc = xmlnsTypeDesc; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReader.cs index 11480e17868bf9..e9a9a7a997e73b 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReader.cs @@ -2145,7 +2145,7 @@ internal Member(XmlSerializationReaderCodeGen outerClass, string source, string? } else { - _arraySource = arraySource == null ? source : arraySource; + _arraySource = arraySource ?? source; _choiceArraySource = _choiceSource; } _mapping = mapping; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReaderILGen.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReaderILGen.cs index d2cca45b10da83..3f52cefcef674c 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReaderILGen.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReaderILGen.cs @@ -106,7 +106,7 @@ internal Member(XmlSerializationReaderILGen outerClass, string source, string? a } else { - _arraySource = arraySource == null ? source : arraySource; + _arraySource = arraySource ?? source; _choiceArraySource = _choiceSource; } _mapping = mapping; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriter.cs index d250d23566290d..11449885a9a6e7 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriter.cs @@ -1365,7 +1365,7 @@ private void WriteReferencedElement(string? name, string? ns, object o, Type? am { TypeEntry? entry = GetTypeEntry(t); if (entry == null) throw CreateUnknownTypeException(t); - WriteStartElement(name.Length == 0 ? entry.typeName! : name!, ns == null ? entry.typeNs : ns, null, true); + WriteStartElement(name.Length == 0 ? entry.typeName! : name!, ns ?? entry.typeNs, null, true); WriteId(o, false); if (ambientType != t) WriteXsiType(entry.typeName!, entry.typeNs); entry.callback!(o); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlTextAttribute.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlTextAttribute.cs index c76ce95e8346a4..2a02292228e0fc 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlTextAttribute.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlTextAttribute.cs @@ -45,7 +45,7 @@ public Type? Type [AllowNull] public string DataType { - get { return _dataType == null ? string.Empty : _dataType; } + get { return _dataType ?? string.Empty; } set { _dataType = value; } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlTypeAttribute.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlTypeAttribute.cs index 5843c35d2f8122..58251d9c2c5f12 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlTypeAttribute.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlTypeAttribute.cs @@ -56,7 +56,7 @@ public bool IncludeInSchema [AllowNull] public string TypeName { - get { return _typeName == null ? string.Empty : _typeName; } + get { return _typeName ?? string.Empty; } set { _typeName = value; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Xmlcustomformatter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Xmlcustomformatter.cs index 4b5c236af79b90..e2d2a962d1f7fb 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Xmlcustomformatter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Xmlcustomformatter.cs @@ -201,7 +201,7 @@ internal static string FromEnum(long val, string[] vals, long[] ids, string? typ if (val != 0) { // failed to parse the enum value - throw new InvalidOperationException(SR.Format(SR.XmlUnknownConstant, originalValue, typeName == null ? "enum" : typeName)); + throw new InvalidOperationException(SR.Format(SR.XmlUnknownConstant, originalValue, typeName ?? "enum")); } if (sb.Length == 0 && iZero >= 0) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/_Events.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/_Events.cs index 2a7cbbc3c2d28e..b0633be8f26f21 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/_Events.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/_Events.cs @@ -60,7 +60,7 @@ public int LinePosition /// public string ExpectedAttributes { - get { return _qnames == null ? string.Empty : _qnames; } + get { return _qnames ?? string.Empty; } } } @@ -108,7 +108,7 @@ public int LinePosition /// public string ExpectedElements { - get { return _qnames == null ? string.Empty : _qnames; } + get { return _qnames ?? string.Empty; } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathException.cs b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathException.cs index 829541715d31dd..c22ec806200d76 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathException.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XPath/XPathException.cs @@ -118,7 +118,7 @@ public override string Message { get { - return (_message == null) ? base.Message : _message; + return _message ?? base.Message; } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XmlException.cs b/src/libraries/System.Private.Xml/src/System/Xml/XmlException.cs index 418dfb17d38f59..a728ab2a164529 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XmlException.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XmlException.cs @@ -272,7 +272,7 @@ public override string Message { get { - return (_message == null) ? base.Message : _message; + return _message ?? base.Message; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/XmlNamespacemanager.cs b/src/libraries/System.Private.Xml/src/System/Xml/XmlNamespacemanager.cs index ad9e88480e29be..5540f60f2a9e5b 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/XmlNamespacemanager.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/XmlNamespacemanager.cs @@ -82,7 +82,7 @@ public virtual string DefaultNamespace get { string? defaultNs = LookupNamespace(string.Empty); - return (defaultNs == null) ? string.Empty : defaultNs; + return defaultNs ?? string.Empty; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilCloneVisitor.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilCloneVisitor.cs index e379522b931206..1029354cda2ccd 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilCloneVisitor.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilCloneVisitor.cs @@ -107,7 +107,7 @@ protected override QilNode VisitChildren(QilNode parent) protected override QilNode VisitReference(QilNode oldNode) { QilNode? newNode = FindClonedReference(oldNode); - return base.VisitReference(newNode == null ? oldNode : newNode); + return base.VisitReference(newNode ?? oldNode); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/WhitespaceRuleReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/WhitespaceRuleReader.cs index 7deb72ba577ab7..2ad5fea1031c50 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/WhitespaceRuleReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/WhitespaceRuleReader.cs @@ -63,7 +63,7 @@ private WhitespaceRuleReader(XmlReader baseReader, WhitespaceRuleLookup wsRules) /// public override string Value { - get { return (_val == null) ? base.Value : _val; } + get { return _val ?? base.Value; } } /// diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlQualifiedNameTest.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlQualifiedNameTest.cs index 11c7986fad96f6..27e31ec1805efb 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlQualifiedNameTest.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XmlQualifiedNameTest.cs @@ -54,7 +54,7 @@ public static XmlQualifiedNameTest New(string? name, string? ns) } else { - return new XmlQualifiedNameTest(name == null ? wildcard : name, ns == null ? wildcard : ns, false); + return new XmlQualifiedNameTest(name ?? wildcard, ns ?? wildcard, false); } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XsltOld/AttributeAction.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XsltOld/AttributeAction.cs index ab9a512dcdff7a..762ec8d1d3f4ae 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XsltOld/AttributeAction.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XsltOld/AttributeAction.cs @@ -34,7 +34,7 @@ internal sealed class AttributeAction : ContainerAction PrefixQName qname = new PrefixQName(); qname.SetQName(name); - qname.Namespace = nsUri != null ? nsUri : manager!.ResolveXPathNamespace(qname.Prefix); + qname.Namespace = nsUri ?? manager!.ResolveXPathNamespace(qname.Prefix); if (qname.Prefix.StartsWith("xml", StringComparison.Ordinal)) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XsltOld/RecordBuilder.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XsltOld/RecordBuilder.cs index 9aed9e0b69edc3..7fa58a6c856cb0 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XsltOld/RecordBuilder.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XsltOld/RecordBuilder.cs @@ -54,7 +54,7 @@ internal RecordBuilder(IRecordOutput output, XmlNameTable? nameTable) { Debug.Assert(output != null); _output = output; - _nameTable = nameTable != null ? nameTable : new NameTable(); + _nameTable = nameTable ?? new NameTable(); _atoms = new OutKeywords(_nameTable); _scopeManager = new OutputScopeManager(_nameTable, _atoms); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XsltOld/SortAction.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XsltOld/SortAction.cs index f6bf402fceaee9..3f46193a3074e5 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XsltOld/SortAction.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XsltOld/SortAction.cs @@ -174,8 +174,7 @@ internal override void Execute(Processor processor, ActionFrame frame) Debug.Assert(processor != null && frame != null); Debug.Assert(frame.State == Initialized); - processor.AddSort(_sort != null ? - _sort : + processor.AddSort(_sort ?? new Sort( _selectKey, _langAvt == null ? _lang : ParseLang(_langAvt.Evaluate(processor, frame)), diff --git a/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Virtual/VirtualPropertyBase.PropertySetterBase.cs b/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Virtual/VirtualPropertyBase.PropertySetterBase.cs index 8642fef1619b99..e62950b3a3d1a0 100644 --- a/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Virtual/VirtualPropertyBase.PropertySetterBase.cs +++ b/src/libraries/System.Reflection.Context/src/System/Reflection/Context/Virtual/VirtualPropertyBase.PropertySetterBase.cs @@ -26,9 +26,7 @@ public sealed override Type ReturnType protected override Type[] GetParameterTypes() { - return (_parameterTypes != null) ? - _parameterTypes : - _parameterTypes = new Type[1] { DeclaringProperty.PropertyType }; + return _parameterTypes ??= new Type[1] { DeclaringProperty.PropertyType }; } } } diff --git a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryObjectReader.cs b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryObjectReader.cs index 20c2b00a447757..94efc7f679fc70 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryObjectReader.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryObjectReader.cs @@ -655,9 +655,7 @@ private void ParseArrayMember(ParseRecord pr) } else { - var = pr._varValue != null ? - pr._varValue : - Converter.FromString(pr._value, pr._dtTypeCode); + var = pr._varValue ?? Converter.FromString(pr._value, pr._dtTypeCode); } if (objectPr._objectA != null) { @@ -680,9 +678,7 @@ private void ParseArrayMember(ParseRecord pr) } else { - object? var = pr._varValue != null ? - pr._varValue : - Converter.FromString(pr._value, objectPr._arrayElementTypeCode); + object? var = pr._varValue ?? Converter.FromString(pr._value, objectPr._arrayElementTypeCode); if (objectPr._objectA != null) { objectPr._objectA[objectPr._indexMap[0]] = var; @@ -820,9 +816,7 @@ private void ParseMember(ParseRecord pr) } else { - object? var = pr._varValue != null ? - pr._varValue : - Converter.FromString(pr._value, pr._dtTypeCode); + object? var = pr._varValue ?? Converter.FromString(pr._value, pr._dtTypeCode); objectPr._objectInfo.AddValue(pr._name, var, ref objectPr._si, ref objectPr._memberData); } } diff --git a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryObjectWriter.cs b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryObjectWriter.cs index bdf952a4ad6fd5..75edd9aa6ca1f1 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryObjectWriter.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryObjectWriter.cs @@ -155,9 +155,8 @@ private void Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo for (int i = 0; i < memberTypes.Length; i++) { Type type = - memberTypes[i] != null ? memberTypes[i] : - memberData[i] != null ? GetType(memberData[i]!) : - Converter.s_typeofObject; + memberTypes[i] ?? (memberData[i] != null ? GetType(memberData[i]!) : + Converter.s_typeofObject); InternalPrimitiveTypeE code = ToCode(type); if ((code == InternalPrimitiveTypeE.Invalid) && diff --git a/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/ACL.cs b/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/ACL.cs index 58d42d4f6cc3cd..945fcc6427ff7e 100644 --- a/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/ACL.cs +++ b/src/libraries/System.Security.AccessControl/src/System/Security/AccessControl/ACL.cs @@ -3062,7 +3062,7 @@ public DiscretionaryAcl(bool isContainer, bool isDS, RawAcl? rawAcl) // internal DiscretionaryAcl(bool isContainer, bool isDS, RawAcl? rawAcl, bool trusted) - : base(isContainer, isDS, rawAcl == null ? new RawAcl(isDS ? AclRevisionDS : AclRevision, 0) : rawAcl, trusted, true) + : base(isContainer, isDS, rawAcl ?? new RawAcl(isDS ? AclRevisionDS : AclRevision, 0), trusted, true) { } diff --git a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedXmlDebugLog.cs b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedXmlDebugLog.cs index 895837406b6b57..0ed69973f3d5c6 100644 --- a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedXmlDebugLog.cs +++ b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedXmlDebugLog.cs @@ -338,7 +338,7 @@ internal static void LogBeginCheckSignedInfo(SignedXml signedXml, SignedInfo sig { string logMessage = SR.Format(CultureInfo.InvariantCulture, SR.Log_CheckSignedInfo, - signedInfo.Id != null ? signedInfo.Id : NullString); + signedInfo.Id ?? NullString); WriteLine(signedXml, TraceEventType.Information, SignedXmlDebugEvent.BeginCheckSignedInfo, logMessage); } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.Windows.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.Windows.cs index efb181f8e6a298..935768067f82b5 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.Windows.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CapiHelper.Windows.cs @@ -109,9 +109,7 @@ internal static string GetDefaultProvider(int dwType) wszUpgrade = UpgradeDSS(dwType, providerNameString); } - return wszUpgrade != null ? - wszUpgrade : // Overwrite the provider name with the upgraded provider name - providerNameString; + return wszUpgrade ?? providerNameString; } /// diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.cs index 244e151372c07f..bc6869bdd0a721 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.cs @@ -305,7 +305,7 @@ stackalloc char[(int)spanLength] : // Already checked to be a size that won't ov set { - string friendlyName = (value == null) ? string.Empty : value; + string friendlyName = value ?? string.Empty; unsafe { IntPtr pFriendlyName = Marshal.StringToHGlobalUni(friendlyName); diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PrincipalPermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PrincipalPermission.cs index 91a3c524c46d3f..848efb5af5907f 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PrincipalPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Permissions/PrincipalPermission.cs @@ -151,12 +151,12 @@ public IPermission Intersect(IPermission target) if (operandIdRole.ID == null || idRole.ID == null || idRole.ID.Equals(operandIdRole.ID)) { - newID = operandIdRole.ID == null ? idRole.ID : operandIdRole.ID; + newID = operandIdRole.ID ?? idRole.ID; addToNewIDRoles = true; } if (operandIdRole.Role == null || idRole.Role == null || idRole.Role.Equals(operandIdRole.Role)) { - newRole = operandIdRole.Role == null ? idRole.Role : operandIdRole.Role; + newRole = operandIdRole.Role ?? idRole.Role; addToNewIDRoles = true; } if (addToNewIDRoles) diff --git a/src/libraries/System.Speech/src/Internal/ObjectToken/ObjectToken.cs b/src/libraries/System.Speech/src/Internal/ObjectToken/ObjectToken.cs index 686d0e1593bc8b..3be89665f3610b 100644 --- a/src/libraries/System.Speech/src/Internal/ObjectToken/ObjectToken.cs +++ b/src/libraries/System.Speech/src/Internal/ObjectToken/ObjectToken.cs @@ -110,7 +110,7 @@ internal RegistryDataKey Attributes { get { - return _attributes != null ? _attributes : (_attributes = OpenKey("Attributes")); + return _attributes ??= OpenKey("Attributes"); } } diff --git a/src/libraries/System.Speech/src/Internal/RBList.cs b/src/libraries/System.Speech/src/Internal/RBList.cs index 353abf50d8093c..faed7c8a397cfc 100644 --- a/src/libraries/System.Speech/src/Internal/RBList.cs +++ b/src/libraries/System.Speech/src/Internal/RBList.cs @@ -237,7 +237,7 @@ private static TreeNode FindSuccessor(TreeNode node) node = node.Parent; } - return node.Parent == null ? null : node.Parent; + return node.Parent ?? null; } else { @@ -410,7 +410,7 @@ private static void FixUpRemoval(TreeNode node) // This node must have at most 1 child Debug.Assert(node.Left == null || node.Right == null); - TreeNode onlyChild = node.Left == null ? node.Right : node.Left; + TreeNode onlyChild = node.Left ?? node.Right; // This node should have been deleted already, and the child has replaced the this node. Debug.Assert(node.Parent == null || node.Parent.Left == onlyChild || node.Parent.Right == onlyChild); diff --git a/src/libraries/System.Speech/src/Internal/SrgsCompiler/BackEnd.cs b/src/libraries/System.Speech/src/Internal/SrgsCompiler/BackEnd.cs index 6d0c8d94f487ce..d3966422063a5f 100644 --- a/src/libraries/System.Speech/src/Internal/SrgsCompiler/BackEnd.cs +++ b/src/libraries/System.Speech/src/Internal/SrgsCompiler/BackEnd.cs @@ -358,7 +358,7 @@ internal Rule FindRule(string sRule) } } - return rule != null ? rule : null; + return rule ?? null; } /// diff --git a/src/libraries/System.Speech/src/Internal/SrgsParser/SrgsDocumentParser.cs b/src/libraries/System.Speech/src/Internal/SrgsParser/SrgsDocumentParser.cs index 66477e9c9cd778..febe5109132eef 100644 --- a/src/libraries/System.Speech/src/Internal/SrgsParser/SrgsDocumentParser.cs +++ b/src/libraries/System.Speech/src/Internal/SrgsParser/SrgsDocumentParser.cs @@ -78,7 +78,7 @@ private void ProcessGrammarElement(SrgsGrammar source, IGrammar grammar) grammar.CodeBehind = source.CodeBehind; grammar.Debug = source.Debug; grammar.ImportNamespaces = source.ImportNamespaces; - grammar.Language = source.Language == null ? "C#" : source.Language; + grammar.Language = source.Language ?? "C#"; grammar.Namespace = source.Namespace; // if add the content to the generic _scrip diff --git a/src/libraries/System.Speech/src/Internal/Synthesis/AudioFormatConverter.cs b/src/libraries/System.Speech/src/Internal/Synthesis/AudioFormatConverter.cs index 819f7c98050359..39c4db1d31e57d 100644 --- a/src/libraries/System.Speech/src/Internal/Synthesis/AudioFormatConverter.cs +++ b/src/libraries/System.Speech/src/Internal/Synthesis/AudioFormatConverter.cs @@ -140,7 +140,7 @@ internal static AudioCodec TypeOf(WAVEFORMATEX format) internal static byte[] ConvertLinear2ULaw(short[] data, int size) { byte[] newData = new byte[size]; - s_uLawCompTableCached = s_uLawCompTableCached == null ? CalcLinear2ULawTable() : s_uLawCompTableCached; + s_uLawCompTableCached ??= CalcLinear2ULawTable(); for (int i = 0; i < size; i++) { @@ -252,7 +252,7 @@ private static byte[] CalcLinear2ULawTable() internal static byte[] ConvertLinear2ALaw(short[] data, int size) { byte[] newData = new byte[size]; - s_aLawCompTableCached = s_aLawCompTableCached == null ? CalcLinear2ALawTable() : s_aLawCompTableCached; + s_aLawCompTableCached ??= CalcLinear2ALawTable(); for (int i = 0; i < size; i++) { @@ -262,6 +262,7 @@ internal static byte[] ConvertLinear2ALaw(short[] data, int size) newData[i] = s_aLawCompTableCached[(ushort)data[i] >> 2]; } } + return newData; } diff --git a/src/libraries/System.Speech/src/Internal/Synthesis/SSmlParser.cs b/src/libraries/System.Speech/src/Internal/Synthesis/SSmlParser.cs index 0ed306da8597eb..11d62a89d2b1b5 100644 --- a/src/libraries/System.Speech/src/Internal/Synthesis/SSmlParser.cs +++ b/src/libraries/System.Speech/src/Internal/Synthesis/SSmlParser.cs @@ -1197,7 +1197,7 @@ private static void ParseVoice(XmlReader reader, ISsmlParser engine, SsmlElement } // Try to change the voice - culture = culture == null ? new CultureInfo(ssmlAttributes._fragmentState.LangId) : culture; + culture ??= new CultureInfo(ssmlAttributes._fragmentState.LangId); bool fNewCulture = culture.LCID != ssmlAttributes._fragmentState.LangId; ssmlAttributes._voice = engine.ProcessVoice(sName, culture, ssmlAttributes._gender, ssmlAttributes._age, variant, fNewCulture, localUnknownNamespaces); ssmlAttributes._fragmentState.LangId = culture.LCID; diff --git a/src/libraries/System.Speech/src/Internal/Synthesis/VoiceSynthesis.cs b/src/libraries/System.Speech/src/Internal/Synthesis/VoiceSynthesis.cs index fb3fd90d052117..53ff9e4d5b2ec3 100644 --- a/src/libraries/System.Speech/src/Internal/Synthesis/VoiceSynthesis.cs +++ b/src/libraries/System.Speech/src/Internal/Synthesis/VoiceSynthesis.cs @@ -536,7 +536,7 @@ internal void RemoveLexicon(Uri uri) /// internal TTSVoice GetEngine(string name, CultureInfo culture, VoiceGender gender, VoiceAge age, int variant, bool switchContext) { - TTSVoice defaultVoice = _currentVoice != null ? _currentVoice : GetVoice(switchContext); + TTSVoice defaultVoice = _currentVoice ?? GetVoice(switchContext); return GetEngineWithVoice(defaultVoice, null, name, culture, gender, age, variant, switchContext); } @@ -758,7 +758,7 @@ private void ThreadProc() List lexicons = new(); //--- Create a single speak info structure for all the text - TTSVoice voice = _currentVoice != null ? _currentVoice : GetVoice(false); + TTSVoice voice = _currentVoice ?? GetVoice(false); //--- Create the speak info SpeakInfo speakInfo = new(this, voice); diff --git a/src/libraries/System.Speech/src/Synthesis/PromptBuilder.cs b/src/libraries/System.Speech/src/Synthesis/PromptBuilder.cs index 9f4b56d5121bc5..4c7c1d19881b8e 100644 --- a/src/libraries/System.Speech/src/Synthesis/PromptBuilder.cs +++ b/src/libraries/System.Speech/src/Synthesis/PromptBuilder.cs @@ -286,7 +286,7 @@ public void StartVoice(VoiceInfo voice) StackElement stackElement = _elementStack.Peek(); ValidateElement(stackElement, SsmlElement.Voice); - CultureInfo culture = voice.Culture == null ? stackElement._culture : voice.Culture; + CultureInfo culture = voice.Culture ?? stackElement._culture; Element startVoice = new(ElementType.StartVoice); startVoice._attributes = new Collection(); diff --git a/src/libraries/System.Speech/src/Synthesis/VoiceInfo.cs b/src/libraries/System.Speech/src/Synthesis/VoiceInfo.cs index c6befbd933692e..d68ccd6cd2cd70 100644 --- a/src/libraries/System.Speech/src/Synthesis/VoiceInfo.cs +++ b/src/libraries/System.Speech/src/Synthesis/VoiceInfo.cs @@ -189,7 +189,7 @@ public string Description { get { - return _description != null ? _description : string.Empty; + return _description ?? string.Empty; } } [EditorBrowsable(EditorBrowsableState.Advanced)] From 077526e9703544b859e4742fc539788fe5aa953a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Fri, 10 Jun 2022 22:35:16 +0900 Subject: [PATCH 035/337] Increase timeout for ARM64 testing (#70551) We're seeing Windows ARM64 workitems being stuck in the Helix queue for more than 90 minutes. --- eng/pipelines/runtime.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index 6e588b348712f9..396660f6f5e73c 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -261,7 +261,7 @@ jobs: isSingleFile: true nameSuffix: NativeAOT buildArgs: -s clr.alljits+clr.tools+clr.nativeaotlibs+clr.nativeaotruntime+libs+libs.tests -c $(_BuildConfig) /p:TestNativeAot=true /p:ArchiveTests=true - timeoutInMinutes: 120 + timeoutInMinutes: 180 # extra steps, run tests extraStepsTemplate: /eng/pipelines/libraries/helix.yml extraStepsParameters: From 3d2702f6044509c46bf2ade81f3afcb2218b9185 Mon Sep 17 00:00:00 2001 From: Qiao Pengcheng Date: Fri, 10 Jun 2022 21:52:53 +0800 Subject: [PATCH 036/337] [LoongArch64] Fixed the compiling error for #69041. (#70544) --- src/coreclr/jit/codegenloongarch64.cpp | 12 ++++++++++++ src/coreclr/jit/emitloongarch64.cpp | 2 +- src/coreclr/jit/emitloongarch64.h | 6 ++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/codegenloongarch64.cpp b/src/coreclr/jit/codegenloongarch64.cpp index 67d64db8c6a821..7f85403db40171 100644 --- a/src/coreclr/jit/codegenloongarch64.cpp +++ b/src/coreclr/jit/codegenloongarch64.cpp @@ -1655,6 +1655,18 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ +//------------------------------------------------------------------------ +// inst_JMP: Generate a jump instruction. +// +void CodeGen::inst_JMP(emitJumpKind jmp, BasicBlock* tgtBlock) +{ +#if !FEATURE_FIXED_OUT_ARGS + assert((tgtBlock->bbTgtStkDepth * sizeof(int) == genStackLevel) || isFramePointerUsed()); +#endif // !FEATURE_FIXED_OUT_ARGS + + GetEmitter()->emitIns_J(emitter::emitJumpKindToIns(jmp), tgtBlock); +} + BasicBlock* CodeGen::genCallFinally(BasicBlock* block) { // Generate a call to the finally, like this: diff --git a/src/coreclr/jit/emitloongarch64.cpp b/src/coreclr/jit/emitloongarch64.cpp index 8e3802123dd5ac..57987606a903c7 100644 --- a/src/coreclr/jit/emitloongarch64.cpp +++ b/src/coreclr/jit/emitloongarch64.cpp @@ -3912,7 +3912,7 @@ static const char* const RegNames[] = void emitter::emitDisInsName(code_t code, const BYTE* addr, instrDesc* id) { - const BYTE* insAdr = addr; + const BYTE* insAdr = addr - writeableOffset; const char* const CFregName[] = {"fcc0", "fcc1", "fcc2", "fcc3", "fcc4", "fcc5", "fcc6", "fcc7"}; unsigned int opcode = (code >> 26) & 0x3f; diff --git a/src/coreclr/jit/emitloongarch64.h b/src/coreclr/jit/emitloongarch64.h index d7e7cc5450acbf..da24986527182c 100644 --- a/src/coreclr/jit/emitloongarch64.h +++ b/src/coreclr/jit/emitloongarch64.h @@ -133,6 +133,12 @@ inline static bool isFloatReg(regNumber reg) return (reg >= REG_FP_FIRST && reg <= REG_FP_LAST); } +/************************************************************************/ +/* Output target-independent instructions */ +/************************************************************************/ + +void emitIns_J(instruction ins, BasicBlock* dst, int instrCount = 0); + /************************************************************************/ /* The public entry points to output instructions */ /************************************************************************/ From e4ac6fa2e4f3de36cd32ed8790dee36ff0a7feaa Mon Sep 17 00:00:00 2001 From: Jan Krivanek Date: Fri, 10 Jun 2022 15:53:10 +0200 Subject: [PATCH 037/337] Fix typo (clr.dll -> mscordacwks.dll) (#70550) --- docs/design/coreclr/botr/dac-notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/design/coreclr/botr/dac-notes.md b/docs/design/coreclr/botr/dac-notes.md index 099807e9d5583c..64cc01fd935e02 100644 --- a/docs/design/coreclr/botr/dac-notes.md +++ b/docs/design/coreclr/botr/dac-notes.md @@ -15,7 +15,7 @@ The DAC infrastructure (the macros and templates that control how host or target When one has no understanding of the DAC, it's easy to find the use of the DAC infrastructure annoying. The `TADDR`s and `PTR_this` and `dac_casts`, etc. seem to clutter the code and make it harder to understand. With just a little work, though, you'll find that these are not really difficult to learn. Keeping host and target addresses explicitly different is really a form of strong typing. The more diligent we are, the easier it becomes to ensure our code is correct. -Because the DAC potentially operates on a dump, the part of the VM sources we build in clr.dll (msdaccore.dll) must be non-invasive. Specifically, we usually don't want to do anything that would cause writing to the target's address space, nor can we execute any code that might cause an immediate garbage collection. (If we can defer the GC, it may be possible to allocate.) Note that the _host_ state is always mutated (temporaries, stack or local heap values); it is only mutating the _target_ space that is problematic. To enforce this, we do two things: code factoring and conditional compilation. In an ideal world, we would factor the VM code so that we would strictly isolate invasive actions in functions that are separate from non-invasive functions. +Because the DAC potentially operates on a dump, the part of the VM sources we build in mscordacwks.dll (msdaccore.dll) must be non-invasive. Specifically, we usually don't want to do anything that would cause writing to the target's address space, nor can we execute any code that might cause an immediate garbage collection. (If we can defer the GC, it may be possible to allocate.) Note that the _host_ state is always mutated (temporaries, stack or local heap values); it is only mutating the _target_ space that is problematic. To enforce this, we do two things: code factoring and conditional compilation. In an ideal world, we would factor the VM code so that we would strictly isolate invasive actions in functions that are separate from non-invasive functions. Unfortunately, we have a large code base, most of which we wrote without ever thinking about the DAC at all. We have a significant number of functions with "find or create" semantics and many other functions that have some parts that just do inspection and other parts that write to the target. Sometimes we control this with a flag passed into the function. This is common in loader code, for example. To avoid having to complete the immense job of refactoring all the VM code before we can use the DAC, we have a second method to prevent executing invasive code from out of process. We have a defined pre-processor constant, `DACCESS_COMPILE` that we use to control what parts of the code we compile into the DAC. We would like to use the `DACCESS_COMPILE` constant as little as we can, so when we DACize a new code path, we prefer to refactor whenever possible. Thus, a function that has "find or create" semantics should become two functions: one that tries to find the information and a wrapper that calls this and creates if the find fails. That way, the DAC code path can call the find function directly and avoid the creation. From 57c88e9e51379bb3d1df8f13257e93c87febe4c1 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Fri, 10 Jun 2022 10:17:24 -0400 Subject: [PATCH 038/337] Fix async handle leak when sync RandomAccess read/write on async handle fails (#69956) * Fix async handle leak when sync RandomAccess read/write on async handle fails * Use UnsafeAllocateNativeOverlapped in GetNativeOverlappedForAsyncHandle This isn't invoking user code and it's entirely for synchronous operations; there's no reason it needs to capture ExecutionContext. --- .../src/System/IO/RandomAccess.Windows.cs | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/RandomAccess.Windows.cs b/src/libraries/System.Private.CoreLib/src/System/IO/RandomAccess.Windows.cs index 234782b022c5bc..6a338378ed483d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/RandomAccess.Windows.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/RandomAccess.Windows.cs @@ -104,6 +104,14 @@ private static unsafe int ReadSyncUsingAsyncHandle(SafeFileHandle handle, Span fileHandle.IsNoBuffering && fileHandle.CanSeek && fileOffset >= fileHandle.GetFileLength(); - // We need to store the reference count (see the comment in FreeNativeOverlappedIfItIsSafe) and an EventHandle to signal the completion. + // We need to store the reference count (see the comment in ReleaseRefCount) and an EventHandle to signal the completion. // We could keep these two things separate, but since ManualResetEvent is sealed and we want to avoid any extra allocations, this type has been created. // It's basically ManualResetEvent with reference count. private sealed class CallbackResetEvent : EventWaitHandle @@ -780,7 +796,7 @@ internal CallbackResetEvent(ThreadPoolBoundHandle threadPoolBoundHandle) : base( _threadPoolBoundHandle = threadPoolBoundHandle; } - internal unsafe void FreeNativeOverlapped(NativeOverlapped* pOverlapped) + internal unsafe void ReleaseRefCount(NativeOverlapped* pOverlapped) { // Each SafeFileHandle opened for async IO is bound to ThreadPool. // It requires us to provide a callback even if we want to use EventHandle and use GetOverlappedResult to obtain the result. From 5786435b4fcc7cf6cf1503e1aa932ce4a17a0acd Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Fri, 10 Jun 2022 07:31:43 -0700 Subject: [PATCH 039/337] Updating the various generic math functions to have default implementations (#70445) * Updating the various generic math functions to have default implementations * Ensure GenericMathHelpers keep the right constraints --- .../Common/tests/System/GenericMathHelpers.cs | 12 +- .../System.Private.CoreLib/src/System/Byte.cs | 3 - .../System.Private.CoreLib/src/System/Char.cs | 31 ---- .../src/System/Decimal.cs | 49 ------ .../src/System/Double.cs | 21 --- .../System.Private.CoreLib/src/System/Half.cs | 21 --- .../src/System/Int16.cs | 3 - .../src/System/Int32.cs | 3 - .../src/System/Int64.cs | 3 - .../src/System/IntPtr.cs | 3 - .../src/System/Numerics/IAdditionOperators.cs | 2 +- .../src/System/Numerics/IBinaryInteger.cs | 30 +++- .../System/Numerics/IDecrementOperators.cs | 2 +- .../src/System/Numerics/IDivisionOperators.cs | 2 +- .../System/Numerics/IExponentialFunctions.cs | 8 +- .../src/System/Numerics/IFloatingPoint.cs | 12 +- .../System/Numerics/IFloatingPointIeee754.cs | 4 +- .../System/Numerics/IHyperbolicFunctions.cs | 2 +- .../System/Numerics/IIncrementOperators.cs | 2 +- .../System/Numerics/ILogarithmicFunctions.cs | 8 +- .../src/System/Numerics/IMultiplyOperators.cs | 2 +- .../src/System/Numerics/INumber.cs | 115 +++++++++++++- .../src/System/Numerics/INumberBase.cs | 6 +- .../src/System/Numerics/IPowerFunctions.cs | 2 +- .../src/System/Numerics/IRootFunctions.cs | 2 +- .../System/Numerics/ISubtractionOperators.cs | 2 +- .../Numerics/ITrigonometricFunctions.cs | 2 +- .../Numerics/IUnaryNegationOperators.cs | 2 +- .../System/Runtime/InteropServices/NFloat.cs | 49 ------ .../src/System/SByte.cs | 3 - .../src/System/Single.cs | 21 --- .../src/System/UInt16.cs | 3 - .../src/System/UInt32.cs | 3 - .../src/System/UInt64.cs | 3 - .../src/System/UIntPtr.cs | 3 - .../ref/System.Runtime.Numerics.cs | 26 +--- .../src/System/Numerics/BigInteger.cs | 49 ------ .../src/System/Numerics/Complex.cs | 41 ----- .../System.Runtime/ref/System.Runtime.cs | 143 ++++++------------ 39 files changed, 224 insertions(+), 474 deletions(-) diff --git a/src/libraries/Common/tests/System/GenericMathHelpers.cs b/src/libraries/Common/tests/System/GenericMathHelpers.cs index c6bbb21304f2ed..f6852bd5a170e8 100644 --- a/src/libraries/Common/tests/System/GenericMathHelpers.cs +++ b/src/libraries/Common/tests/System/GenericMathHelpers.cs @@ -113,7 +113,7 @@ public static class EqualityOperatorsHelper } public static class ExponentialFunctionsHelper - where TSelf : IExponentialFunctions + where TSelf : IExponentialFunctions, INumberBase { public static TSelf Exp(TSelf x) => TSelf.Exp(x); @@ -223,7 +223,7 @@ public static class FloatingPointIeee754Helper } public static class HyperbolicFunctionsHelper - where TSelf : IHyperbolicFunctions + where TSelf : IHyperbolicFunctions, INumberBase { public static TSelf Acosh(TSelf x) => TSelf.Acosh(x); @@ -247,7 +247,7 @@ public static class IncrementOperatorsHelper } public static class LogarithmicFunctionsHelper - where TSelf : ILogarithmicFunctions + where TSelf : ILogarithmicFunctions, INumberBase { public static TSelf Log(TSelf x) => TSelf.Log(x); @@ -390,13 +390,13 @@ public static class ParsableHelper } public static class PowerFunctionsHelper - where TSelf : IPowerFunctions + where TSelf : IPowerFunctions, INumberBase { public static TSelf Pow(TSelf x, TSelf y) => TSelf.Pow(x, y); } public static class RootFunctionsHelper - where TSelf : IRootFunctions + where TSelf : IRootFunctions, INumberBase { public static TSelf Cbrt(TSelf x) => TSelf.Cbrt(x); @@ -436,7 +436,7 @@ public static class SubtractionOperatorsHelper } public static class TrigonometricFunctionsHelper - where TSelf : ITrigonometricFunctions + where TSelf : ITrigonometricFunctions, INumberBase { public static TSelf Acos(TSelf x) => TSelf.Acos(x); diff --git a/src/libraries/System.Private.CoreLib/src/System/Byte.cs b/src/libraries/System.Private.CoreLib/src/System/Byte.cs index f8bf9347ec5c16..e850444f84ea89 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Byte.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Byte.cs @@ -433,9 +433,6 @@ bool IBinaryInteger.TryWriteLittleEndian(Span destination, out int b /// static byte IDivisionOperators.operator /(byte left, byte right) => (byte)(left / right); - /// - static byte IDivisionOperators.operator checked /(byte left, byte right) => (byte)(left / right); - // // IEqualityOperators // diff --git a/src/libraries/System.Private.CoreLib/src/System/Char.cs b/src/libraries/System.Private.CoreLib/src/System/Char.cs index fa100bbb36e381..9309a28a1ba2ec 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Char.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Char.cs @@ -1165,9 +1165,6 @@ public static int ConvertToUtf32(string s, int index) // IBinaryInteger // - /// - static (char Quotient, char Remainder) IBinaryInteger.DivRem(char left, char right) => ((char, char))Math.DivRem(left, right); - /// static char IBinaryInteger.LeadingZeroCount(char value) => (char)(BitOperations.LeadingZeroCount(value) - 16); @@ -1284,9 +1281,6 @@ bool IBinaryInteger.TryWriteLittleEndian(Span destination, out int b /// static char IDivisionOperators.operator /(char left, char right) => (char)(left / right); - /// - static char IDivisionOperators.operator checked /(char left, char right) => (char)(left / right); - // // IEqualityOperators // @@ -1341,31 +1335,6 @@ bool IBinaryInteger.TryWriteLittleEndian(Span destination, out int b /// static char IMultiplyOperators.operator checked *(char left, char right) => checked((char)(left * right)); - // - // INumber - // - - /// - static char INumber.Clamp(char value, char min, char max) => (char)Math.Clamp(value, min, max); - - /// - static char INumber.CopySign(char value, char sign) => value; - - /// - static char INumber.Max(char x, char y) => (char)Math.Max(x, y); - - /// - static char INumber.MaxNumber(char x, char y) => (char)Math.Max(x, y); - - /// - static char INumber.Min(char x, char y) => (char)Math.Min(x, y); - - /// - static char INumber.MinNumber(char x, char y) => (char)Math.Min(x, y); - - /// - static int INumber.Sign(char value) => (value == 0) ? 0 : 1; - // // INumberBase // diff --git a/src/libraries/System.Private.CoreLib/src/System/Decimal.cs b/src/libraries/System.Private.CoreLib/src/System/Decimal.cs index fdad839460d8fb..161da75bcb9304 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Decimal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Decimal.cs @@ -1118,13 +1118,6 @@ object IConvertible.ToType(Type type, IFormatProvider? provider) return Convert.DefaultToType((IConvertible)this, type, provider); } - // - // IAdditionOperators - // - - /// - static decimal IAdditionOperators.operator checked +(decimal left, decimal right) => left + right; - // // IAdditiveIdentity // @@ -1132,20 +1125,6 @@ object IConvertible.ToType(Type type, IFormatProvider? provider) /// static decimal IAdditiveIdentity.AdditiveIdentity => AdditiveIdentity; - // - // IDecrementOperators - // - - /// - static decimal IDecrementOperators.operator checked --(decimal value) => --value; - - // - // IDivisionOperators - // - - /// - static decimal IDivisionOperators.operator checked /(decimal left, decimal right) => left / right; - // // IFloatingPoint // @@ -1260,13 +1239,6 @@ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destinat } } - // - // IIncrementOperators - // - - /// - static decimal IIncrementOperators.operator checked ++(decimal value) => ++value; - // // IMinMaxValue // @@ -1284,13 +1256,6 @@ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destinat /// static decimal IMultiplicativeIdentity.MultiplicativeIdentity => MultiplicativeIdentity; - // - // IMultiplyOperators - // - - /// - public static decimal operator checked *(decimal left, decimal right) => left * right; - // // INumber // @@ -1792,19 +1757,5 @@ private static bool TryConvertTo(decimal value, [NotNullWhen(true)] out /// public static bool TryParse(ReadOnlySpan s, IFormatProvider? provider, out decimal result) => TryParse(s, NumberStyles.Number, provider, out result); - - // - // ISubtractionOperators - // - - /// - static decimal ISubtractionOperators.operator checked -(decimal left, decimal right) => left - right; - - // - // IUnaryNegationOperators - // - - /// - static decimal IUnaryNegationOperators.operator checked -(decimal value) => -value; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Double.cs b/src/libraries/System.Private.CoreLib/src/System/Double.cs index 1655435fbeae4f..aee762bb058b37 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Double.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Double.cs @@ -532,9 +532,6 @@ object IConvertible.ToType(Type type, IFormatProvider? provider) /// static double IAdditionOperators.operator +(double left, double right) => left + right; - /// - static double IAdditionOperators.operator checked +(double left, double right) => left + right; - // // IAdditiveIdentity // @@ -601,9 +598,6 @@ public static bool IsPow2(double value) /// static double IDecrementOperators.operator --(double value) => --value; - /// - static double IDecrementOperators.operator checked --(double value) => --value; - // // IDivisionOperators // @@ -611,9 +605,6 @@ public static bool IsPow2(double value) /// static double IDivisionOperators.operator /(double left, double right) => left / right; - /// - static double IDivisionOperators.operator checked /(double left, double right) => left / right; - // // IExponentialFunctions // @@ -865,9 +856,6 @@ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destinati /// static double IIncrementOperators.operator ++(double value) => ++value; - /// - static double IIncrementOperators.operator checked ++(double value) => ++value; - // // ILogarithmicFunctions // @@ -921,9 +909,6 @@ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destinati /// static double IMultiplyOperators.operator *(double left, double right) => left * right; - /// - static double IMultiplyOperators.operator checked *(double left, double right) => left * right; - // // INumber // @@ -1401,9 +1386,6 @@ private static bool TryConvertTo(double value, [NotNullWhen(true)] out T /// static double ISubtractionOperators.operator -(double left, double right) => left - right; - /// - static double ISubtractionOperators.operator checked -(double left, double right) => left - right; - // // ITrigonometricFunctions // @@ -1460,9 +1442,6 @@ private static bool TryConvertTo(double value, [NotNullWhen(true)] out T /// static double IUnaryNegationOperators.operator -(double value) => -value; - /// - static double IUnaryNegationOperators.operator checked -(double value) => -value; - // // IUnaryPlusOperators // diff --git a/src/libraries/System.Private.CoreLib/src/System/Half.cs b/src/libraries/System.Private.CoreLib/src/System/Half.cs index 059299f5effb5e..7e18eac88f491f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Half.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Half.cs @@ -998,9 +998,6 @@ private static double CreateDoubleNaN(bool sign, ulong significand) /// public static Half operator +(Half left, Half right) => (Half)((float)left + (float)right); - /// - static Half IAdditionOperators.operator checked +(Half left, Half right) => left + right; - // // IAdditiveIdentity // @@ -1072,9 +1069,6 @@ public static bool IsPow2(Half value) return (Half)tmp; } - /// - static Half IDecrementOperators.operator checked --(Half value) => --value; - // // IDivisionOperators // @@ -1082,9 +1076,6 @@ public static bool IsPow2(Half value) /// public static Half operator /(Half left, Half right) => (Half)((float)left / (float)right); - /// - static Half IDivisionOperators.operator checked /(Half left, Half right) => left / right; - // // IExponentialFunctions // @@ -1317,9 +1308,6 @@ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destination return (Half)tmp; } - /// - static Half IIncrementOperators.operator checked ++(Half value) => ++value; - // // ILogarithmicFunctions // @@ -1363,9 +1351,6 @@ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destination /// public static Half operator *(Half left, Half right) => (Half)((float)left * (float)right); - /// - static Half IMultiplyOperators.operator checked *(Half left, Half right) => left * right; - // // INumber // @@ -1836,9 +1821,6 @@ private static bool TryConvertTo(Half value, [NotNullWhen(true)] out TOt /// public static Half operator -(Half left, Half right) => (Half)((float)left - (float)right); - /// - static Half ISubtractionOperators.operator checked -(Half left, Half right) => left - right; - // // ITrigonometricFunctions // @@ -1899,9 +1881,6 @@ public static (Half Sin, Half Cos) SinCos(Half x) /// public static Half operator -(Half value) => (Half)(-(float)value); - /// - static Half IUnaryNegationOperators.operator checked -(Half value) => -value; - // // IUnaryPlusOperators // diff --git a/src/libraries/System.Private.CoreLib/src/System/Int16.cs b/src/libraries/System.Private.CoreLib/src/System/Int16.cs index 75025b7a59732e..cadd004979a86a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Int16.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Int16.cs @@ -459,9 +459,6 @@ public static short Log2(short value) /// static short IDivisionOperators.operator /(short left, short right) => (short)(left / right); - /// - static short IDivisionOperators.operator checked /(short left, short right) => (short)(left / right); - // // IEqualityOperators // diff --git a/src/libraries/System.Private.CoreLib/src/System/Int32.cs b/src/libraries/System.Private.CoreLib/src/System/Int32.cs index b40fedc2636b50..0c837a367c5915 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Int32.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Int32.cs @@ -451,9 +451,6 @@ public static int Log2(int value) /// static int IDivisionOperators.operator /(int left, int right) => left / right; - /// - static int IDivisionOperators.operator checked /(int left, int right) => left / right; - // // IEqualityOperators // diff --git a/src/libraries/System.Private.CoreLib/src/System/Int64.cs b/src/libraries/System.Private.CoreLib/src/System/Int64.cs index 0c7fa4a26d3f30..e6d014edb99f8c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Int64.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Int64.cs @@ -438,9 +438,6 @@ public static long Log2(long value) /// static long IDivisionOperators.operator /(long left, long right) => left / right; - /// - static long IDivisionOperators.operator checked /(long left, long right) => left / right; - // // IEqualityOperators // diff --git a/src/libraries/System.Private.CoreLib/src/System/IntPtr.cs b/src/libraries/System.Private.CoreLib/src/System/IntPtr.cs index 9d3e923096b907..822fb356b2ec6b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IntPtr.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IntPtr.cs @@ -421,9 +421,6 @@ public static nint Log2(nint value) /// static nint IDivisionOperators.operator /(nint left, nint right) => left / right; - /// - static nint IDivisionOperators.operator checked /(nint left, nint right) => left / right; - // // IIncrementOperators // diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/IAdditionOperators.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/IAdditionOperators.cs index 2a23b40648fce1..ca11868381a295 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/IAdditionOperators.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/IAdditionOperators.cs @@ -21,6 +21,6 @@ public interface IAdditionOperators /// The value which is added to . /// The sum of and . /// The sum of and is not representable by . - static abstract TResult operator checked +(TSelf left, TOther right); + static virtual TResult operator checked +(TSelf left, TOther right) => left + right; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/IBinaryInteger.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/IBinaryInteger.cs index eb77b66f9a87df..400848f8c953f8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/IBinaryInteger.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/IBinaryInteger.cs @@ -14,12 +14,26 @@ public interface IBinaryInteger /// The value which divides. /// The value which divides . /// The quotient and remainder of divided-by . - static abstract (TSelf Quotient, TSelf Remainder) DivRem(TSelf left, TSelf right); + static virtual (TSelf Quotient, TSelf Remainder) DivRem(TSelf left, TSelf right) + { + TSelf quotient = left / right; + return (quotient, (left - (quotient * right))); + } /// Computes the number of leading zeros in a value. /// The value whose leading zeroes are to be counted. /// The number of leading zeros in . - static abstract TSelf LeadingZeroCount(TSelf value); + static virtual TSelf LeadingZeroCount(TSelf value) + { + TSelf bitCount = TSelf.CreateChecked(value.GetByteCount() * 8L); + + if (value == TSelf.Zero) + { + return TSelf.CreateChecked(bitCount); + } + + return (bitCount - TSelf.One) ^ TSelf.Log2(value); + } /// Computes the number of bits that are set in a value. /// The value whose set bits are to be counted. @@ -30,13 +44,21 @@ public interface IBinaryInteger /// The value which is rotated left by . /// The amount by which is rotated left. /// The result of rotating left by . - static abstract TSelf RotateLeft(TSelf value, int rotateAmount); + static virtual TSelf RotateLeft(TSelf value, int rotateAmount) + { + int bitCount = checked(value.GetByteCount() * 8); + return (value << rotateAmount) | (value >> (bitCount - rotateAmount)); + } /// Rotates a value right by a given amount. /// The value which is rotated right by . /// The amount by which is rotated right. /// The result of rotating right by . - static abstract TSelf RotateRight(TSelf value, int rotateAmount); + static virtual TSelf RotateRight(TSelf value, int rotateAmount) + { + int bitCount = checked(value.GetByteCount() * 8); + return (value >> rotateAmount) | (value << (bitCount - rotateAmount)); + } /// Computes the number of trailing zeros in a value. /// The value whose trailing zeroes are to be counted. diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/IDecrementOperators.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/IDecrementOperators.cs index 49ad93519f5c24..159ad6bc44e2dc 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/IDecrementOperators.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/IDecrementOperators.cs @@ -17,6 +17,6 @@ public interface IDecrementOperators /// The value to decrement. /// The result of decrementing . /// The result of decrementing is not representable by . - static abstract TSelf operator checked --(TSelf value); + static virtual TSelf operator checked --(TSelf value) => --value; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/IDivisionOperators.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/IDivisionOperators.cs index 4c5548920c6da5..a8ed07a6335910 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/IDivisionOperators.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/IDivisionOperators.cs @@ -21,6 +21,6 @@ public interface IDivisionOperators /// The value which divides . /// The quotient of divided-by . /// The quotient of divided-by is not representable by . - static abstract TResult operator checked /(TSelf left, TOther right); + static virtual TResult operator checked /(TSelf left, TOther right) => left / right; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/IExponentialFunctions.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/IExponentialFunctions.cs index bc5a08ae7057c1..f24b2ce6ae49ef 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/IExponentialFunctions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/IExponentialFunctions.cs @@ -6,7 +6,7 @@ namespace System.Numerics /// Defines support for exponential functions. /// The type that implements this interface. public interface IExponentialFunctions - where TSelf : IExponentialFunctions + where TSelf : IExponentialFunctions, INumberBase { /// Computes E raised to a given power. /// The power to which E is raised. @@ -16,7 +16,7 @@ public interface IExponentialFunctions /// Computes E raised to a given power and subtracts one. /// The power to which E is raised. /// E - 1 - static abstract TSelf ExpM1(TSelf x); + static virtual TSelf ExpM1(TSelf x) => TSelf.Exp(x) - TSelf.One; /// Computes 2 raised to a given power. /// The power to which 2 is raised. @@ -26,7 +26,7 @@ public interface IExponentialFunctions /// Computes 2 raised to a given power and subtracts one. /// The power to which 2 is raised. /// 2 - 1 - static abstract TSelf Exp2M1(TSelf x); + static virtual TSelf Exp2M1(TSelf x) => TSelf.Exp2(x) - TSelf.One; /// Computes 10 raised to a given power. /// The power to which 10 is raised. @@ -36,6 +36,6 @@ public interface IExponentialFunctions /// Computes 10 raised to a given power and subtracts one. /// The power to which 10 is raised. /// 10 - 1 - static abstract TSelf Exp10M1(TSelf x); + static virtual TSelf Exp10M1(TSelf x) => TSelf.Exp10M1(x) - TSelf.One; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/IFloatingPoint.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/IFloatingPoint.cs index 5ea7beaeb39ebc..48b0bfdc39fd43 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/IFloatingPoint.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/IFloatingPoint.cs @@ -13,29 +13,29 @@ public interface IFloatingPoint /// Computes the ceiling of a value. /// The value whose ceiling is to be computed. /// The ceiling of . - static abstract TSelf Ceiling(TSelf x); + static virtual TSelf Ceiling(TSelf x) => TSelf.Round(x, digits: 0, MidpointRounding.ToPositiveInfinity); /// Computes the floor of a value. /// The value whose floor is to be computed. /// The floor of . - static abstract TSelf Floor(TSelf x); + static virtual TSelf Floor(TSelf x) => TSelf.Round(x, digits: 0, MidpointRounding.ToNegativeInfinity); /// Rounds a value to the nearest integer using the default rounding mode (). /// The value to round. /// The result of rounding to the nearest integer using the default rounding mode. - static abstract TSelf Round(TSelf x); + static virtual TSelf Round(TSelf x) => TSelf.Round(x, digits: 0, MidpointRounding.ToEven); /// Rounds a value to a specified number of fractional-digits using the default rounding mode (). /// The value to round. /// The number of fractional digits to which should be rounded. /// The result of rounding to fractional-digits using the default rounding mode. - static abstract TSelf Round(TSelf x, int digits); + static virtual TSelf Round(TSelf x, int digits) => TSelf.Round(x, digits, MidpointRounding.ToEven); /// Rounds a value to the nearest integer using the specified rounding mode. /// The value to round. /// The mode under which should be rounded. /// The result of rounding to the nearest integer using . - static abstract TSelf Round(TSelf x, MidpointRounding mode); + static virtual TSelf Round(TSelf x, MidpointRounding mode) => TSelf.Round(x, digits: 0, MidpointRounding.ToEven); /// Rounds a value to a specified number of fractional-digits using the default rounding mode (). /// The value to round. @@ -47,7 +47,7 @@ public interface IFloatingPoint /// Truncates a value. /// The value to truncate. /// The truncation of . - static abstract TSelf Truncate(TSelf x); + static virtual TSelf Truncate(TSelf x) => TSelf.Round(x, digits: 0, MidpointRounding.ToZero); /// Gets the number of bytes that will be written as part of . /// The number of bytes that will be written as part of . diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/IFloatingPointIeee754.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/IFloatingPointIeee754.cs index 101488459c718b..97ae0ef3852e5d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/IFloatingPointIeee754.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/IFloatingPointIeee754.cs @@ -70,12 +70,12 @@ public interface IFloatingPointIeee754 /// Computes an estimate of the reciprocal of a value. /// The value whose estimate of the reciprocal is to be computed. /// An estimate of the reciprocal of . - static abstract TSelf ReciprocalEstimate(TSelf x); + static virtual TSelf ReciprocalEstimate(TSelf x) => TSelf.One / x; /// Computes an estimate of the reciprocal square root of a value. /// The value whose estimate of the reciprocal square root is to be computed. /// An estimate of the reciprocal square root of . - static abstract TSelf ReciprocalSqrtEstimate(TSelf x); + static virtual TSelf ReciprocalSqrtEstimate(TSelf x) => TSelf.One / TSelf.Sqrt(x); /// Computes the product of a value and its base-radix raised to the specified power. /// The value which base-radix raised to the power of multiplies. diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/IHyperbolicFunctions.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/IHyperbolicFunctions.cs index d4b8f4a0115626..0f7ad9ccd06811 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/IHyperbolicFunctions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/IHyperbolicFunctions.cs @@ -6,7 +6,7 @@ namespace System.Numerics /// Defines support for hyperbolic functions. /// The type that implements this interface. public interface IHyperbolicFunctions - where TSelf : IHyperbolicFunctions + where TSelf : IHyperbolicFunctions, INumberBase { /// Computes the hyperbolic arc-cosine of a value. /// The value, in radians, whose hyperbolic arc-cosine is to be computed. diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/IIncrementOperators.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/IIncrementOperators.cs index 3dd705603e4733..9024a4a6615ace 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/IIncrementOperators.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/IIncrementOperators.cs @@ -17,6 +17,6 @@ public interface IIncrementOperators /// The value to increment. /// The result of incrementing . /// The result of incrementing is not representable by . - static abstract TSelf operator checked ++(TSelf value); + static virtual TSelf operator checked ++(TSelf value) => ++value; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/ILogarithmicFunctions.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/ILogarithmicFunctions.cs index c27e1230ccf288..cbd259ffcb4220 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/ILogarithmicFunctions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/ILogarithmicFunctions.cs @@ -6,7 +6,7 @@ namespace System.Numerics /// Defines support for logarithmic functions. /// The type that implements this interface. public interface ILogarithmicFunctions - where TSelf : ILogarithmicFunctions + where TSelf : ILogarithmicFunctions, INumberBase { /// Computes the natural (base-E) logarithm of a value. /// The value whose natural logarithm is to be computed. @@ -22,7 +22,7 @@ public interface ILogarithmicFunctions /// Computes the natural (base-E) logarithm of a value plus one. /// The value to which one is added before computing the natural logarithm. /// loge( + 1) - static abstract TSelf LogP1(TSelf x); + static virtual TSelf LogP1(TSelf x) => TSelf.Log(x + TSelf.One); /// Computes the base-2 logarithm of a value. /// The value whose base-2 logarithm is to be computed. @@ -32,7 +32,7 @@ public interface ILogarithmicFunctions /// Computes the base-2 logarithm of a value plus one. /// The value to which one is added before computing the base-2 logarithm. /// log2( + 1) - static abstract TSelf Log2P1(TSelf x); + static virtual TSelf Log2P1(TSelf x) => TSelf.Log2(x + TSelf.One); /// Computes the base-10 logarithm of a value. /// The value whose base-10 logarithm is to be computed. @@ -42,6 +42,6 @@ public interface ILogarithmicFunctions /// Computes the base-10 logarithm of a value plus one. /// The value to which one is added before computing the base-10 logarithm. /// log10( + 1) - static abstract TSelf Log10P1(TSelf x); + static virtual TSelf Log10P1(TSelf x) => TSelf.Log10(x + TSelf.One); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/IMultiplyOperators.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/IMultiplyOperators.cs index 24a2a41470c98d..a3e4d52ec42b81 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/IMultiplyOperators.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/IMultiplyOperators.cs @@ -21,6 +21,6 @@ public interface IMultiplyOperators /// The value which multiplies . /// The product of divided-by . /// The product of multiplied-by is not representable by . - static abstract TResult operator checked *(TSelf left, TOther right); + static virtual TResult operator checked *(TSelf left, TOther right) => left * right; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/INumber.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/INumber.cs index 0d5fbd0c13e449..ebf5e75d388c63 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/INumber.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/INumber.cs @@ -20,46 +20,147 @@ public interface INumber /// The inclusive maximum to which should clamp. /// The result of clamping to the inclusive range of and . /// is greater than . - static abstract TSelf Clamp(TSelf value, TSelf min, TSelf max); + static virtual TSelf Clamp(TSelf value, TSelf min, TSelf max) + { + if (min > max) + { + Math.ThrowMinMaxException(min, max); + } + + TSelf result = value; + + result = TSelf.Max(result, min); + result = TSelf.Min(result, max); + + return result; + } /// Copies the sign of a value to the sign of another value.. /// The value whose magnitude is used in the result. /// The value whose sign is used in the result. /// A value with the magnitude of and the sign of . - static abstract TSelf CopySign(TSelf value, TSelf sign); + static virtual TSelf CopySign(TSelf value, TSelf sign) + { + TSelf result = value; + + if (TSelf.IsNegative(value) != TSelf.IsNegative(sign)) + { + result = checked(-result); + } + + return result; + } /// Compares two values to compute which is greater. /// The value to compare with . /// The value to compare with . /// if it is greater than ; otherwise, . /// For this method matches the IEEE 754:2019 maximum function. This requires NaN inputs to be propagated back to the caller and for -0.0 to be treated as less than +0.0. - static abstract TSelf Max(TSelf x, TSelf y); + static virtual TSelf Max(TSelf x, TSelf y) + { + // This matches the IEEE 754:2019 `maximum` function + // + // It propagates NaN inputs back to the caller and + // otherwise returns the larger of the inputs. It + // treats +0 as larger than -0 as per the specification. + + if (x != y) + { + if (!TSelf.IsNaN(x)) + { + return y < x ? x : y; + } + + return x; + } + + return TSelf.IsNegative(y) ? x : y; + } /// Compares two values to compute which is greater and returning the other value if an input is NaN. /// The value to compare with . /// The value to compare with . /// if it is greater than ; otherwise, . /// For this method matches the IEEE 754:2019 maximumNumber function. This requires NaN inputs to not be propagated back to the caller and for -0.0 to be treated as less than +0.0. - static abstract TSelf MaxNumber(TSelf x, TSelf y); + static virtual TSelf MaxNumber(TSelf x, TSelf y) + { + // This matches the IEEE 754:2019 `maximumNumber` function + // + // It does not propagate NaN inputs back to the caller and + // otherwise returns the larger of the inputs. It + // treats +0 as larger than -0 as per the specification. + + if (x != y) + { + if (!TSelf.IsNaN(y)) + { + return y < x ? x : y; + } + + return x; + } + + return TSelf.IsNegative(y) ? x : y; + } /// Compares two values to compute which is lesser. /// The value to compare with . /// The value to compare with . /// if it is less than ; otherwise, . /// For this method matches the IEEE 754:2019 minimum function. This requires NaN inputs to be propagated back to the caller and for -0.0 to be treated as less than +0.0. - static abstract TSelf Min(TSelf x, TSelf y); + static virtual TSelf Min(TSelf x, TSelf y) + { + // This matches the IEEE 754:2019 `minimum` function + // + // It propagates NaN inputs back to the caller and + // otherwise returns the larger of the inputs. It + // treats +0 as larger than -0 as per the specification. + + if ((x != y) && !TSelf.IsNaN(x)) + { + return x < y ? x : y; + } + + return TSelf.IsNegative(x) ? x : y; + } /// Compares two values to compute which is lesser and returning the other value if an input is NaN. /// The value to compare with . /// The value to compare with . /// if it is less than ; otherwise, . /// For this method matches the IEEE 754:2019 minimumNumber function. This requires NaN inputs to not be propagated back to the caller and for -0.0 to be treated as less than +0.0. - static abstract TSelf MinNumber(TSelf x, TSelf y); + static virtual TSelf MinNumber(TSelf x, TSelf y) + { + // This matches the IEEE 754:2019 `minimumNumber` function + // + // It does not propagate NaN inputs back to the caller and + // otherwise returns the larger of the inputs. It + // treats +0 as larger than -0 as per the specification. + + if (x != y) + { + if (!TSelf.IsNaN(y)) + { + return x < y ? x : y; + } + + return x; + } + + return TSelf.IsNegative(x) ? x : y; + } /// Computes the sign of a value. /// The value whose sign is to be computed. /// A positive value if is positive, if is zero, and a negative value if is negative. /// It is recommended that a function return 1, 0, and -1, respectively. - static abstract int Sign(TSelf value); + static virtual int Sign(TSelf value) + { + if (value != TSelf.Zero) + { + return TSelf.IsNegative(value) ? -1 : +1; + } + return 0; + } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/INumberBase.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/INumberBase.cs index cefd019a9aa245..138aef8f8d0f86 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/INumberBase.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/INumberBase.cs @@ -47,7 +47,7 @@ public interface INumberBase /// is not supported. /// is not representable by . [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static virtual TSelf CreateChecked(TOther value) + static virtual TSelf CreateChecked(TOther value) where TOther : INumberBase { TSelf? result; @@ -70,7 +70,7 @@ public static virtual TSelf CreateChecked(TOther value) /// An instance of created from , saturating if falls outside the representable range of . /// is not supported. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static virtual TSelf CreateSaturating(TOther value) + static virtual TSelf CreateSaturating(TOther value) where TOther : INumberBase { TSelf? result; @@ -93,7 +93,7 @@ public static virtual TSelf CreateSaturating(TOther value) /// An instance of created from , truncating if falls outside the representable range of . /// is not supported. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static virtual TSelf CreateTruncating(TOther value) + static virtual TSelf CreateTruncating(TOther value) where TOther : INumberBase { TSelf? result; diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/IPowerFunctions.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/IPowerFunctions.cs index 5b31fa9e5f49ab..05c767ebe629e1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/IPowerFunctions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/IPowerFunctions.cs @@ -6,7 +6,7 @@ namespace System.Numerics /// Defines support for power functions. /// The type that implements this interface. public interface IPowerFunctions - where TSelf : IPowerFunctions + where TSelf : IPowerFunctions, INumberBase { /// Computes a value raised to a given power. /// The value which is raised to the power of . diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/IRootFunctions.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/IRootFunctions.cs index 7a84aefcba7edb..f4215cdd72c290 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/IRootFunctions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/IRootFunctions.cs @@ -6,7 +6,7 @@ namespace System.Numerics /// Defines support for root functions. /// The type that implements this interface. public interface IRootFunctions - where TSelf : IRootFunctions + where TSelf : IRootFunctions, INumberBase { /// Computes the cube-root of a value. /// The value whose cube-root is to be computed. diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/ISubtractionOperators.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/ISubtractionOperators.cs index 38bd5a2b4625fb..b79879bef3651e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/ISubtractionOperators.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/ISubtractionOperators.cs @@ -21,6 +21,6 @@ public interface ISubtractionOperators /// The value which is subtracted from . /// The difference of subtracted from . /// The difference of subtracted from is not representable by . - static abstract TResult operator checked -(TSelf left, TOther right); + static virtual TResult operator checked -(TSelf left, TOther right) => left - right; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/ITrigonometricFunctions.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/ITrigonometricFunctions.cs index 734d5554d6edc8..9a073e4eb80e1d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/ITrigonometricFunctions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/ITrigonometricFunctions.cs @@ -6,7 +6,7 @@ namespace System.Numerics /// Defines support for trigonometric functions. /// The type that implements this interface. public interface ITrigonometricFunctions - where TSelf : ITrigonometricFunctions + where TSelf : ITrigonometricFunctions, INumberBase { /// Computes the arc-cosine of a value. /// The value, in radians, whose arc-cosine is to be computed. diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/IUnaryNegationOperators.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/IUnaryNegationOperators.cs index b03b13d5071e4b..6a8ee11fe07a49 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/IUnaryNegationOperators.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/IUnaryNegationOperators.cs @@ -18,6 +18,6 @@ public interface IUnaryNegationOperators /// The value for which to compute its unary negation. /// The unary negation of . /// The unary negation of is not representable by . - static abstract TResult operator checked -(TSelf value); + static virtual TResult operator checked -(TSelf value) => -value; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs index a348ff49f5334d..1366ebf68c282d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs @@ -860,13 +860,6 @@ public int CompareTo(object? obj) /// true if the formatting was successful; otherwise, false. public bool TryFormat(Span destination, out int charsWritten, [StringSyntax(StringSyntaxAttribute.NumericFormat)] ReadOnlySpan format = default, IFormatProvider? provider = null) => _value.TryFormat(destination, out charsWritten, format, provider); - // - // IAdditionOperators - // - - /// - static NFloat IAdditionOperators.operator checked +(NFloat left, NFloat right) => left + right; - // // IAdditiveIdentity // @@ -944,20 +937,6 @@ public int CompareTo(object? obj) #endif } - // - // IDecrementOperators - // - - /// - static NFloat IDecrementOperators.operator checked --(NFloat value) => --value; - - // - // IDivisionOperators - // - - /// - static NFloat IDivisionOperators.operator checked /(NFloat left, NFloat right) => left / right; - // // IExponentialFunctions // @@ -1197,13 +1176,6 @@ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destinati /// public static NFloat Tanh(NFloat x) => new NFloat(NativeType.Tanh(x._value)); - // - // IIncrementOperators - // - - /// - static NFloat IIncrementOperators.operator checked ++(NFloat value) => ++value; - // // ILogarithmicFunctions // @@ -1233,13 +1205,6 @@ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destinati /// static NFloat IMultiplicativeIdentity.MultiplicativeIdentity => new NFloat(NativeType.MultiplicativeIdentity); - // - // IMultiplyOperators - // - - /// - static NFloat IMultiplyOperators.operator checked *(NFloat left, NFloat right) => left * right; - // // INumber // @@ -1761,13 +1726,6 @@ private static bool TryConvertTo(NFloat value, [NotNullWhen(true)] out T /// public static bool TryParse(ReadOnlySpan s, IFormatProvider? provider, out NFloat result) => TryParse(s, NumberStyles.Float | NumberStyles.AllowThousands, provider, out result); - // - // ISubtractionOperators - // - - /// - static NFloat ISubtractionOperators.operator checked -(NFloat left, NFloat right) => left - right; - // // ITrigonometricFunctions // @@ -1820,12 +1778,5 @@ public static (NFloat Sin, NFloat Cos) SinCos(NFloat x) // /// // public static NFloat TanPi(NFloat x) => new NFloat(NativeType.TanPi(x._value, y._value)); - - // - // IUnaryNegationOperators - // - - /// - static NFloat IUnaryNegationOperators.operator checked -(NFloat value) => -value; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/SByte.cs b/src/libraries/System.Private.CoreLib/src/System/SByte.cs index ac88c897ae997b..ffe15363f37fe2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SByte.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SByte.cs @@ -466,9 +466,6 @@ public static sbyte Log2(sbyte value) /// static sbyte IDivisionOperators.operator /(sbyte left, sbyte right) => (sbyte)(left / right); - /// - static sbyte IDivisionOperators.operator checked /(sbyte left, sbyte right) => (sbyte)(left / right); - // // IEqualityOperators // diff --git a/src/libraries/System.Private.CoreLib/src/System/Single.cs b/src/libraries/System.Private.CoreLib/src/System/Single.cs index 96e413d938f3cb..9a9b32d1d6c306 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Single.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Single.cs @@ -527,9 +527,6 @@ object IConvertible.ToType(Type type, IFormatProvider? provider) /// static float IAdditionOperators.operator +(float left, float right) => left + right; - /// - static float IAdditionOperators.operator checked +(float left, float right) => left + right; - // // IAdditiveIdentity // @@ -596,9 +593,6 @@ public static bool IsPow2(float value) /// static float IDecrementOperators.operator --(float value) => --value; - /// - static float IDecrementOperators.operator checked --(float value) => --value; - // // IDivisionOperators // @@ -606,9 +600,6 @@ public static bool IsPow2(float value) /// static float IDivisionOperators.operator /(float left, float right) => left / right; - /// - static float IDivisionOperators.operator checked /(float left, float right) => left / right; - // // IExponentialFunctions // @@ -848,9 +839,6 @@ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destinatio /// static float IIncrementOperators.operator ++(float value) => ++value; - /// - static float IIncrementOperators.operator checked ++(float value) => ++value; - // // ILogarithmicFunctions // @@ -904,9 +892,6 @@ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destinatio /// static float IMultiplyOperators.operator *(float left, float right) => left * right; - /// - static float IMultiplyOperators.operator checked *(float left, float right) => left * right; - // // INumber // @@ -1384,9 +1369,6 @@ private static bool TryConvertTo(float value, [NotNullWhen(true)] out TO /// static float ISubtractionOperators.operator -(float left, float right) => left - right; - /// - static float ISubtractionOperators.operator checked -(float left, float right) => left - right; - // // ITrigonometricFunctions // @@ -1443,9 +1425,6 @@ private static bool TryConvertTo(float value, [NotNullWhen(true)] out TO /// static float IUnaryNegationOperators.operator -(float value) => -value; - /// - static float IUnaryNegationOperators.operator checked -(float value) => -value; - // // IUnaryPlusOperators // diff --git a/src/libraries/System.Private.CoreLib/src/System/UInt16.cs b/src/libraries/System.Private.CoreLib/src/System/UInt16.cs index 3ef0feff7a90aa..5d1f957361bbb2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/UInt16.cs +++ b/src/libraries/System.Private.CoreLib/src/System/UInt16.cs @@ -428,9 +428,6 @@ bool IBinaryInteger.TryWriteLittleEndian(Span destination, out int /// static ushort IDivisionOperators.operator /(ushort left, ushort right) => (ushort)(left / right); - /// - static ushort IDivisionOperators.operator checked /(ushort left, ushort right) => (ushort)(left / right); - // // IEqualityOperators // diff --git a/src/libraries/System.Private.CoreLib/src/System/UInt32.cs b/src/libraries/System.Private.CoreLib/src/System/UInt32.cs index 93c27f43d5d069..52a9206944a8fd 100644 --- a/src/libraries/System.Private.CoreLib/src/System/UInt32.cs +++ b/src/libraries/System.Private.CoreLib/src/System/UInt32.cs @@ -414,9 +414,6 @@ bool IBinaryInteger.TryWriteLittleEndian(Span destination, out int b /// static uint IDivisionOperators.operator /(uint left, uint right) => left / right; - /// - static uint IDivisionOperators.operator checked /(uint left, uint right) => left / right; - // // IEqualityOperators // diff --git a/src/libraries/System.Private.CoreLib/src/System/UInt64.cs b/src/libraries/System.Private.CoreLib/src/System/UInt64.cs index 928163fa2a85ab..dda78b15ffabd8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/UInt64.cs +++ b/src/libraries/System.Private.CoreLib/src/System/UInt64.cs @@ -413,9 +413,6 @@ bool IBinaryInteger.TryWriteLittleEndian(Span destination, out int /// static ulong IDivisionOperators.operator /(ulong left, ulong right) => left / right; - /// - static ulong IDivisionOperators.operator checked /(ulong left, ulong right) => left / right; - // // IEqualityOperators // diff --git a/src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs b/src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs index 48ef6b8103f2e4..b57ee876477bc3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs +++ b/src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs @@ -399,9 +399,6 @@ bool IBinaryInteger.TryWriteLittleEndian(Span destination, out int /// static nuint IDivisionOperators.operator /(nuint left, nuint right) => left / right; - /// - static nuint IDivisionOperators.operator checked /(nuint left, nuint right) => left / right; - // // IIncrementOperators // diff --git a/src/libraries/System.Runtime.Numerics/ref/System.Runtime.Numerics.cs b/src/libraries/System.Runtime.Numerics/ref/System.Runtime.Numerics.cs index 8c09f8a7db6e90..cd734a0dd3d846 100644 --- a/src/libraries/System.Runtime.Numerics/ref/System.Runtime.Numerics.cs +++ b/src/libraries/System.Runtime.Numerics/ref/System.Runtime.Numerics.cs @@ -98,7 +98,7 @@ namespace System.Numerics public static explicit operator short (System.Numerics.BigInteger value) { throw null; } public static explicit operator int (System.Numerics.BigInteger value) { throw null; } public static explicit operator long (System.Numerics.BigInteger value) { throw null; } - public static explicit operator System.IntPtr (System.Numerics.BigInteger value) { throw null; } + public static explicit operator nint (System.Numerics.BigInteger value) { throw null; } [System.CLSCompliantAttribute(false)] public static explicit operator sbyte (System.Numerics.BigInteger value) { throw null; } public static explicit operator float (System.Numerics.BigInteger value) { throw null; } @@ -111,7 +111,7 @@ namespace System.Numerics [System.CLSCompliantAttribute(false)] public static explicit operator ulong (System.Numerics.BigInteger value) { throw null; } [System.CLSCompliantAttribute(false)] - public static explicit operator System.UIntPtr (System.Numerics.BigInteger value) { throw null; } + public static explicit operator nuint (System.Numerics.BigInteger value) { throw null; } public static explicit operator System.Numerics.BigInteger (System.Numerics.Complex value) { throw null; } public static explicit operator System.Numerics.BigInteger (float value) { throw null; } public static bool operator >(long left, System.Numerics.BigInteger right) { throw null; } @@ -134,7 +134,7 @@ namespace System.Numerics public static implicit operator System.Numerics.BigInteger (short value) { throw null; } public static implicit operator System.Numerics.BigInteger (int value) { throw null; } public static implicit operator System.Numerics.BigInteger (long value) { throw null; } - public static implicit operator System.Numerics.BigInteger (System.IntPtr value) { throw null; } + public static implicit operator System.Numerics.BigInteger (nint value) { throw null; } [System.CLSCompliantAttribute(false)] public static implicit operator System.Numerics.BigInteger (sbyte value) { throw null; } [System.CLSCompliantAttribute(false)] @@ -146,7 +146,7 @@ namespace System.Numerics [System.CLSCompliantAttribute(false)] public static implicit operator System.Numerics.BigInteger (ulong value) { throw null; } [System.CLSCompliantAttribute(false)] - public static implicit operator System.Numerics.BigInteger (System.UIntPtr value) { throw null; } + public static implicit operator System.Numerics.BigInteger (nuint value) { throw null; } public static System.Numerics.BigInteger operator ++(System.Numerics.BigInteger value) { throw null; } public static bool operator !=(long left, System.Numerics.BigInteger right) { throw null; } public static bool operator !=(System.Numerics.BigInteger left, long right) { throw null; } @@ -190,15 +190,10 @@ namespace System.Numerics public static System.Numerics.BigInteger RotateLeft(System.Numerics.BigInteger value, int rotateAmount) { throw null; } public static System.Numerics.BigInteger RotateRight(System.Numerics.BigInteger value, int rotateAmount) { throw null; } public static System.Numerics.BigInteger Subtract(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; } - static System.Numerics.BigInteger System.Numerics.IAdditionOperators.operator checked +(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; } int System.Numerics.IBinaryInteger.GetByteCount() { throw null; } int System.Numerics.IBinaryInteger.GetShortestBitLength() { throw null; } bool System.Numerics.IBinaryInteger.TryWriteBigEndian(System.Span destination, out int bytesWritten) { throw null; } bool System.Numerics.IBinaryInteger.TryWriteLittleEndian(System.Span destination, out int bytesWritten) { throw null; } - static System.Numerics.BigInteger System.Numerics.IDecrementOperators.operator checked --(System.Numerics.BigInteger value) { throw null; } - static System.Numerics.BigInteger System.Numerics.IDivisionOperators.operator checked /(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; } - static System.Numerics.BigInteger System.Numerics.IIncrementOperators.operator checked ++(System.Numerics.BigInteger value) { throw null; } - static System.Numerics.BigInteger System.Numerics.IMultiplyOperators.operator checked *(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; } static bool System.Numerics.INumberBase.IsCanonical(System.Numerics.BigInteger value) { throw null; } static bool System.Numerics.INumberBase.IsComplexNumber(System.Numerics.BigInteger value) { throw null; } static bool System.Numerics.INumberBase.IsFinite(System.Numerics.BigInteger value) { throw null; } @@ -223,8 +218,6 @@ namespace System.Numerics static System.Numerics.BigInteger System.Numerics.INumber.MaxNumber(System.Numerics.BigInteger x, System.Numerics.BigInteger y) { throw null; } static System.Numerics.BigInteger System.Numerics.INumber.MinNumber(System.Numerics.BigInteger x, System.Numerics.BigInteger y) { throw null; } static int System.Numerics.INumber.Sign(System.Numerics.BigInteger value) { throw null; } - static System.Numerics.BigInteger System.Numerics.ISubtractionOperators.operator checked -(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; } - static System.Numerics.BigInteger System.Numerics.IUnaryNegationOperators.operator checked -(System.Numerics.BigInteger value) { throw null; } public byte[] ToByteArray() { throw null; } public byte[] ToByteArray(bool isUnsigned = false, bool isBigEndian = false) { throw null; } public override string ToString() { throw null; } @@ -322,7 +315,7 @@ namespace System.Numerics public static implicit operator System.Numerics.Complex (short value) { throw null; } public static implicit operator System.Numerics.Complex (int value) { throw null; } public static implicit operator System.Numerics.Complex (long value) { throw null; } - public static implicit operator System.Numerics.Complex (System.IntPtr value) { throw null; } + public static implicit operator System.Numerics.Complex (nint value) { throw null; } [System.CLSCompliantAttribute(false)] public static implicit operator System.Numerics.Complex (sbyte value) { throw null; } public static implicit operator System.Numerics.Complex (float value) { throw null; } @@ -333,7 +326,7 @@ namespace System.Numerics [System.CLSCompliantAttribute(false)] public static implicit operator System.Numerics.Complex (ulong value) { throw null; } [System.CLSCompliantAttribute(false)] - public static implicit operator System.Numerics.Complex (System.UIntPtr value) { throw null; } + public static implicit operator System.Numerics.Complex (nuint value) { throw null; } public static System.Numerics.Complex operator ++(System.Numerics.Complex value) { throw null; } public static bool operator !=(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; } public static System.Numerics.Complex operator *(double left, System.Numerics.Complex right) { throw null; } @@ -357,11 +350,6 @@ namespace System.Numerics public static System.Numerics.Complex Subtract(double left, System.Numerics.Complex right) { throw null; } public static System.Numerics.Complex Subtract(System.Numerics.Complex left, double right) { throw null; } public static System.Numerics.Complex Subtract(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; } - static System.Numerics.Complex System.Numerics.IAdditionOperators.operator checked +(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; } - static System.Numerics.Complex System.Numerics.IDecrementOperators.operator checked --(System.Numerics.Complex value) { throw null; } - static System.Numerics.Complex System.Numerics.IDivisionOperators.operator checked /(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; } - static System.Numerics.Complex System.Numerics.IIncrementOperators.operator checked ++(System.Numerics.Complex value) { throw null; } - static System.Numerics.Complex System.Numerics.IMultiplyOperators.operator checked *(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; } static System.Numerics.Complex System.Numerics.INumberBase.Abs(System.Numerics.Complex value) { throw null; } static bool System.Numerics.INumberBase.IsCanonical(System.Numerics.Complex value) { throw null; } static bool System.Numerics.INumberBase.IsZero(System.Numerics.Complex value) { throw null; } @@ -373,8 +361,6 @@ namespace System.Numerics static bool System.Numerics.INumberBase.TryConvertToChecked(System.Numerics.Complex value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static bool System.Numerics.INumberBase.TryConvertToSaturating(System.Numerics.Complex value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static bool System.Numerics.INumberBase.TryConvertToTruncating(System.Numerics.Complex value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } - static System.Numerics.Complex System.Numerics.ISubtractionOperators.operator checked -(System.Numerics.Complex left, System.Numerics.Complex right) { throw null; } - static System.Numerics.Complex System.Numerics.IUnaryNegationOperators.operator checked -(System.Numerics.Complex value) { throw null; } public static System.Numerics.Complex Tan(System.Numerics.Complex value) { throw null; } public static System.Numerics.Complex Tanh(System.Numerics.Complex value) { throw null; } public override string ToString() { throw null; } diff --git a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs index 39c8346a54ee43..021fd9a63204a9 100644 --- a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs +++ b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs @@ -3113,13 +3113,6 @@ private void AssertValid() } } - // - // IAdditionOperators - // - - /// - static BigInteger IAdditionOperators.operator checked +(BigInteger left, BigInteger right) => left + right; - // // IAdditiveIdentity // @@ -3849,27 +3842,6 @@ public static BigInteger Log2(BigInteger value) return ((value._bits.Length * 32) - 1) ^ uint.LeadingZeroCount(value._bits[^1]); } - // - // IDecrementOperators - // - - /// - static BigInteger IDecrementOperators.operator checked --(BigInteger value) => --value; - - // - // IDivisionOperators - // - - /// - static BigInteger IDivisionOperators.operator checked /(BigInteger left, BigInteger right) => left / right; - - // - // IIncrementOperators - // - - /// - static BigInteger IIncrementOperators.operator checked ++(BigInteger value) => ++value; - // // IMultiplicativeIdentity // @@ -3877,13 +3849,6 @@ public static BigInteger Log2(BigInteger value) /// static BigInteger IMultiplicativeIdentity.MultiplicativeIdentity => One; - // - // IMultiplyOperators - // - - /// - static BigInteger IMultiplyOperators.operator checked *(BigInteger left, BigInteger right) => left * right; - // // INumber // @@ -5255,19 +5220,5 @@ static bool INumberBase.TryConvertToTruncating(BigInteger va /// public static bool TryParse(ReadOnlySpan s, IFormatProvider? provider, out BigInteger result) => TryParse(s, NumberStyles.Integer, provider, out result); - - // - // ISubtractionOperators - // - - /// - static BigInteger ISubtractionOperators.operator checked -(BigInteger left, BigInteger right) => left - right; - - // - // IUnaryNegationOperators - // - - /// - static BigInteger IUnaryNegationOperators.operator checked -(BigInteger value) => -value; } } diff --git a/src/libraries/System.Runtime.Numerics/src/System/Numerics/Complex.cs b/src/libraries/System.Runtime.Numerics/src/System/Numerics/Complex.cs index 534605a6ac2c8f..334cfefbee0e9d 100644 --- a/src/libraries/System.Runtime.Numerics/src/System/Numerics/Complex.cs +++ b/src/libraries/System.Runtime.Numerics/src/System/Numerics/Complex.cs @@ -922,13 +922,6 @@ public static implicit operator Complex(nuint value) return new Complex(value, 0.0); } - // - // IAdditionOperators - // - - /// - static Complex IAdditionOperators.operator checked +(Complex left, Complex right) => left + right; - // // IAdditiveIdentity // @@ -943,16 +936,6 @@ public static implicit operator Complex(nuint value) /// public static Complex operator --(Complex value) => value - One; - /// - static Complex IDecrementOperators.operator checked --(Complex value) => --value; - - // - // IDivisionOperators - // - - /// - static Complex IDivisionOperators.operator checked /(Complex left, Complex right) => left / right; - // // IIncrementOperators // @@ -960,9 +943,6 @@ public static implicit operator Complex(nuint value) /// public static Complex operator ++(Complex value) => value + One; - /// - static Complex IIncrementOperators.operator checked ++(Complex value) => ++value; - // // IMultiplicativeIdentity // @@ -970,13 +950,6 @@ public static implicit operator Complex(nuint value) /// static Complex IMultiplicativeIdentity.MultiplicativeIdentity => new Complex(1.0, 0.0); - // - // IMultiplyOperators - // - - /// - static Complex IMultiplyOperators.operator checked *(Complex left, Complex right) => left * right; - // // INumberBase // @@ -2231,20 +2204,6 @@ public bool TryFormat(Span destination, out int charsWritten, ReadOnlySpan /// public static bool TryParse(ReadOnlySpan s, IFormatProvider? provider, out Complex result) => TryParse(s, DefaultNumberStyle, provider, out result); - // - // ISubtractionOperators - // - - /// - static Complex ISubtractionOperators.operator checked -(Complex left, Complex right) => left - right; - - // - // IUnaryNegationOperators - // - - /// - static Complex IUnaryNegationOperators.operator checked -(Complex value) => -value; - // // IUnaryPlusOperators // diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index a9a6194f326dff..29dba4b49d954d 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -781,7 +781,6 @@ public static void SetByte(System.Array array, int index, byte value) { } static bool System.Numerics.IComparisonOperators.operator <=(byte left, byte right) { throw null; } static byte System.Numerics.IDecrementOperators.operator checked --(byte value) { throw null; } static byte System.Numerics.IDecrementOperators.operator --(byte value) { throw null; } - static byte System.Numerics.IDivisionOperators.operator checked /(byte left, byte right) { throw null; } static byte System.Numerics.IDivisionOperators.operator /(byte left, byte right) { throw null; } static bool System.Numerics.IEqualityOperators.operator ==(byte left, byte right) { throw null; } static bool System.Numerics.IEqualityOperators.operator !=(byte left, byte right) { throw null; } @@ -936,7 +935,6 @@ public CannotUnloadAppDomainException(string? message, System.Exception? innerEx static bool System.ISpanParsable.TryParse(System.ReadOnlySpan s, System.IFormatProvider? provider, out char result) { throw null; } static char System.Numerics.IAdditionOperators.operator +(char left, char right) { throw null; } static char System.Numerics.IAdditionOperators.operator checked +(char left, char right) { throw null; } - static (char Quotient, char Remainder) System.Numerics.IBinaryInteger.DivRem(char left, char right) { throw null; } int System.Numerics.IBinaryInteger.GetByteCount() { throw null; } int System.Numerics.IBinaryInteger.GetShortestBitLength() { throw null; } static char System.Numerics.IBinaryInteger.LeadingZeroCount(char value) { throw null; } @@ -958,7 +956,6 @@ public CannotUnloadAppDomainException(string? message, System.Exception? innerEx static bool System.Numerics.IComparisonOperators.operator <=(char left, char right) { throw null; } static char System.Numerics.IDecrementOperators.operator checked --(char value) { throw null; } static char System.Numerics.IDecrementOperators.operator --(char value) { throw null; } - static char System.Numerics.IDivisionOperators.operator checked /(char left, char right) { throw null; } static char System.Numerics.IDivisionOperators.operator /(char left, char right) { throw null; } static bool System.Numerics.IEqualityOperators.operator ==(char left, char right) { throw null; } static bool System.Numerics.IEqualityOperators.operator !=(char left, char right) { throw null; } @@ -999,13 +996,6 @@ public CannotUnloadAppDomainException(string? message, System.Exception? innerEx static bool System.Numerics.INumberBase.TryConvertToTruncating(char value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static bool System.Numerics.INumberBase.TryParse(System.ReadOnlySpan s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out char result) { throw null; } static bool System.Numerics.INumberBase.TryParse([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] string? s, System.Globalization.NumberStyles style, System.IFormatProvider? provider, out char result) { throw null; } - static char System.Numerics.INumber.Clamp(char value, char min, char max) { throw null; } - static char System.Numerics.INumber.CopySign(char value, char sign) { throw null; } - static char System.Numerics.INumber.Max(char x, char y) { throw null; } - static char System.Numerics.INumber.MaxNumber(char x, char y) { throw null; } - static char System.Numerics.INumber.Min(char x, char y) { throw null; } - static char System.Numerics.INumber.MinNumber(char x, char y) { throw null; } - static int System.Numerics.INumber.Sign(char value) { throw null; } static char System.Numerics.IShiftOperators.operator <<(char value, int shiftAmount) { throw null; } static char System.Numerics.IShiftOperators.operator >>(char value, int shiftAmount) { throw null; } static char System.Numerics.IShiftOperators.operator >>>(char value, int shiftAmount) { throw null; } @@ -1915,7 +1905,6 @@ public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, S public static decimal Multiply(decimal d1, decimal d2) { throw null; } public static decimal Negate(decimal d) { throw null; } public static decimal operator +(decimal d1, decimal d2) { throw null; } - public static decimal operator checked *(decimal left, decimal right) { throw null; } public static decimal operator --(decimal d) { throw null; } public static decimal operator /(decimal d1, decimal d2) { throw null; } public static bool operator ==(decimal d1, decimal d2) { throw null; } @@ -1988,9 +1977,6 @@ public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, S ushort System.IConvertible.ToUInt16(System.IFormatProvider? provider) { throw null; } uint System.IConvertible.ToUInt32(System.IFormatProvider? provider) { throw null; } ulong System.IConvertible.ToUInt64(System.IFormatProvider? provider) { throw null; } - static decimal System.Numerics.IAdditionOperators.operator checked +(decimal left, decimal right) { throw null; } - static decimal System.Numerics.IDecrementOperators.operator checked --(decimal value) { throw null; } - static decimal System.Numerics.IDivisionOperators.operator checked /(decimal left, decimal right) { throw null; } int System.Numerics.IFloatingPoint.GetExponentByteCount() { throw null; } int System.Numerics.IFloatingPoint.GetExponentShortestBitLength() { throw null; } int System.Numerics.IFloatingPoint.GetSignificandBitLength() { throw null; } @@ -1999,7 +1985,6 @@ public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, S bool System.Numerics.IFloatingPoint.TryWriteExponentLittleEndian(System.Span destination, out int bytesWritten) { throw null; } bool System.Numerics.IFloatingPoint.TryWriteSignificandBigEndian(System.Span destination, out int bytesWritten) { throw null; } bool System.Numerics.IFloatingPoint.TryWriteSignificandLittleEndian(System.Span destination, out int bytesWritten) { throw null; } - static decimal System.Numerics.IIncrementOperators.operator checked ++(decimal value) { throw null; } static bool System.Numerics.INumberBase.IsComplexNumber(decimal value) { throw null; } static bool System.Numerics.INumberBase.IsFinite(decimal value) { throw null; } static bool System.Numerics.INumberBase.IsImaginaryNumber(decimal value) { throw null; } @@ -2021,8 +2006,6 @@ public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, S static bool System.Numerics.INumberBase.TryConvertToTruncating(decimal value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static decimal System.Numerics.INumber.MaxNumber(decimal x, decimal y) { throw null; } static decimal System.Numerics.INumber.MinNumber(decimal x, decimal y) { throw null; } - static decimal System.Numerics.ISubtractionOperators.operator checked -(decimal left, decimal right) { throw null; } - static decimal System.Numerics.IUnaryNegationOperators.operator checked -(decimal value) { throw null; } void System.Runtime.Serialization.IDeserializationCallback.OnDeserialization(object? sender) { } void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public static byte ToByte(decimal value) { throw null; } @@ -2231,14 +2214,11 @@ public DivideByZeroException(string? message, System.Exception? innerException) uint System.IConvertible.ToUInt32(System.IFormatProvider? provider) { throw null; } ulong System.IConvertible.ToUInt64(System.IFormatProvider? provider) { throw null; } static double System.Numerics.IAdditionOperators.operator +(double left, double right) { throw null; } - static double System.Numerics.IAdditionOperators.operator checked +(double left, double right) { throw null; } static double System.Numerics.IBitwiseOperators.operator &(double left, double right) { throw null; } static double System.Numerics.IBitwiseOperators.operator |(double left, double right) { throw null; } static double System.Numerics.IBitwiseOperators.operator ^(double left, double right) { throw null; } static double System.Numerics.IBitwiseOperators.operator ~(double value) { throw null; } - static double System.Numerics.IDecrementOperators.operator checked --(double value) { throw null; } static double System.Numerics.IDecrementOperators.operator --(double value) { throw null; } - static double System.Numerics.IDivisionOperators.operator checked /(double left, double right) { throw null; } static double System.Numerics.IDivisionOperators.operator /(double left, double right) { throw null; } int System.Numerics.IFloatingPoint.GetExponentByteCount() { throw null; } int System.Numerics.IFloatingPoint.GetExponentShortestBitLength() { throw null; } @@ -2248,10 +2228,8 @@ public DivideByZeroException(string? message, System.Exception? innerException) bool System.Numerics.IFloatingPoint.TryWriteExponentLittleEndian(System.Span destination, out int bytesWritten) { throw null; } bool System.Numerics.IFloatingPoint.TryWriteSignificandBigEndian(System.Span destination, out int bytesWritten) { throw null; } bool System.Numerics.IFloatingPoint.TryWriteSignificandLittleEndian(System.Span destination, out int bytesWritten) { throw null; } - static double System.Numerics.IIncrementOperators.operator checked ++(double value) { throw null; } static double System.Numerics.IIncrementOperators.operator ++(double value) { throw null; } static double System.Numerics.IModulusOperators.operator %(double left, double right) { throw null; } - static double System.Numerics.IMultiplyOperators.operator checked *(double left, double right) { throw null; } static double System.Numerics.IMultiplyOperators.operator *(double left, double right) { throw null; } static bool System.Numerics.INumberBase.IsCanonical(double value) { throw null; } static bool System.Numerics.INumberBase.IsComplexNumber(double value) { throw null; } @@ -2263,9 +2241,7 @@ public DivideByZeroException(string? message, System.Exception? innerException) static bool System.Numerics.INumberBase.TryConvertToChecked(double value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static bool System.Numerics.INumberBase.TryConvertToSaturating(double value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static bool System.Numerics.INumberBase.TryConvertToTruncating(double value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } - static double System.Numerics.ISubtractionOperators.operator checked -(double left, double right) { throw null; } static double System.Numerics.ISubtractionOperators.operator -(double left, double right) { throw null; } - static double System.Numerics.IUnaryNegationOperators.operator checked -(double value) { throw null; } static double System.Numerics.IUnaryNegationOperators.operator -(double value) { throw null; } static double System.Numerics.IUnaryPlusOperators.operator +(double value) { throw null; } public static double Tan(double x) { throw null; } @@ -2911,13 +2887,10 @@ public GopherStyleUriParser() { } public static (System.Half Sin, System.Half Cos) SinCos(System.Half x) { throw null; } public static System.Half Sinh(System.Half x) { throw null; } public static System.Half Sqrt(System.Half x) { throw null; } - static System.Half System.Numerics.IAdditionOperators.operator checked +(System.Half left, System.Half right) { throw null; } static System.Half System.Numerics.IBitwiseOperators.operator &(System.Half left, System.Half right) { throw null; } static System.Half System.Numerics.IBitwiseOperators.operator |(System.Half left, System.Half right) { throw null; } static System.Half System.Numerics.IBitwiseOperators.operator ^(System.Half left, System.Half right) { throw null; } static System.Half System.Numerics.IBitwiseOperators.operator ~(System.Half value) { throw null; } - static System.Half System.Numerics.IDecrementOperators.operator checked --(System.Half value) { throw null; } - static System.Half System.Numerics.IDivisionOperators.operator checked /(System.Half left, System.Half right) { throw null; } int System.Numerics.IFloatingPoint.GetExponentByteCount() { throw null; } int System.Numerics.IFloatingPoint.GetExponentShortestBitLength() { throw null; } int System.Numerics.IFloatingPoint.GetSignificandBitLength() { throw null; } @@ -2926,8 +2899,6 @@ public GopherStyleUriParser() { } bool System.Numerics.IFloatingPoint.TryWriteExponentLittleEndian(System.Span destination, out int bytesWritten) { throw null; } bool System.Numerics.IFloatingPoint.TryWriteSignificandBigEndian(System.Span destination, out int bytesWritten) { throw null; } bool System.Numerics.IFloatingPoint.TryWriteSignificandLittleEndian(System.Span destination, out int bytesWritten) { throw null; } - static System.Half System.Numerics.IIncrementOperators.operator checked ++(System.Half value) { throw null; } - static System.Half System.Numerics.IMultiplyOperators.operator checked *(System.Half left, System.Half right) { throw null; } static bool System.Numerics.INumberBase.IsCanonical(System.Half value) { throw null; } static bool System.Numerics.INumberBase.IsComplexNumber(System.Half value) { throw null; } static bool System.Numerics.INumberBase.IsImaginaryNumber(System.Half value) { throw null; } @@ -2938,8 +2909,6 @@ public GopherStyleUriParser() { } static bool System.Numerics.INumberBase.TryConvertToChecked(System.Half value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static bool System.Numerics.INumberBase.TryConvertToSaturating(System.Half value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static bool System.Numerics.INumberBase.TryConvertToTruncating(System.Half value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } - static System.Half System.Numerics.ISubtractionOperators.operator checked -(System.Half left, System.Half right) { throw null; } - static System.Half System.Numerics.IUnaryNegationOperators.operator checked -(System.Half value) { throw null; } public static System.Half Tan(System.Half x) { throw null; } public static System.Half Tanh(System.Half x) { throw null; } public override string ToString() { throw null; } @@ -3138,7 +3107,7 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep public static explicit operator checked System.UInt128 (System.Int128 value) { throw null; } [System.CLSCompliantAttribute(false)] public static explicit operator checked nuint (System.Int128 value) { throw null; } - public static explicit operator checked System.Int128(float value) { throw null; } + public static explicit operator checked System.Int128 (float value) { throw null; } public static System.Int128 operator checked ++(System.Int128 value) { throw null; } public static System.Int128 operator checked *(System.Int128 left, System.Int128 right) { throw null; } public static System.Int128 operator checked -(System.Int128 left, System.Int128 right) { throw null; } @@ -3328,7 +3297,6 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep static bool System.Numerics.IComparisonOperators.operator <=(short left, short right) { throw null; } static short System.Numerics.IDecrementOperators.operator checked --(short value) { throw null; } static short System.Numerics.IDecrementOperators.operator --(short value) { throw null; } - static short System.Numerics.IDivisionOperators.operator checked /(short left, short right) { throw null; } static short System.Numerics.IDivisionOperators.operator /(short left, short right) { throw null; } static bool System.Numerics.IEqualityOperators.operator ==(short left, short right) { throw null; } static bool System.Numerics.IEqualityOperators.operator !=(short left, short right) { throw null; } @@ -3456,7 +3424,6 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep static bool System.Numerics.IComparisonOperators.operator <=(int left, int right) { throw null; } static int System.Numerics.IDecrementOperators.operator checked --(int value) { throw null; } static int System.Numerics.IDecrementOperators.operator --(int value) { throw null; } - static int System.Numerics.IDivisionOperators.operator checked /(int left, int right) { throw null; } static int System.Numerics.IDivisionOperators.operator /(int left, int right) { throw null; } static bool System.Numerics.IEqualityOperators.operator ==(int left, int right) { throw null; } static bool System.Numerics.IEqualityOperators.operator !=(int left, int right) { throw null; } @@ -3584,7 +3551,6 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep static bool System.Numerics.IComparisonOperators.operator <=(long left, long right) { throw null; } static long System.Numerics.IDecrementOperators.operator checked --(long value) { throw null; } static long System.Numerics.IDecrementOperators.operator --(long value) { throw null; } - static long System.Numerics.IDivisionOperators.operator checked /(long left, long right) { throw null; } static long System.Numerics.IDivisionOperators.operator /(long left, long right) { throw null; } static bool System.Numerics.IEqualityOperators.operator ==(long left, long right) { throw null; } static bool System.Numerics.IEqualityOperators.operator !=(long left, long right) { throw null; } @@ -3716,7 +3682,6 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep static bool System.Numerics.IComparisonOperators.operator <=(nint left, nint right) { throw null; } static nint System.Numerics.IDecrementOperators.operator checked --(nint value) { throw null; } static nint System.Numerics.IDecrementOperators.operator --(nint value) { throw null; } - static nint System.Numerics.IDivisionOperators.operator checked /(nint left, nint right) { throw null; } static nint System.Numerics.IDivisionOperators.operator /(nint left, nint right) { throw null; } static nint System.Numerics.IIncrementOperators.operator checked ++(nint value) { throw null; } static nint System.Numerics.IIncrementOperators.operator ++(nint value) { throw null; } @@ -4652,7 +4617,6 @@ public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, S static bool System.Numerics.IComparisonOperators.operator <=(sbyte left, sbyte right) { throw null; } static sbyte System.Numerics.IDecrementOperators.operator checked --(sbyte value) { throw null; } static sbyte System.Numerics.IDecrementOperators.operator --(sbyte value) { throw null; } - static sbyte System.Numerics.IDivisionOperators.operator checked /(sbyte left, sbyte right) { throw null; } static sbyte System.Numerics.IDivisionOperators.operator /(sbyte left, sbyte right) { throw null; } static bool System.Numerics.IEqualityOperators.operator ==(sbyte left, sbyte right) { throw null; } static bool System.Numerics.IEqualityOperators.operator !=(sbyte left, sbyte right) { throw null; } @@ -4841,14 +4805,11 @@ public SerializableAttribute() { } uint System.IConvertible.ToUInt32(System.IFormatProvider? provider) { throw null; } ulong System.IConvertible.ToUInt64(System.IFormatProvider? provider) { throw null; } static float System.Numerics.IAdditionOperators.operator +(float left, float right) { throw null; } - static float System.Numerics.IAdditionOperators.operator checked +(float left, float right) { throw null; } static float System.Numerics.IBitwiseOperators.operator &(float left, float right) { throw null; } static float System.Numerics.IBitwiseOperators.operator |(float left, float right) { throw null; } static float System.Numerics.IBitwiseOperators.operator ^(float left, float right) { throw null; } static float System.Numerics.IBitwiseOperators.operator ~(float value) { throw null; } - static float System.Numerics.IDecrementOperators.operator checked --(float value) { throw null; } static float System.Numerics.IDecrementOperators.operator --(float value) { throw null; } - static float System.Numerics.IDivisionOperators.operator checked /(float left, float right) { throw null; } static float System.Numerics.IDivisionOperators.operator /(float left, float right) { throw null; } int System.Numerics.IFloatingPoint.GetExponentByteCount() { throw null; } int System.Numerics.IFloatingPoint.GetExponentShortestBitLength() { throw null; } @@ -4858,10 +4819,8 @@ public SerializableAttribute() { } bool System.Numerics.IFloatingPoint.TryWriteExponentLittleEndian(System.Span destination, out int bytesWritten) { throw null; } bool System.Numerics.IFloatingPoint.TryWriteSignificandBigEndian(System.Span destination, out int bytesWritten) { throw null; } bool System.Numerics.IFloatingPoint.TryWriteSignificandLittleEndian(System.Span destination, out int bytesWritten) { throw null; } - static float System.Numerics.IIncrementOperators.operator checked ++(float value) { throw null; } static float System.Numerics.IIncrementOperators.operator ++(float value) { throw null; } static float System.Numerics.IModulusOperators.operator %(float left, float right) { throw null; } - static float System.Numerics.IMultiplyOperators.operator checked *(float left, float right) { throw null; } static float System.Numerics.IMultiplyOperators.operator *(float left, float right) { throw null; } static bool System.Numerics.INumberBase.IsCanonical(float value) { throw null; } static bool System.Numerics.INumberBase.IsComplexNumber(float value) { throw null; } @@ -4873,9 +4832,7 @@ public SerializableAttribute() { } static bool System.Numerics.INumberBase.TryConvertToChecked(float value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static bool System.Numerics.INumberBase.TryConvertToSaturating(float value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } static bool System.Numerics.INumberBase.TryConvertToTruncating(float value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; } - static float System.Numerics.ISubtractionOperators.operator checked -(float left, float right) { throw null; } static float System.Numerics.ISubtractionOperators.operator -(float left, float right) { throw null; } - static float System.Numerics.IUnaryNegationOperators.operator checked -(float value) { throw null; } static float System.Numerics.IUnaryNegationOperators.operator -(float value) { throw null; } static float System.Numerics.IUnaryPlusOperators.operator +(float value) { throw null; } public static float Tan(float x) { throw null; } @@ -6308,7 +6265,6 @@ public TypeUnloadedException(string? message, System.Exception? innerException) static bool System.Numerics.IComparisonOperators.operator <=(ushort left, ushort right) { throw null; } static ushort System.Numerics.IDecrementOperators.operator checked --(ushort value) { throw null; } static ushort System.Numerics.IDecrementOperators.operator --(ushort value) { throw null; } - static ushort System.Numerics.IDivisionOperators.operator checked /(ushort left, ushort right) { throw null; } static ushort System.Numerics.IDivisionOperators.operator /(ushort left, ushort right) { throw null; } static bool System.Numerics.IEqualityOperators.operator ==(ushort left, ushort right) { throw null; } static bool System.Numerics.IEqualityOperators.operator !=(ushort left, ushort right) { throw null; } @@ -6436,7 +6392,6 @@ public TypeUnloadedException(string? message, System.Exception? innerException) static bool System.Numerics.IComparisonOperators.operator <=(uint left, uint right) { throw null; } static uint System.Numerics.IDecrementOperators.operator checked --(uint value) { throw null; } static uint System.Numerics.IDecrementOperators.operator --(uint value) { throw null; } - static uint System.Numerics.IDivisionOperators.operator checked /(uint left, uint right) { throw null; } static uint System.Numerics.IDivisionOperators.operator /(uint left, uint right) { throw null; } static bool System.Numerics.IEqualityOperators.operator ==(uint left, uint right) { throw null; } static bool System.Numerics.IEqualityOperators.operator !=(uint left, uint right) { throw null; } @@ -6564,7 +6519,6 @@ public TypeUnloadedException(string? message, System.Exception? innerException) static bool System.Numerics.IComparisonOperators.operator <=(ulong left, ulong right) { throw null; } static ulong System.Numerics.IDecrementOperators.operator checked --(ulong value) { throw null; } static ulong System.Numerics.IDecrementOperators.operator --(ulong value) { throw null; } - static ulong System.Numerics.IDivisionOperators.operator checked /(ulong left, ulong right) { throw null; } static ulong System.Numerics.IDivisionOperators.operator /(ulong left, ulong right) { throw null; } static bool System.Numerics.IEqualityOperators.operator ==(ulong left, ulong right) { throw null; } static bool System.Numerics.IEqualityOperators.operator !=(ulong left, ulong right) { throw null; } @@ -6626,7 +6580,7 @@ public TypeUnloadedException(string? message, System.Exception? innerException) [System.CLSCompliantAttribute(false)] public readonly partial struct UIntPtr : System.IComparable, System.IComparable, System.IEquatable, System.IFormattable, System.IParsable, System.ISpanFormattable, System.ISpanParsable, System.Numerics.IAdditionOperators, System.Numerics.IAdditiveIdentity, System.Numerics.IBinaryInteger, System.Numerics.IBinaryNumber, System.Numerics.IBitwiseOperators, System.Numerics.IComparisonOperators, System.Numerics.IDecrementOperators, System.Numerics.IDivisionOperators, System.Numerics.IEqualityOperators, System.Numerics.IIncrementOperators, System.Numerics.IMinMaxValue, System.Numerics.IModulusOperators, System.Numerics.IMultiplicativeIdentity, System.Numerics.IMultiplyOperators, System.Numerics.INumber, System.Numerics.INumberBase, System.Numerics.IShiftOperators, System.Numerics.ISubtractionOperators, System.Numerics.IUnaryNegationOperators, System.Numerics.IUnaryPlusOperators, System.Numerics.IUnsignedNumber, System.Runtime.Serialization.ISerializable { - private readonly unsafe void*_dummyPrimitive; + private readonly unsafe void* _dummyPrimitive; public static readonly nuint Zero; public UIntPtr(uint value) { throw null; } public UIntPtr(ulong value) { throw null; } @@ -6693,7 +6647,6 @@ public TypeUnloadedException(string? message, System.Exception? innerException) static bool System.Numerics.IComparisonOperators.operator <=(nuint left, nuint right) { throw null; } static nuint System.Numerics.IDecrementOperators.operator checked --(nuint value) { throw null; } static nuint System.Numerics.IDecrementOperators.operator --(nuint value) { throw null; } - static nuint System.Numerics.IDivisionOperators.operator checked /(nuint left, nuint right) { throw null; } static nuint System.Numerics.IDivisionOperators.operator /(nuint left, nuint right) { throw null; } static nuint System.Numerics.IIncrementOperators.operator checked ++(nuint value) { throw null; } static nuint System.Numerics.IIncrementOperators.operator ++(nuint value) { throw null; } @@ -10286,12 +10239,12 @@ namespace System.Numerics public static partial class BitOperations { public static bool IsPow2(int value) { throw null; } + public static bool IsPow2(long value) { throw null; } + public static bool IsPow2(nint value) { throw null; } [System.CLSCompliantAttribute(false)] public static bool IsPow2(uint value) { throw null; } - public static bool IsPow2(long value) { throw null; } [System.CLSCompliantAttribute(false)] public static bool IsPow2(ulong value) { throw null; } - public static bool IsPow2(nint value) { throw null; } [System.CLSCompliantAttribute(false)] public static bool IsPow2(nuint value) { throw null; } [System.CLSCompliantAttribute(false)] @@ -10332,18 +10285,18 @@ public static partial class BitOperations public static nuint RoundUpToPowerOf2(nuint value) { throw null; } public static int TrailingZeroCount(int value) { throw null; } public static int TrailingZeroCount(long value) { throw null; } + public static int TrailingZeroCount(nint value) { throw null; } [System.CLSCompliantAttribute(false)] public static int TrailingZeroCount(uint value) { throw null; } [System.CLSCompliantAttribute(false)] public static int TrailingZeroCount(ulong value) { throw null; } - public static int TrailingZeroCount(nint value) { throw null; } [System.CLSCompliantAttribute(false)] public static int TrailingZeroCount(nuint value) { throw null; } } public partial interface IAdditionOperators where TSelf : System.Numerics.IAdditionOperators { static abstract TResult operator +(TSelf left, TOther right); - static abstract TResult operator checked +(TSelf left, TOther right); + static virtual TResult operator checked +(TSelf left, TOther right) { throw null; } } public partial interface IAdditiveIdentity where TSelf : System.Numerics.IAdditiveIdentity { @@ -10354,13 +10307,13 @@ public partial interface IBinaryFloatingPointIeee754 : System.IComparable } public partial interface IBinaryInteger : System.IComparable, System.IComparable, System.IEquatable, System.IFormattable, System.IParsable, System.ISpanFormattable, System.ISpanParsable, System.Numerics.IAdditionOperators, System.Numerics.IAdditiveIdentity, System.Numerics.IBinaryNumber, System.Numerics.IBitwiseOperators, System.Numerics.IComparisonOperators, System.Numerics.IDecrementOperators, System.Numerics.IDivisionOperators, System.Numerics.IEqualityOperators, System.Numerics.IIncrementOperators, System.Numerics.IModulusOperators, System.Numerics.IMultiplicativeIdentity, System.Numerics.IMultiplyOperators, System.Numerics.INumber, System.Numerics.INumberBase, System.Numerics.IShiftOperators, System.Numerics.ISubtractionOperators, System.Numerics.IUnaryNegationOperators, System.Numerics.IUnaryPlusOperators where TSelf : System.Numerics.IBinaryInteger { - static abstract (TSelf Quotient, TSelf Remainder) DivRem(TSelf left, TSelf right); + static virtual (TSelf Quotient, TSelf Remainder) DivRem(TSelf left, TSelf right) { throw null; } int GetByteCount(); int GetShortestBitLength(); - static abstract TSelf LeadingZeroCount(TSelf value); + static virtual TSelf LeadingZeroCount(TSelf value) { throw null; } static abstract TSelf PopCount(TSelf value); - static abstract TSelf RotateLeft(TSelf value, int rotateAmount); - static abstract TSelf RotateRight(TSelf value, int rotateAmount); + static virtual TSelf RotateLeft(TSelf value, int rotateAmount) { throw null; } + static virtual TSelf RotateRight(TSelf value, int rotateAmount) { throw null; } static abstract TSelf TrailingZeroCount(TSelf value); bool TryWriteBigEndian(System.Span destination, out int bytesWritten); bool TryWriteLittleEndian(System.Span destination, out int bytesWritten); @@ -10392,12 +10345,12 @@ public partial interface IComparisonOperators : System.IComparabl } public partial interface IDecrementOperators where TSelf : System.Numerics.IDecrementOperators { - static abstract TSelf operator checked --(TSelf value); + static virtual TSelf operator checked --(TSelf value) { throw null; } static abstract TSelf operator --(TSelf value); } public partial interface IDivisionOperators where TSelf : System.Numerics.IDivisionOperators { - static abstract TResult operator checked /(TSelf left, TOther right); + static virtual TResult operator checked /(TSelf left, TOther right) { throw null; } static abstract TResult operator /(TSelf left, TOther right); } public partial interface IEqualityOperators : System.IEquatable where TSelf : System.Numerics.IEqualityOperators @@ -10405,14 +10358,14 @@ public partial interface IEqualityOperators : System.IEquatable where TSelf : System.Numerics.IExponentialFunctions + public partial interface IExponentialFunctions where TSelf : System.Numerics.IExponentialFunctions, System.Numerics.INumberBase { static abstract TSelf Exp(TSelf x); static abstract TSelf Exp10(TSelf x); - static abstract TSelf Exp10M1(TSelf x); + static virtual TSelf Exp10M1(TSelf x) { throw null; } static abstract TSelf Exp2(TSelf x); - static abstract TSelf Exp2M1(TSelf x); - static abstract TSelf ExpM1(TSelf x); + static virtual TSelf Exp2M1(TSelf x) { throw null; } + static virtual TSelf ExpM1(TSelf x) { throw null; } } public partial interface IFloatingPointIeee754 : System.IComparable, System.IComparable, System.IEquatable, System.IFormattable, System.IParsable, System.ISpanFormattable, System.ISpanParsable, System.Numerics.IAdditionOperators, System.Numerics.IAdditiveIdentity, System.Numerics.IComparisonOperators, System.Numerics.IDecrementOperators, System.Numerics.IDivisionOperators, System.Numerics.IEqualityOperators, System.Numerics.IExponentialFunctions, System.Numerics.IFloatingPoint, System.Numerics.IHyperbolicFunctions, System.Numerics.IIncrementOperators, System.Numerics.ILogarithmicFunctions, System.Numerics.IModulusOperators, System.Numerics.IMultiplicativeIdentity, System.Numerics.IMultiplyOperators, System.Numerics.INumber, System.Numerics.INumberBase, System.Numerics.IPowerFunctions, System.Numerics.IRootFunctions, System.Numerics.ISignedNumber, System.Numerics.ISubtractionOperators, System.Numerics.ITrigonometricFunctions, System.Numerics.IUnaryNegationOperators, System.Numerics.IUnaryPlusOperators where TSelf : System.Numerics.IFloatingPointIeee754 { @@ -10429,27 +10382,27 @@ public partial interface IFloatingPointIeee754 : System.IComparable, Syst static abstract TSelf FusedMultiplyAdd(TSelf left, TSelf right, TSelf addend); static abstract TSelf Ieee754Remainder(TSelf left, TSelf right); static abstract int ILogB(TSelf x); - static abstract TSelf ReciprocalEstimate(TSelf x); - static abstract TSelf ReciprocalSqrtEstimate(TSelf x); + static virtual TSelf ReciprocalEstimate(TSelf x) { throw null; } + static virtual TSelf ReciprocalSqrtEstimate(TSelf x) { throw null; } static abstract TSelf ScaleB(TSelf x, int n); } public partial interface IFloatingPoint : System.IComparable, System.IComparable, System.IEquatable, System.IFormattable, System.IParsable, System.ISpanFormattable, System.ISpanParsable, System.Numerics.IAdditionOperators, System.Numerics.IAdditiveIdentity, System.Numerics.IComparisonOperators, System.Numerics.IDecrementOperators, System.Numerics.IDivisionOperators, System.Numerics.IEqualityOperators, System.Numerics.IIncrementOperators, System.Numerics.IModulusOperators, System.Numerics.IMultiplicativeIdentity, System.Numerics.IMultiplyOperators, System.Numerics.INumber, System.Numerics.INumberBase, System.Numerics.ISignedNumber, System.Numerics.ISubtractionOperators, System.Numerics.IUnaryNegationOperators, System.Numerics.IUnaryPlusOperators where TSelf : System.Numerics.IFloatingPoint { - static abstract TSelf Ceiling(TSelf x); - static abstract TSelf Floor(TSelf x); + static virtual TSelf Ceiling(TSelf x) { throw null; } + static virtual TSelf Floor(TSelf x) { throw null; } int GetExponentByteCount(); int GetExponentShortestBitLength(); - int GetSignificandByteCount(); int GetSignificandBitLength(); - static abstract TSelf Round(TSelf x); - static abstract TSelf Round(TSelf x, int digits); + int GetSignificandByteCount(); + static virtual TSelf Round(TSelf x) { throw null; } + static virtual TSelf Round(TSelf x, int digits) { throw null; } static abstract TSelf Round(TSelf x, int digits, System.MidpointRounding mode); - static abstract TSelf Round(TSelf x, System.MidpointRounding mode); - static abstract TSelf Truncate(TSelf x); - bool TryWriteExponentBigEndian(Span destination, out int bytesWritten); - bool TryWriteExponentLittleEndian(Span destination, out int bytesWritten); - bool TryWriteSignificandBigEndian(Span destination, out int bytesWritten); - bool TryWriteSignificandLittleEndian(Span destination, out int bytesWritten); + static virtual TSelf Round(TSelf x, System.MidpointRounding mode) { throw null; } + static virtual TSelf Truncate(TSelf x) { throw null; } + bool TryWriteExponentBigEndian(System.Span destination, out int bytesWritten); + bool TryWriteExponentLittleEndian(System.Span destination, out int bytesWritten); + bool TryWriteSignificandBigEndian(System.Span destination, out int bytesWritten); + bool TryWriteSignificandLittleEndian(System.Span destination, out int bytesWritten); int WriteExponentBigEndian(byte[] destination) { throw null; } int WriteExponentBigEndian(byte[] destination, int startIndex) { throw null; } int WriteExponentBigEndian(System.Span destination) { throw null; } @@ -10463,7 +10416,7 @@ public partial interface IFloatingPoint : System.IComparable, System.ICom int WriteSignificandLittleEndian(byte[] destination, int startIndex) { throw null; } int WriteSignificandLittleEndian(System.Span destination) { throw null; } } - public partial interface IHyperbolicFunctions where TSelf : System.Numerics.IHyperbolicFunctions + public partial interface IHyperbolicFunctions where TSelf : System.Numerics.IHyperbolicFunctions, System.Numerics.INumberBase { static abstract TSelf Acosh(TSelf x); static abstract TSelf Asinh(TSelf x); @@ -10474,18 +10427,18 @@ public partial interface IHyperbolicFunctions where TSelf : System.Numeri } public partial interface IIncrementOperators where TSelf : System.Numerics.IIncrementOperators { - static abstract TSelf operator checked ++(TSelf value); + static virtual TSelf operator checked ++(TSelf value) { throw null; } static abstract TSelf operator ++(TSelf value); } - public partial interface ILogarithmicFunctions where TSelf : System.Numerics.ILogarithmicFunctions + public partial interface ILogarithmicFunctions where TSelf : System.Numerics.ILogarithmicFunctions, System.Numerics.INumberBase { static abstract TSelf Log(TSelf x); static abstract TSelf Log(TSelf x, TSelf newBase); static abstract TSelf Log10(TSelf x); - static abstract TSelf Log10P1(TSelf x); + static virtual TSelf Log10P1(TSelf x) { throw null; } static abstract TSelf Log2(TSelf x); - static abstract TSelf Log2P1(TSelf x); - static abstract TSelf LogP1(TSelf x); + static virtual TSelf Log2P1(TSelf x) { throw null; } + static virtual TSelf LogP1(TSelf x) { throw null; } } public partial interface IMinMaxValue where TSelf : System.Numerics.IMinMaxValue { @@ -10502,7 +10455,7 @@ public partial interface IMultiplicativeIdentity where TSelf : S } public partial interface IMultiplyOperators where TSelf : System.Numerics.IMultiplyOperators { - static abstract TResult operator checked *(TSelf left, TOther right); + static virtual TResult operator checked *(TSelf left, TOther right) { throw null; } static abstract TResult operator *(TSelf left, TOther right); } public partial interface INumberBase : System.IEquatable, System.IFormattable, System.IParsable, System.ISpanFormattable, System.ISpanParsable, System.Numerics.IAdditionOperators, System.Numerics.IAdditiveIdentity, System.Numerics.IDecrementOperators, System.Numerics.IDivisionOperators, System.Numerics.IEqualityOperators, System.Numerics.IIncrementOperators, System.Numerics.IMultiplicativeIdentity, System.Numerics.IMultiplyOperators, System.Numerics.ISubtractionOperators, System.Numerics.IUnaryNegationOperators, System.Numerics.IUnaryPlusOperators where TSelf : System.Numerics.INumberBase @@ -10548,19 +10501,19 @@ public partial interface INumberBase : System.IEquatable, System.I } public partial interface INumber : System.IComparable, System.IComparable, System.IEquatable, System.IFormattable, System.IParsable, System.ISpanFormattable, System.ISpanParsable, System.Numerics.IAdditionOperators, System.Numerics.IAdditiveIdentity, System.Numerics.IComparisonOperators, System.Numerics.IDecrementOperators, System.Numerics.IDivisionOperators, System.Numerics.IEqualityOperators, System.Numerics.IIncrementOperators, System.Numerics.IModulusOperators, System.Numerics.IMultiplicativeIdentity, System.Numerics.IMultiplyOperators, System.Numerics.INumberBase, System.Numerics.ISubtractionOperators, System.Numerics.IUnaryNegationOperators, System.Numerics.IUnaryPlusOperators where TSelf : System.Numerics.INumber { - static abstract TSelf Clamp(TSelf value, TSelf min, TSelf max); - static abstract TSelf CopySign(TSelf value, TSelf sign); - static abstract TSelf Max(TSelf x, TSelf y); - static abstract TSelf MaxNumber(TSelf x, TSelf y); - static abstract TSelf Min(TSelf x, TSelf y); - static abstract TSelf MinNumber(TSelf x, TSelf y); - static abstract int Sign(TSelf value); + static virtual TSelf Clamp(TSelf value, TSelf min, TSelf max) { throw null; } + static virtual TSelf CopySign(TSelf value, TSelf sign) { throw null; } + static virtual TSelf Max(TSelf x, TSelf y) { throw null; } + static virtual TSelf MaxNumber(TSelf x, TSelf y) { throw null; } + static virtual TSelf Min(TSelf x, TSelf y) { throw null; } + static virtual TSelf MinNumber(TSelf x, TSelf y) { throw null; } + static virtual int Sign(TSelf value) { throw null; } } - public partial interface IPowerFunctions where TSelf : System.Numerics.IPowerFunctions + public partial interface IPowerFunctions where TSelf : System.Numerics.IPowerFunctions, System.Numerics.INumberBase { static abstract TSelf Pow(TSelf x, TSelf y); } - public partial interface IRootFunctions where TSelf : System.Numerics.IRootFunctions + public partial interface IRootFunctions where TSelf : System.Numerics.IRootFunctions, System.Numerics.INumberBase { static abstract TSelf Cbrt(TSelf x); static abstract TSelf Sqrt(TSelf x); @@ -10577,10 +10530,10 @@ public partial interface ISignedNumber where TSelf : System.Numerics.INum } public partial interface ISubtractionOperators where TSelf : System.Numerics.ISubtractionOperators { - static abstract TResult operator checked -(TSelf left, TOther right); + static virtual TResult operator checked -(TSelf left, TOther right) { throw null; } static abstract TResult operator -(TSelf left, TOther right); } - public partial interface ITrigonometricFunctions where TSelf : System.Numerics.ITrigonometricFunctions + public partial interface ITrigonometricFunctions where TSelf : System.Numerics.ITrigonometricFunctions, System.Numerics.INumberBase { static abstract TSelf Acos(TSelf x); static abstract TSelf Asin(TSelf x); @@ -10593,7 +10546,7 @@ public partial interface ITrigonometricFunctions where TSelf : System.Num } public partial interface IUnaryNegationOperators where TSelf : System.Numerics.IUnaryNegationOperators { - static abstract TResult operator checked -(TSelf value); + static virtual TResult operator checked -(TSelf value) { throw null; } static abstract TResult operator -(TSelf value); } public partial interface IUnaryPlusOperators where TSelf : System.Numerics.IUnaryPlusOperators From fc538c23852556a9d04759be9f74681b95ae60af Mon Sep 17 00:00:00 2001 From: Eirik Tsarpalis Date: Fri, 10 Jun 2022 18:47:30 +0300 Subject: [PATCH 040/337] Makes the following changes: (#70430) * Change DeserializeAsyncEnumerable so that reading from the underlying stream does not wait until the underlying buffer is full. * Encapsulate the buffer management logic behind ReadBufferState. * Avoid allocating a new JsonTypeInfo instance on every IAsyncEnumerator initialization. --- .../JsonSerializer.Read.Stream.cs | 168 +++--------------- .../Json/Serialization/ReadBufferState.cs | 162 +++++++++++++++-- 2 files changed, 172 insertions(+), 158 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs index 5c4ba44ee383d4..55ba3ef0a2496f 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Stream.cs @@ -1,14 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Buffers; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Runtime.CompilerServices; using System.Text.Json.Serialization; -using System.Text.Json.Serialization.Converters; using System.Text.Json.Serialization.Metadata; using System.Threading; using System.Threading.Tasks; @@ -375,7 +373,7 @@ public static partial class JsonSerializer } JsonTypeInfo jsonTypeInfo = options.GetOrAddJsonTypeInfoForRootType(typeof(TValue)); - return CreateAsyncEnumerableDeserializer(utf8Json, jsonTypeInfo, cancellationToken); + return CreateAsyncEnumerableDeserializer(utf8Json, CreateQueueTypeInfo(jsonTypeInfo), cancellationToken); } /// @@ -406,28 +404,30 @@ public static partial class JsonSerializer ThrowHelper.ThrowArgumentNullException(nameof(jsonTypeInfo)); } - return CreateAsyncEnumerableDeserializer(utf8Json, jsonTypeInfo, cancellationToken); + return CreateAsyncEnumerableDeserializer(utf8Json, CreateQueueTypeInfo(jsonTypeInfo), cancellationToken); + } + + private static JsonTypeInfo> CreateQueueTypeInfo(JsonTypeInfo jsonTypeInfo) + { + return JsonMetadataServices.CreateQueueInfo, TValue>( + options: jsonTypeInfo.Options, + collectionInfo: new() + { + ObjectCreator = static () => new Queue(), + ElementInfo = jsonTypeInfo, + NumberHandling = jsonTypeInfo.Options.NumberHandling + }); } private static async IAsyncEnumerable CreateAsyncEnumerableDeserializer( Stream utf8Json, - JsonTypeInfo jsonTypeInfo, + JsonTypeInfo> queueTypeInfo, [EnumeratorCancellation] CancellationToken cancellationToken) { - JsonSerializerOptions options = jsonTypeInfo.Options; - JsonTypeInfo> queueTypeInfo = - JsonMetadataServices.CreateQueueInfo, TValue>( - options: options, - collectionInfo: new() - { - ObjectCreator = () => new Queue(), - ElementInfo = jsonTypeInfo, - NumberHandling = options.NumberHandling - }); - + queueTypeInfo.EnsureConfigured(); + JsonSerializerOptions options = queueTypeInfo.Options; var bufferState = new ReadBufferState(options.DefaultBufferSize); ReadStack readStack = default; - queueTypeInfo.EnsureConfigured(); readStack.Initialize(queueTypeInfo, supportContinuation: true); var jsonReaderState = new JsonReaderState(options.GetReaderOptions()); @@ -435,7 +435,7 @@ private static async IAsyncEnumerable CreateAsyncEnumerableDeserializer< { do { - bufferState = await ReadFromStreamAsync(utf8Json, bufferState, cancellationToken).ConfigureAwait(false); + bufferState = await bufferState.ReadFromStreamAsync(utf8Json, cancellationToken, fillBuffer: false).ConfigureAwait(false); ContinueDeserialize>( ref bufferState, ref jsonReaderState, @@ -476,7 +476,7 @@ private static async IAsyncEnumerable CreateAsyncEnumerableDeserializer< { while (true) { - bufferState = await ReadFromStreamAsync(utf8Json, bufferState, cancellationToken).ConfigureAwait(false); + bufferState = await bufferState.ReadFromStreamAsync(utf8Json, cancellationToken).ConfigureAwait(false); TValue value = ContinueDeserialize(ref bufferState, ref jsonReaderState, ref readStack, converter, options); if (bufferState.IsFinalBlock) @@ -507,7 +507,7 @@ private static async IAsyncEnumerable CreateAsyncEnumerableDeserializer< { while (true) { - bufferState = ReadFromStream(utf8Json, bufferState); + bufferState.ReadFromStream(utf8Json); TValue value = ContinueDeserialize(ref bufferState, ref jsonReaderState, ref readStack, converter, options); if (bufferState.IsFinalBlock) @@ -522,78 +522,6 @@ private static async IAsyncEnumerable CreateAsyncEnumerableDeserializer< } } - /// - /// Read from the stream until either our buffer is filled or we hit EOF. - /// Calling ReadCore is relatively expensive, so we minimize the number of times - /// we need to call it. - /// - internal static async ValueTask ReadFromStreamAsync( - Stream utf8Json, - ReadBufferState bufferState, - CancellationToken cancellationToken) - { - while (true) - { - int bytesRead = await utf8Json.ReadAsync( -#if BUILDING_INBOX_LIBRARY - bufferState.Buffer.AsMemory(bufferState.BytesInBuffer), -#else - bufferState.Buffer, bufferState.BytesInBuffer, bufferState.Buffer.Length - bufferState.BytesInBuffer, -#endif - cancellationToken).ConfigureAwait(false); - - if (bytesRead == 0) - { - bufferState.IsFinalBlock = true; - break; - } - - bufferState.BytesInBuffer += bytesRead; - - if (bufferState.BytesInBuffer == bufferState.Buffer.Length) - { - break; - } - } - - return bufferState; - } - - /// - /// Read from the stream until either our buffer is filled or we hit EOF. - /// Calling ReadCore is relatively expensive, so we minimize the number of times - /// we need to call it. - /// - internal static ReadBufferState ReadFromStream( - Stream utf8Json, - ReadBufferState bufferState) - { - while (true) - { - int bytesRead = utf8Json.Read( -#if BUILDING_INBOX_LIBRARY - bufferState.Buffer.AsSpan(bufferState.BytesInBuffer)); -#else - bufferState.Buffer, bufferState.BytesInBuffer, bufferState.Buffer.Length - bufferState.BytesInBuffer); -#endif - - if (bytesRead == 0) - { - bufferState.IsFinalBlock = true; - break; - } - - bufferState.BytesInBuffer += bytesRead; - - if (bufferState.BytesInBuffer == bufferState.Buffer.Length) - { - break; - } - } - - return bufferState; - } - internal static TValue ContinueDeserialize( ref ReadBufferState bufferState, ref JsonReaderState jsonReaderState, @@ -601,67 +529,17 @@ internal static TValue ContinueDeserialize( JsonConverter converter, JsonSerializerOptions options) { - if (bufferState.BytesInBuffer > bufferState.ClearMax) - { - bufferState.ClearMax = bufferState.BytesInBuffer; - } - - int start = 0; - if (bufferState.IsFirstIteration) - { - bufferState.IsFirstIteration = false; - - // Handle the UTF-8 BOM if present - Debug.Assert(bufferState.Buffer.Length >= JsonConstants.Utf8Bom.Length); - if (bufferState.Buffer.AsSpan().StartsWith(JsonConstants.Utf8Bom)) - { - start += JsonConstants.Utf8Bom.Length; - bufferState.BytesInBuffer -= JsonConstants.Utf8Bom.Length; - } - } - // Process the data available TValue value = ReadCore( ref jsonReaderState, bufferState.IsFinalBlock, - new ReadOnlySpan(bufferState.Buffer, start, bufferState.BytesInBuffer), + bufferState.Bytes, options, ref readStack, converter); - Debug.Assert(readStack.BytesConsumed <= bufferState.BytesInBuffer); - int bytesConsumed = checked((int)readStack.BytesConsumed); - - bufferState.BytesInBuffer -= bytesConsumed; - - // The reader should have thrown if we have remaining bytes. - Debug.Assert(!bufferState.IsFinalBlock || bufferState.BytesInBuffer == 0); - - if (!bufferState.IsFinalBlock) - { - // Check if we need to shift or expand the buffer because there wasn't enough data to complete deserialization. - if ((uint)bufferState.BytesInBuffer > ((uint)bufferState.Buffer.Length / 2)) - { - // We have less than half the buffer available, double the buffer size. - byte[] oldBuffer = bufferState.Buffer; - int oldClearMax = bufferState.ClearMax; - byte[] newBuffer = ArrayPool.Shared.Rent((bufferState.Buffer.Length < (int.MaxValue / 2)) ? bufferState.Buffer.Length * 2 : int.MaxValue); - - // Copy the unprocessed data to the new buffer while shifting the processed bytes. - Buffer.BlockCopy(oldBuffer, bytesConsumed + start, newBuffer, 0, bufferState.BytesInBuffer); - bufferState.Buffer = newBuffer; - bufferState.ClearMax = bufferState.BytesInBuffer; - - // Clear and return the old buffer - new Span(oldBuffer, 0, oldClearMax).Clear(); - ArrayPool.Shared.Return(oldBuffer); - } - else if (bufferState.BytesInBuffer != 0) - { - // Shift the processed bytes to the beginning of buffer to make more room. - Buffer.BlockCopy(bufferState.Buffer, bytesConsumed + start, bufferState.Buffer, 0, bufferState.BytesInBuffer); - } - } + Debug.Assert(readStack.BytesConsumed <= bufferState.Bytes.Length); + bufferState.AdvanceBuffer((int)readStack.BytesConsumed); return value; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadBufferState.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadBufferState.cs index d909716eb35260..77a55f4198c56e 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadBufferState.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadBufferState.cs @@ -2,32 +2,168 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Buffers; +using System.Diagnostics; +using System.IO; +using System.Threading; +using System.Threading.Tasks; namespace System.Text.Json.Serialization { internal struct ReadBufferState : IDisposable { - public byte[] Buffer; - public int BytesInBuffer; - public int ClearMax; - public bool IsFirstIteration; - public bool IsFinalBlock; + private byte[] _buffer; + private byte _offset; // Read bytes offset typically used when skipping the UTF-8 BOM. + private int _count; // Number of read bytes yet to be consumed by the serializer. + private int _maxCount; // Number of bytes we need to clear before returning the buffer. + private bool _isFirstBlock; + private bool _isFinalBlock; - public ReadBufferState(int defaultBufferSize) + public ReadBufferState(int initialBufferSize) { - Buffer = ArrayPool.Shared.Rent(Math.Max(defaultBufferSize, JsonConstants.Utf8Bom.Length)); - BytesInBuffer = ClearMax = 0; - IsFirstIteration = true; - IsFinalBlock = false; + _buffer = ArrayPool.Shared.Rent(Math.Max(initialBufferSize, JsonConstants.Utf8Bom.Length)); + _maxCount = _count = _offset = 0; + _isFirstBlock = true; + _isFinalBlock = false; + } + + public bool IsFinalBlock => _isFinalBlock; + + public ReadOnlySpan Bytes => _buffer.AsSpan(_offset, _count); + + /// + /// Read from the stream until either our buffer is filled or we hit EOF. + /// Calling ReadCore is relatively expensive, so we minimize the number of times + /// we need to call it. + /// + public readonly async ValueTask ReadFromStreamAsync( + Stream utf8Json, + CancellationToken cancellationToken, + bool fillBuffer = true) + { + // Since mutable structs don't work well with async state machines, + // make all updates on a copy which is returned once complete. + ReadBufferState bufferState = this; + + do + { + int bytesRead = await utf8Json.ReadAsync( +#if BUILDING_INBOX_LIBRARY + bufferState._buffer.AsMemory(bufferState._count), +#else + bufferState._buffer, bufferState._count, bufferState._buffer.Length - bufferState._count, +#endif + cancellationToken).ConfigureAwait(false); + + if (bytesRead == 0) + { + bufferState._isFinalBlock = true; + break; + } + + bufferState._count += bytesRead; + } + while (fillBuffer && bufferState._count < bufferState._buffer.Length); + + bufferState.ProcessReadBytes(); + return bufferState; + } + + /// + /// Read from the stream until either our buffer is filled or we hit EOF. + /// Calling ReadCore is relatively expensive, so we minimize the number of times + /// we need to call it. + /// + public void ReadFromStream(Stream utf8Json) + { + do + { + int bytesRead = utf8Json.Read( +#if BUILDING_INBOX_LIBRARY + _buffer.AsSpan(_count)); +#else + _buffer, _count, _buffer.Length - _count); +#endif + + if (bytesRead == 0) + { + _isFinalBlock = true; + break; + } + + _count += bytesRead; + } + while (_count < _buffer.Length); + + ProcessReadBytes(); + } + + /// + /// Advances the buffer in anticipation of a subsequent read operation. + /// + public void AdvanceBuffer(int bytesConsumed) + { + Debug.Assert(bytesConsumed <= _count); + Debug.Assert(!_isFinalBlock || _count == bytesConsumed, "The reader should have thrown if we have remaining bytes."); + + _count -= bytesConsumed; + + if (!_isFinalBlock) + { + // Check if we need to shift or expand the buffer because there wasn't enough data to complete deserialization. + if ((uint)_count > ((uint)_buffer.Length / 2)) + { + // We have less than half the buffer available, double the buffer size. + byte[] oldBuffer = _buffer; + int oldMaxCount = _maxCount; + byte[] newBuffer = ArrayPool.Shared.Rent((_buffer.Length < (int.MaxValue / 2)) ? _buffer.Length * 2 : int.MaxValue); + + // Copy the unprocessed data to the new buffer while shifting the processed bytes. + Buffer.BlockCopy(oldBuffer, _offset + bytesConsumed, newBuffer, 0, _count); + _buffer = newBuffer; + _offset = 0; + _maxCount = _count; + + // Clear and return the old buffer + new Span(oldBuffer, 0, oldMaxCount).Clear(); + ArrayPool.Shared.Return(oldBuffer); + } + else if (_count != 0) + { + // Shift the processed bytes to the beginning of buffer to make more room. + Buffer.BlockCopy(_buffer, _offset + bytesConsumed, _buffer, 0, _count); + _offset = 0; + } + } + } + + private void ProcessReadBytes() + { + if (_count > _maxCount) + { + _maxCount = _count; + } + + if (_isFirstBlock) + { + _isFirstBlock = false; + + // Handle the UTF-8 BOM if present + Debug.Assert(_buffer.Length >= JsonConstants.Utf8Bom.Length); + if (_buffer.AsSpan(0, _count).StartsWith(JsonConstants.Utf8Bom)) + { + _offset = (byte)JsonConstants.Utf8Bom.Length; + _count -= JsonConstants.Utf8Bom.Length; + } + } } public void Dispose() { // Clear only what we used and return the buffer to the pool - new Span(Buffer, 0, ClearMax).Clear(); + new Span(_buffer, 0, _maxCount).Clear(); - byte[] toReturn = Buffer; - Buffer = null!; + byte[] toReturn = _buffer; + _buffer = null!; ArrayPool.Shared.Return(toReturn); } From 6ecdf9ed04cc777fa20e9917b0a6cc6720b6e5b1 Mon Sep 17 00:00:00 2001 From: Sapana-Khemkar <94051076+Sapana-Khemkar@users.noreply.github.com> Date: Fri, 10 Jun 2022 21:34:28 +0530 Subject: [PATCH 041/337] [mono] add support to build for ppc64le architecture (#68802) * mono add support to build for ppc64le * fix build failures in mini-ppc.c * handle unhandled exception ids * donot use std/ld inst when address is not div by 4. This adds fix for test failure in System.Buffers.Binary.Tests.BinaryReaderUnitTestsw.ReadingStructFieldByFieldOrReadAndReverseEndianness * Fixed failing test cases from System.Numerics.Vectors.Tests * change objcopy name for ppc64le from ppc64le-linux-gnu-objcopy to powerpcle-linux-gnu-objcopy --- src/mono/CMakeLists.txt | 11 ++- .../System.Private.CoreLib.csproj | 6 +- src/mono/mono.proj | 8 ++ src/mono/mono/arch/ppc/ppc-codegen.h | 1 + src/mono/mono/mini/CMakeLists.txt | 15 ++++ src/mono/mono/mini/mini-ppc.c | 73 +++++++++++++------ src/mono/mono/utils/CMakeLists.txt | 2 + 7 files changed, 92 insertions(+), 24 deletions(-) diff --git a/src/mono/CMakeLists.txt b/src/mono/CMakeLists.txt index bc3bc96caa1bef..fd38892822c719 100644 --- a/src/mono/CMakeLists.txt +++ b/src/mono/CMakeLists.txt @@ -375,6 +375,8 @@ elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "s390x") set(HOST_S390X 1) elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "wasm" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "wasm32") set(HOST_WASM 1) +elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64le") + set(HOST_POWERPC64 1) else() message(FATAL_ERROR "CMAKE_SYSTEM_PROCESSOR='${CMAKE_SYSTEM_PROCESSOR}' not supported.") endif() @@ -448,8 +450,13 @@ elseif(TARGET_ARCH STREQUAL "wasm" OR TARGET_ARCH STREQUAL "wasm32") set(TARGET_SIZEOF_VOID_P 4) set(SIZEOF_REGISTER 4) elseif(TARGET_ARCH STREQUAL "ppc64le") - # TODO: not complete - set(__mono_ppc64__ 1) + set(TARGET_POWERPC 1) + set(TARGET_POWERPC64 1) + set(MONO_ARCHITECTURE "\"ppc64le\"") + set(TARGET_SIZEOF_VOID_P 8) + set(SIZEOF_REGISTER 8) + add_definitions("-D__mono_ppc__") + add_definitions("-D__mono_ppc64__") else() message(FATAL_ERROR "TARGET_ARCH='${TARGET_ARCH}' not supported.") endif() diff --git a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj index b66fe9404973f3..d11987e6305c26 100644 --- a/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj +++ b/src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj @@ -10,7 +10,7 @@ $(RuntimeBinDir)IL/ Debug;Release;Checked - x64;x86;arm;armv6;arm64;s390x;wasm + x64;x86;arm;armv6;arm64;s390x;wasm;ppc64le true @@ -75,6 +75,10 @@ AnyCPU $(DefineConstants);TARGET_WASM + + AnyCPU + $(DefineConstants);TARGET_POWERPC64 + diff --git a/src/mono/mono.proj b/src/mono/mono.proj index 3b9ff636a63bbd..9e90b9134fb103 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -265,6 +265,13 @@ <_MonoBuildEnv Include="PKG_CONFIG_PATH=$(MonoCrossDir)/usr/lib/s390x-linux-gnu/pkgconfig" /> + + + <_MonoCMakeArgs Include="-DCMAKE_TOOLCHAIN_FILE=$(CrossToolchainFile)" /> + <_MonoBuildEnv Include="TARGET_BUILD_ARCH=ppc64le" /> + <_MonoBuildEnv Include="PKG_CONFIG_PATH=$(MonoCrossDir)/usr/lib/powerpc64le-linux-gnu/pkgconfig" /> + + <_MonoCMakeArgs Include="-DCMAKE_TOOLCHAIN_FILE=$(CrossToolchainFile)" /> @@ -546,6 +553,7 @@ <_Objcopy Condition="'$(Platform)' == 'armv6'">arm-linux-$(_LinuxAbi)eabi$(_LinuxFloatAbi)-$(_Objcopy) <_Objcopy Condition="'$(Platform)' == 'arm64'">aarch64-linux-$(_LinuxAbi)-$(_Objcopy) <_Objcopy Condition="'$(Platform)' == 's390x'">s390x-linux-$(_LinuxAbi)-$(_Objcopy) + <_Objcopy Condition="'$(Platform)' == 'ppc64le'">powerpc64le-linux-$(_LinuxAbi)-$(_Objcopy) <_Objcopy Condition="'$(Platform)' == 'x64'">x86_64-linux-$(_LinuxAbi)-$(_Objcopy) <_Objcopy Condition="'$(Platform)' == 'x86'">i686-linux-$(_LinuxAbi)-$(_Objcopy) <_Objcopy Condition="'$(TargetsAndroid)' == 'true' or '$(TargetsLinuxBionic)' == 'true'">$(ANDROID_NDK_ROOT)/toolchains/llvm/prebuilt/$(MonoToolchainPrebuiltOS)/bin/llvm-objcopy diff --git a/src/mono/mono/arch/ppc/ppc-codegen.h b/src/mono/mono/arch/ppc/ppc-codegen.h index a52d17ab767f0c..ca3c13791ffda9 100644 --- a/src/mono/mono/arch/ppc/ppc-codegen.h +++ b/src/mono/mono/arch/ppc/ppc-codegen.h @@ -129,6 +129,7 @@ enum { #define ppc_is_imm16(val) ((((val)>> 15) == 0) || (((val)>> 15) == -1)) #define ppc_is_uimm16(val) ((glong)(val) >= 0L && (glong)(val) <= 65535L) #define ppc_ha(val) (((val >> 16) + ((val & 0x8000) ? 1 : 0)) & 0xffff) +#define ppc_is_dsoffset_valid(offset) (((offset)& 3) == 0) #define ppc_load32(c,D,v) G_STMT_START { \ ppc_lis ((c), (D), (guint32)(v) >> 16); \ diff --git a/src/mono/mono/mini/CMakeLists.txt b/src/mono/mono/mini/CMakeLists.txt index 76e1184c60d4a0..5c85f9d9275b91 100644 --- a/src/mono/mono/mini/CMakeLists.txt +++ b/src/mono/mono/mini/CMakeLists.txt @@ -222,6 +222,13 @@ set(wasm_sources exceptions-wasm.c cpu-wasm.h) +set(powerpc64_sources + mini-ppc.c + mini-ppc.h + exceptions-ppc.c + tramp-ppc.c + cpu-ppc64.h) + if(TARGET_AMD64) set(arch_sources ${amd64_sources}) elseif(TARGET_X86) @@ -234,6 +241,8 @@ elseif(TARGET_S390X) set(arch_sources ${s390x_sources}) elseif(TARGET_WASM) set(arch_sources ${wasm_sources}) +elseif(TARGET_POWERPC) +set(arch_sources ${powerpc64_sources}) endif() set(darwin_sources @@ -480,6 +489,12 @@ add_custom_command( VERBATIM ) +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cpu-ppc64.h + COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_POWERPC ${CMAKE_CURRENT_SOURCE_DIR} cpu-ppc64.h ppc64_cpu_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-ppc64.mdesc + VERBATIM +) + if(NOT DISABLE_EXECUTABLES) set(main_sources "main.c") if(HOST_WIN32) diff --git a/src/mono/mono/mini/mini-ppc.c b/src/mono/mono/mini/mini-ppc.c index a50ddc6b89cb9d..581775a34613c3 100644 --- a/src/mono/mono/mini/mini-ppc.c +++ b/src/mono/mono/mini/mini-ppc.c @@ -1179,23 +1179,35 @@ get_call_info (MonoMethodSignature *sig) } else #endif { - align_size += (sizeof (target_mgreg_t) - 1); - align_size &= ~(sizeof (target_mgreg_t) - 1); - nregs = (align_size + sizeof (target_mgreg_t) -1 ) / sizeof (target_mgreg_t); - n_in_regs = MIN (rest, nregs); - if (n_in_regs < 0) - n_in_regs = 0; + if (is_all_floats && (mbr_cnt > 0)) { + rest = PPC_LAST_ARG_REG - gr + 1; + nregs = mbr_cnt; + n_in_regs = (rest >= mbr_cnt) ? MIN (rest, nregs) : 0; + cinfo->args [n].regtype = RegTypeStructByVal; + cinfo->args [n].vtregs = n_in_regs; + cinfo->args [n].size = mbr_size; + cinfo->args [n].vtsize = nregs - n_in_regs; + cinfo->args [n].reg = gr; + gr += n_in_regs; + } else { + align_size += (sizeof (target_mgreg_t) - 1); + align_size &= ~(sizeof (target_mgreg_t) - 1); + nregs = (align_size + sizeof (target_mgreg_t) -1 ) / sizeof (target_mgreg_t); + n_in_regs = MIN (rest, nregs); + if (n_in_regs < 0) + n_in_regs = 0; #ifdef __APPLE__ - /* FIXME: check this */ - if (size >= 3 && size % 4 != 0) - n_in_regs = 0; + /* FIXME: check this */ + if (size >= 3 && size % 4 != 0) + n_in_regs = 0; #endif - cinfo->args [n].regtype = RegTypeStructByVal; - cinfo->args [n].vtregs = n_in_regs; - cinfo->args [n].size = n_in_regs; - cinfo->args [n].vtsize = nregs - n_in_regs; - cinfo->args [n].reg = gr; - gr += n_in_regs; + cinfo->args [n].regtype = RegTypeStructByVal; + cinfo->args [n].vtregs = n_in_regs; + cinfo->args [n].size = n_in_regs; + cinfo->args [n].vtsize = nregs - n_in_regs; + cinfo->args [n].reg = gr; + gr += n_in_regs; + } } #ifdef __mono_ppc64__ @@ -1824,7 +1836,7 @@ void mono_arch_emit_setret (MonoCompile *cfg, MonoMethod *method, MonoInst *val) { MonoType *ret = mini_get_underlying_type (mono_method_signature_internal (method)->ret); - if (!rm_type_is_byref (ret)) { + if (!m_type_is_byref (ret)) { #ifndef __mono_ppc64__ if (ret->type == MONO_TYPE_I8 || ret->type == MONO_TYPE_U8) { MonoInst *ins; @@ -1963,7 +1975,7 @@ mono_arch_peephole_pass_2 (MonoCompile *cfg, MonoBasicBlock *bb) MONO_DELETE_INS (bb, ins); continue; } - } else if (inst->inst_imm > 0) { + } else if (ins->inst_imm > 0) { int power2 = mono_is_power_of_two (ins->inst_imm); if (power2 > 0) { ins->opcode = OP_SHL_IMM; @@ -3116,7 +3128,12 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) break; case OP_STORE_MEMBASE_REG: if (ppc_is_imm16 (ins->inst_offset)) { - ppc_stptr (code, ins->sreg1, ins->inst_offset, ins->inst_destbasereg); + if (ppc_is_dsoffset_valid(ins->inst_offset)) { + ppc_stptr (code, ins->sreg1, ins->inst_offset, ins->inst_destbasereg); + } else { + ppc_load (code, ppc_r0, ins->inst_offset); + ppc_stptr_indexed(code, ins->sreg1, ins->inst_destbasereg, ppc_r0); + } } else { if (ppc_is_imm32 (ins->inst_offset)) { ppc_addis (code, ppc_r11, ins->inst_destbasereg, ppc_ha(ins->inst_offset)); @@ -3151,7 +3168,12 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) break; case OP_LOAD_MEMBASE: if (ppc_is_imm16 (ins->inst_offset)) { - ppc_ldptr (code, ins->dreg, ins->inst_offset, ins->inst_basereg); + if( ppc_is_dsoffset_valid (ins->inst_offset)) { + ppc_ldptr (code, ins->dreg, ins->inst_offset, ins->inst_basereg); + } else { + ppc_load (code, ppc_r0, ins->inst_offset); + ppc_ldptr_indexed (code, ins->dreg, ins->inst_basereg, ppc_r0); + } } else { if (ppc_is_imm32 (ins->inst_offset) && (ins->dreg > 0)) { ppc_addis (code, ins->dreg, ins->inst_basereg, ppc_ha(ins->inst_offset)); @@ -3165,7 +3187,12 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) case OP_LOADI4_MEMBASE: #ifdef __mono_ppc64__ if (ppc_is_imm16 (ins->inst_offset)) { - ppc_lwa (code, ins->dreg, ins->inst_offset, ins->inst_basereg); + if(ppc_is_dsoffset_valid (ins->inst_offset)) { + ppc_lwa (code, ins->dreg, ins->inst_offset, ins->inst_basereg); + } else { + ppc_load (code, ppc_r0, ins->inst_offset); + ppc_lwax (code, ins->dreg, ins->inst_basereg, ppc_r0); + } } else { if (ppc_is_imm32 (ins->inst_offset) && (ins->dreg > 0)) { ppc_addis (code, ins->dreg, ins->inst_basereg, ppc_ha(ins->inst_offset)); @@ -5309,6 +5336,10 @@ exception_id_by_name (const char *name) return MONO_EXC_ARRAY_TYPE_MISMATCH; if (strcmp (name, "ArgumentException") == 0) return MONO_EXC_ARGUMENT; + if (strcmp (name, "ArgumentOutOfRangeException") == 0) + return MONO_EXC_ARGUMENT_OUT_OF_RANGE; + if (strcmp (name, "OutOfMemoryException") == 0) + return MONO_EXC_ARGUMENT_OUT_OF_MEMORY; g_error ("Unknown intrinsic exception %s\n", name); return 0; } @@ -5753,7 +5784,7 @@ host_mgreg_t* mono_arch_context_get_int_reg_address (MonoContext *ctx, int reg) { if (reg == ppc_r1) - return (host_mgreg_t)(gsize)&MONO_CONTEXT_GET_SP (ctx); + return (host_mgreg_t)(gsize)MONO_CONTEXT_GET_SP (ctx); return &ctx->regs [reg]; } diff --git a/src/mono/mono/utils/CMakeLists.txt b/src/mono/mono/utils/CMakeLists.txt index d0a01e77935507..47634e0be3e9fa 100644 --- a/src/mono/mono/utils/CMakeLists.txt +++ b/src/mono/mono/utils/CMakeLists.txt @@ -221,6 +221,8 @@ elseif(TARGET_S390X) set(utils_arch_sources "${utils_arch_sources};mono-hwcap-s390x.c") elseif(TARGET_WASM) set(utils_arch_sources "${utils_arch_sources};mono-hwcap-wasm.c;mono-mmap-wasm.c") +elseif(TARGET_POWERPC) +set(utils_arch_sources "${utils_arch_sources};mono-hwcap-ppc.c") else() message(FATAL_ERROR "") endif() From b2143be9d09dc5cab47815b9f00ed5b0cb3a466f Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Fri, 10 Jun 2022 12:55:14 -0400 Subject: [PATCH 042/337] Use Stream.CopyToAsync in OCSP download on Linux (#70567) --- .../Common/src/System/Net/Http/X509ResourceClient.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libraries/Common/src/System/Net/Http/X509ResourceClient.cs b/src/libraries/Common/src/System/Net/Http/X509ResourceClient.cs index c2e36bae468ebb..ae6c0a17f95334 100644 --- a/src/libraries/Common/src/System/Net/Http/X509ResourceClient.cs +++ b/src/libraries/Common/src/System/Net/Http/X509ResourceClient.cs @@ -227,7 +227,14 @@ internal static partial class X509ResourceClient using Stream responseStream = (Stream)readAsStreamMethod.Invoke(content, null)!; var result = new MemoryStream(); - responseStream.CopyTo(result); + if (async) + { + await responseStream.CopyToAsync(result).ConfigureAwait(false); + } + else + { + responseStream.CopyTo(result); + } ((IDisposable)responseMessage).Dispose(); return result.ToArray(); }; From f37d44ac926ba77a53e9e2f60d4461b756d7aece Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Fri, 10 Jun 2022 12:55:28 -0400 Subject: [PATCH 043/337] Remove unnecessary CS8601 suppression from SSPIHandleCache.cs (#70565) --- .../Common/src/System/Net/Security/SSPIHandleCache.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/libraries/Common/src/System/Net/Security/SSPIHandleCache.cs b/src/libraries/Common/src/System/Net/Security/SSPIHandleCache.cs index 15a67dee335e1d..0b98ca2c82a0b3 100644 --- a/src/libraries/Common/src/System/Net/Security/SSPIHandleCache.cs +++ b/src/libraries/Common/src/System/Net/Security/SSPIHandleCache.cs @@ -11,8 +11,8 @@ namespace System.Net.Security // internal static class SSPIHandleCache { - private const int c_MaxCacheSize = 0x1F; // must a (power of 2) - 1 - private static readonly SafeCredentialReference?[] s_cacheSlots = new SafeCredentialReference[c_MaxCacheSize + 1]; + private const int MaxCacheSize = 0x1F; // must a (power of 2) - 1 + private static readonly SafeCredentialReference?[] s_cacheSlots = new SafeCredentialReference[MaxCacheSize + 1]; private static int s_current = -1; internal static void CacheCredential(SafeFreeCredentials newHandle) @@ -25,12 +25,9 @@ internal static void CacheCredential(SafeFreeCredentials newHandle) return; } - int index = Interlocked.Increment(ref s_current) & c_MaxCacheSize; -#pragma warning disable CS8601 // Possible null reference assignment. - newRef = Interlocked.Exchange(ref s_cacheSlots[index], newRef); -#pragma warning restore CS8601 // Possible null reference assignment. + int index = Interlocked.Increment(ref s_current) & MaxCacheSize; - newRef?.Dispose(); + Interlocked.Exchange(ref s_cacheSlots[index], newRef)?.Dispose(); } catch (Exception e) { From 42356f209e412c63c536c4c137ee19043e5c442a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Fri, 10 Jun 2022 19:00:22 +0200 Subject: [PATCH 044/337] Update dependencies from https://github.com/dotnet/xharness build 20220610.1 (#70566) Microsoft.DotNet.XHarness.CLI , Microsoft.DotNet.XHarness.TestRunners.Common , Microsoft.DotNet.XHarness.TestRunners.Xunit From Version 1.0.0-prerelease.22305.1 -> To Version 1.0.0-prerelease.22310.1 Co-authored-by: dotnet-maestro[bot] --- .config/dotnet-tools.json | 2 +- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 76d5359f980ba1..8ae6cf1f84e9d6 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -15,7 +15,7 @@ ] }, "microsoft.dotnet.xharness.cli": { - "version": "1.0.0-prerelease.22305.1", + "version": "1.0.0-prerelease.22310.1", "commands": [ "xharness" ] diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 82eaf6103f8976..5f87f4276cb439 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -242,17 +242,17 @@ https://github.com/dotnet/linker 978b631362f2ffdccdf63fbe3ffe59dfe985ae3d - + https://github.com/dotnet/xharness - a1d9a67e971fc0b8724507847491fe93f65728db + 43e9fe312ac5513edf763877ce9ebf5d57ca9f88 - + https://github.com/dotnet/xharness - a1d9a67e971fc0b8724507847491fe93f65728db + 43e9fe312ac5513edf763877ce9ebf5d57ca9f88 - + https://github.com/dotnet/xharness - a1d9a67e971fc0b8724507847491fe93f65728db + 43e9fe312ac5513edf763877ce9ebf5d57ca9f88 https://github.com/dotnet/arcade diff --git a/eng/Versions.props b/eng/Versions.props index 8b89ed4279fc86..32199b5ec1b38b 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -150,9 +150,9 @@ 1.1.0 16.9.0-preview-20201201-01 - 1.0.0-prerelease.22305.1 - 1.0.0-prerelease.22305.1 - 1.0.0-prerelease.22305.1 + 1.0.0-prerelease.22310.1 + 1.0.0-prerelease.22310.1 + 1.0.0-prerelease.22310.1 1.1.0-alpha.0.22306.2 2.4.2-pre.22 0.12.0-pre.20 From fae7ee8e7e3aa7f86836318a10ed676641e813ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Fri, 10 Jun 2022 19:01:18 +0200 Subject: [PATCH 045/337] Remove Android crypto internals from System.Security.Cryptography.X509Certificates tests (#70554) * Remove Android crypto internals from System.Security.Cryptography.X509Certificates tests The `Interop.AndroidCrypto.X509ChainSupportsRevocationOptions` internally just checks that a certain Java class exists, we can assume it is always there on Android API 24+. This allows us to remove a bunch of internal crypto code from the tests. * Remove unused managed API --- .../Interop.X509Chain.cs | 4 ---- .../RevocationTests/DynamicRevocationTests.Android.cs | 2 +- ...Security.Cryptography.X509Certificates.Tests.csproj | 10 ---------- .../pal_x509chain.c | 6 +++--- .../pal_x509chain.h | 5 ----- 5 files changed, 4 insertions(+), 23 deletions(-) diff --git a/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.X509Chain.cs b/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.X509Chain.cs index 996b0de5513f59..0e5a9a7e724266 100644 --- a/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.X509Chain.cs +++ b/src/libraries/Common/src/Interop/Android/System.Security.Cryptography.Native.Android/Interop.X509Chain.cs @@ -98,10 +98,6 @@ internal static partial int X509ChainSetCustomTrustStore( IntPtr[] customTrustStore, int customTrustStoreLen); - [LibraryImport(Libraries.AndroidCryptoNative, EntryPoint = "AndroidCryptoNative_X509ChainSupportsRevocationOptions")] - [return:MarshalAs(UnmanagedType.U1)] - internal static partial bool X509ChainSupportsRevocationOptions(); - [LibraryImport(Libraries.AndroidCryptoNative, EntryPoint = "AndroidCryptoNative_X509ChainValidate")] internal static partial int X509ChainValidate( SafeX509ChainContextHandle ctx, diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/DynamicRevocationTests.Android.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/DynamicRevocationTests.Android.cs index fd733341851fcd..7d58459af276ab 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/DynamicRevocationTests.Android.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/DynamicRevocationTests.Android.cs @@ -11,6 +11,6 @@ namespace System.Security.Cryptography.X509Certificates.Tests.RevocationTests { public static partial class DynamicRevocationTests { - public static bool SupportsDynamicRevocation { get; } = Interop.AndroidCrypto.X509ChainSupportsRevocationOptions(); + public static bool SupportsDynamicRevocation { get; } = OperatingSystem.IsAndroidVersionAtLeast(24); } } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/System.Security.Cryptography.X509Certificates.Tests.csproj b/src/libraries/System.Security.Cryptography.X509Certificates/tests/System.Security.Cryptography.X509Certificates.Tests.csproj index bda7909c02c85e..50d8fa1b5989cb 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/System.Security.Cryptography.X509Certificates.Tests.csproj +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/System.Security.Cryptography.X509Certificates.Tests.csproj @@ -124,16 +124,6 @@ - - - - - diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_x509chain.c b/src/native/libs/System.Security.Cryptography.Native.Android/pal_x509chain.c index a8b24a097bc4e8..f3d99362967c3b 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_x509chain.c +++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_x509chain.c @@ -428,7 +428,7 @@ int32_t AndroidCryptoNative_X509ChainSetCustomTrustStore(X509ChainContext* ctx, return CheckJNIExceptions(env) ? FAIL : SUCCESS; } -bool AndroidCryptoNative_X509ChainSupportsRevocationOptions(void) +static bool X509ChainSupportsRevocationOptions(void) { return g_CertPathValidatorGetRevocationChecker != NULL && g_PKIXRevocationCheckerClass != NULL; } @@ -507,7 +507,7 @@ static int32_t ValidateWithRevocation(JNIEnv* env, else { certPathToUse = ctx->certPath; - if (AndroidCryptoNative_X509ChainSupportsRevocationOptions()) + if (X509ChainSupportsRevocationOptions()) { // Only add the ONLY_END_ENTITY if we are not just checking the trust anchor. If ONLY_END_ENTITY is // specified, revocation checking will skip the trust anchor even if it is the only certificate. @@ -536,7 +536,7 @@ static int32_t ValidateWithRevocation(JNIEnv* env, } jobject params = ctx->params; - if (AndroidCryptoNative_X509ChainSupportsRevocationOptions()) + if (X509ChainSupportsRevocationOptions()) { // PKIXRevocationChecker checker = validator.getRevocationChecker(); loc[checker] = (*env)->CallObjectMethod(env, validator, g_CertPathValidatorGetRevocationChecker); diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_x509chain.h b/src/native/libs/System.Security.Cryptography.Native.Android/pal_x509chain.h index 4c92fa74c56594..35ed119cc758dd 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_x509chain.h +++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_x509chain.h @@ -62,11 +62,6 @@ PALEXPORT int32_t AndroidCryptoNative_X509ChainSetCustomTrustStore(X509ChainCont jobject* /*X509Certificate[]*/ customTrustStore, int32_t customTrustStoreLen); -/* -Returns true if revocation checking is supported. Returns false otherwise. -*/ -PALEXPORT bool AndroidCryptoNative_X509ChainSupportsRevocationOptions(void); - // Matches managed X509RevocationMode enum enum { From b22fcf4e7bac2a61413509b36cb4ba3b0c864c2f Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Fri, 10 Jun 2022 22:31:59 +0200 Subject: [PATCH 046/337] Move a morph opt to post-order (#69984) When changing the shape of child nodes in pre-order we must ensure we properly morph potential promoted/demoted child nodes. Normally this happens inside fgMorphTree which does it for child nodes, but this specific transform was not calling fgMorphTree on the parent tree after changing the shape of child nodes. The simplest fix is just to move the optimization to post-order which catches more cases and does not need to bother dealing with this. Fix #61074 --- src/coreclr/jit/morph.cpp | 30 ++++++------- .../JitBlue/Runtime_61074/Runtime_61074.cs | 45 +++++++++++++++++++ .../Runtime_61074/Runtime_61074.csproj | 9 ++++ 3 files changed, 68 insertions(+), 16 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_61074/Runtime_61074.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_61074/Runtime_61074.csproj diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index d41ad4babb6790..26157da548943a 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -10284,22 +10284,6 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac) case GT_MUL: noway_assert(op2 != nullptr); - if (opts.OptimizationEnabled() && !optValnumCSE_phase && !tree->gtOverflow()) - { - // MUL(NEG(a), C) => MUL(a, NEG(C)) - if (op1->OperIs(GT_NEG) && !op1->gtGetOp1()->IsCnsIntOrI() && op2->IsCnsIntOrI() && - !op2->IsIconHandle()) - { - GenTree* newOp1 = op1->gtGetOp1(); - GenTree* newConst = gtNewIconNode(-op2->AsIntCon()->IconValue(), op2->TypeGet()); - DEBUG_DESTROY_NODE(op1); - DEBUG_DESTROY_NODE(op2); - tree->AsOp()->gtOp1 = newOp1; - tree->AsOp()->gtOp2 = newConst; - return fgMorphSmpOp(tree, mac); - } - } - #ifndef TARGET_64BIT if (typ == TYP_LONG) { @@ -12910,6 +12894,20 @@ GenTree* Compiler::fgOptimizeMultiply(GenTreeOp* mul) if (op2->IsIntegralConst()) { + // We should not get here for 64-bit multiplications on 32-bit. + assert(op2->IsCnsIntOrI()); + + // MUL(NEG(a), C) => MUL(a, NEG(C)) + if (opts.OptimizationEnabled() && op1->OperIs(GT_NEG) && !op2->IsIconHandle()) + { + mul->gtOp1 = op1->AsUnOp()->gtGetOp1(); + op2->AsIntCon()->gtIconVal = -op2->AsIntCon()->gtIconVal; + fgUpdateConstTreeValueNumber(op2); + DEBUG_DESTROY_NODE(op1); + + op1 = mul->gtOp1; + } + ssize_t mult = op2->AsIntConCommon()->IconValue(); if (mult == 0) diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_61074/Runtime_61074.cs b/src/tests/JIT/Regression/JitBlue/Runtime_61074/Runtime_61074.cs new file mode 100644 index 00000000000000..9f1683cf92371d --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_61074/Runtime_61074.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. + +// Adapted from a Fuzzlyn example: +// Generated by Fuzzlyn v1.5 on 2021-10-31 16:57:02 +// Run on X64 Windows +// Seed: 701457804295464207 +// Reduced from 37.8 KiB to 0.3 KiB in 00:00:50 +// Hits JIT assert in Release: +// Assertion failed '!parentStruct->lvUndoneStructPromotion' in 'Program:M2(S0)' during 'Mark local vars' (IL size 33) +// +// File: D:\a\_work\1\s\src\coreclr\jit\lclvars.cpp Line: 4039 +// +using System; +using System.Runtime.CompilerServices; + +public struct S0 +{ + public long F0; + public long F1; +} + +public class Runtime_61074 +{ + public static int Main() + { + S0 vr4 = new S0 { F0 = 10, F1 = -1 }; + long result = WeirdAnd(vr4); + if (result == 10) + { + Console.WriteLine("PASS"); + return 100; + } + + Console.WriteLine("FAIL: Result {0} != 10 as expected", result); + return -1; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static long WeirdAnd(S0 arg4) + { + long result = (-arg4.F0 * -1) & arg4.F1--; + return result; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_61074/Runtime_61074.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_61074/Runtime_61074.csproj new file mode 100644 index 00000000000000..f492aeac9d056b --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_61074/Runtime_61074.csproj @@ -0,0 +1,9 @@ + + + Exe + True + + + + + \ No newline at end of file From 933dbb15b8dda4ac280cce1cf8082c58c302afb2 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Fri, 10 Jun 2022 22:56:02 +0200 Subject: [PATCH 047/337] Avoid discarding upper bits when folding GT_SWITCH (#69986) --- src/coreclr/jit/fgopt.cpp | 7 +- src/coreclr/jit/morph.cpp | 34 +++--- .../JitBlue/Runtime_68568/Runtime_68568.il | 107 ++++++++++++++++++ .../Runtime_68568/Runtime_68568.ilproj | 12 ++ src/tests/issues.targets | 3 + 5 files changed, 142 insertions(+), 21 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_68568/Runtime_68568.il create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_68568/Runtime_68568.ilproj diff --git a/src/coreclr/jit/fgopt.cpp b/src/coreclr/jit/fgopt.cpp index d0d4ae647ec989..360633d901e939 100644 --- a/src/coreclr/jit/fgopt.cpp +++ b/src/coreclr/jit/fgopt.cpp @@ -3221,8 +3221,10 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block) if (verbose) { printf("\nConverting a switch (" FMT_BB ") with only one significant clause besides a default target to a " - "conditional branch\n", + "conditional branch. Before:\n", block->bbNum); + + gtDispTree(switchTree); } #endif // DEBUG @@ -3247,6 +3249,9 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block) block->bbJumpDest = block->bbJumpSwt->bbsDstTab[0]; block->bbJumpKind = BBJ_COND; + JITDUMP("After:\n"); + DISPNODE(switchTree); + return true; } return returnvalue; diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 26157da548943a..29f10051e79f04 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -14922,18 +14922,16 @@ Compiler::FoldResult Compiler::fgFoldConditional(BasicBlock* block) noway_assert(lastStmt->GetRootNode()->gtOper == GT_SWITCH); - /* Did we fold the conditional */ + // Did we fold the conditional noway_assert(lastStmt->GetRootNode()->AsOp()->gtOp1); - GenTree* condTree; - condTree = lastStmt->GetRootNode()->AsOp()->gtOp1; - GenTree* cond; - cond = condTree->gtEffectiveVal(true); + GenTree* condTree = lastStmt->GetRootNode()->AsOp()->gtOp1; + GenTree* cond = condTree->gtEffectiveVal(true); if (cond->OperIsConst()) { - /* Yupee - we folded the conditional! - * Remove the conditional statement */ + // Yupee - we folded the conditional! + // Remove the conditional statement noway_assert(cond->gtOper == GT_CNS_INT); @@ -14951,17 +14949,13 @@ Compiler::FoldResult Compiler::fgFoldConditional(BasicBlock* block) result = FoldResult::FOLD_REMOVED_LAST_STMT; } - /* modify the flow graph */ + // modify the flow graph - /* Find the actual jump target */ - unsigned switchVal; - switchVal = (unsigned)cond->AsIntCon()->gtIconVal; - unsigned jumpCnt; - jumpCnt = block->bbJumpSwt->bbsCount; - BasicBlock** jumpTab; - jumpTab = block->bbJumpSwt->bbsDstTab; - bool foundVal; - foundVal = false; + // Find the actual jump target + size_t switchVal = (size_t)cond->AsIntCon()->gtIconVal; + unsigned jumpCnt = block->bbJumpSwt->bbsCount; + BasicBlock** jumpTab = block->bbJumpSwt->bbsDstTab; + bool foundVal = false; for (unsigned val = 0; val < jumpCnt; val++, jumpTab++) { @@ -14976,20 +14970,20 @@ Compiler::FoldResult Compiler::fgFoldConditional(BasicBlock* block) { if (curJump != block->bbNext) { - /* transform the basic block into a BBJ_ALWAYS */ + // transform the basic block into a BBJ_ALWAYS block->bbJumpKind = BBJ_ALWAYS; block->bbJumpDest = curJump; } else { - /* transform the basic block into a BBJ_NONE */ + // transform the basic block into a BBJ_NONE block->bbJumpKind = BBJ_NONE; } foundVal = true; } else { - /* Remove 'block' from the predecessor list of 'curJump' */ + // Remove 'block' from the predecessor list of 'curJump' fgRemoveRefPred(curJump, block); } } diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_68568/Runtime_68568.il b/src/tests/JIT/Regression/JitBlue/Runtime_68568/Runtime_68568.il new file mode 100644 index 00000000000000..e1ee96ef39adc6 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_68568/Runtime_68568.il @@ -0,0 +1,107 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// Metadata version: v4.0.30319 +.assembly extern System.Runtime +{ + .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: + .ver 7:0:0:0 +} +.assembly extern System.Console +{ + .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....: + .ver 7:0:0:0 +} +.assembly playground +{ +} + +// =============== CLASS MEMBERS DECLARATION =================== + +.class public auto ansi beforefieldinit Runtime_68568 + extends [System.Runtime]System.Object +{ + .method public hidebysig static int32 Main() cil managed + { + .entrypoint + // Code size 79 (0x4f) + .maxstack 2 + .locals init (bool V_0) + +// Code equivalent to the following, except without the +// int cast that C# adds on switch cases. +// +// switch (unchecked((nuint)0x100000000)) +// { +// case 0: +// pass = sizeof(nint) == 4; +// break; +// case 1: +// pass = false; +// break; +// default: +// pass = sizeof(nint) == 8; +// break; +// } +// +// if (pass) +// { +// Console.WriteLine("PASS"); +// return 100; +// } +// +// Console.WriteLine("FAIL"); +// return -1; + + + IL_0000: ldc.i4.0 + IL_0001: stloc.0 + IL_0002: ldc.i8 0x100000000 + IL_000b: conv.u + IL_000c: switch ( + IL_0025, + IL_0031) + IL_0019: sizeof [System.Runtime]System.IntPtr + IL_001f: ldc.i4.8 + IL_0020: ceq + IL_0022: stloc.0 + IL_0023: br.s IL_0033 + + IL_0025: sizeof [System.Runtime]System.IntPtr + IL_002b: ldc.i4.4 + IL_002c: ceq + IL_002e: stloc.0 + IL_002f: br.s IL_0033 + + IL_0031: ldc.i4.0 + IL_0032: stloc.0 + IL_0033: ldloc.0 + IL_0034: brfalse.s IL_0043 + + IL_0036: ldstr "PASS" + IL_003b: call void [System.Console]System.Console::WriteLine(string) + IL_0040: ldc.i4.s 100 + IL_0042: ret + + IL_0043: ldstr "FAIL" + IL_0048: call void [System.Console]System.Console::WriteLine(string) + IL_004d: ldc.i4.m1 + IL_004e: ret + } // end of method Runtime_68568::Main + + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 7 (0x7) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [System.Runtime]System.Object::.ctor() + IL_0006: ret + } // end of method Runtime_68568::.ctor + +} // end of class Runtime_68568 + + +// ============================================================= + +// *********** DISASSEMBLY COMPLETE *********************** diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_68568/Runtime_68568.ilproj b/src/tests/JIT/Regression/JitBlue/Runtime_68568/Runtime_68568.ilproj new file mode 100644 index 00000000000000..e7c67cc80e8533 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_68568/Runtime_68568.ilproj @@ -0,0 +1,12 @@ + + + Exe + + + None + True + + + + + diff --git a/src/tests/issues.targets b/src/tests/issues.targets index 19201279814a68..a4e91296655d74 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -2201,6 +2201,9 @@ https://github.com/dotnet/runtime/issues/70279 + + Tests coreclr's handling of switches on natively sized integers + From 3a6a6d5ad8cd763656aadc44e536094372d84230 Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Fri, 10 Jun 2022 17:36:52 -0400 Subject: [PATCH 048/337] [Android] Fix failing LocalTzIsNotUtc test (#70485) Add a trait to control when the test executes as we don't have a good way to differentiate between Android emulators and devices. Fixes #70482 --- eng/pipelines/runtime-extra-platforms-other.yml | 4 ++-- eng/pipelines/runtime.yml | 2 +- .../System.Runtime/tests/System.Runtime.Tests.csproj | 7 +++++++ .../System.Runtime/tests/System/TimeZoneInfoTests.cs | 2 ++ 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/eng/pipelines/runtime-extra-platforms-other.yml b/eng/pipelines/runtime-extra-platforms-other.yml index dd8a6e0da07b16..9907d7ed9079ef 100644 --- a/eng/pipelines/runtime-extra-platforms-other.yml +++ b/eng/pipelines/runtime-extra-platforms-other.yml @@ -197,7 +197,7 @@ jobs: jobParameters: testGroup: innerloop nameSuffix: AllSubsets_Mono - buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true $(_runSmokeTestsOnlyArg) /p:BuildTestsOnHelix=true /p:UsePortableRuntimePack=true /p:BuildDarwinFrameworks=true + buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true $(_runSmokeTestsOnlyArg) /p:BuildTestsOnHelix=true /p:EnableAdditionalTimezoneChecks=true /p:UsePortableRuntimePack=true /p:BuildDarwinFrameworks=true timeoutInMinutes: 180 condition: >- or( @@ -361,7 +361,7 @@ jobs: jobParameters: testGroup: innerloop nameSuffix: AllSubsets_Mono - buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg) + buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg) /p:EnableAdditionalTimezoneChecks=true timeoutInMinutes: 180 condition: >- or( diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index 396660f6f5e73c..0cf7e96a580768 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -433,7 +433,7 @@ jobs: jobParameters: testGroup: innerloop nameSuffix: AllSubsets_Mono - buildArgs: -s mono+libs+libs.tests+host+packs -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true /p:RunSmokeTestsOnly=true /p:BuildTestsOnHelix=true /p:UsePortableRuntimePack=true /p:BuildDarwinFrameworks=true + buildArgs: -s mono+libs+libs.tests+host+packs -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true /p:RunSmokeTestsOnly=true /p:BuildTestsOnHelix=true /p:EnableAdditionalTimezoneChecks=true /p:UsePortableRuntimePack=true /p:BuildDarwinFrameworks=true timeoutInMinutes: 180 condition: >- or( diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj b/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj index 3ac55699a6a379..036977e8d25f8c 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests.csproj @@ -9,6 +9,13 @@ $(Features.Replace('nullablePublicOnly', '') + + + $(WithoutCategories);AdditionalTimezoneChecks + + diff --git a/src/libraries/System.Runtime/tests/System/TimeZoneInfoTests.cs b/src/libraries/System.Runtime/tests/System/TimeZoneInfoTests.cs index 5d04aa8638f5fe..75b4ea29973f2b 100644 --- a/src/libraries/System.Runtime/tests/System/TimeZoneInfoTests.cs +++ b/src/libraries/System.Runtime/tests/System/TimeZoneInfoTests.cs @@ -11,6 +11,7 @@ using System.Runtime.Serialization.Formatters.Binary; using System.Text.RegularExpressions; using Microsoft.DotNet.RemoteExecutor; +using Microsoft.DotNet.XUnitExtensions; using Xunit; namespace System.Tests @@ -2948,6 +2949,7 @@ public static void NoBackwardTimeZones() [Fact] [PlatformSpecific(TestPlatforms.Android | TestPlatforms.iOS | TestPlatforms.tvOS)] + [Trait(XunitConstants.Category, "AdditionalTimezoneChecks")] public static void LocalTzIsNotUtc() { Assert.NotEqual(TimeZoneInfo.Utc.StandardName, TimeZoneInfo.Local.StandardName); From 08692dcf6bb971ee420c6a7e6dffec135023b6b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksey=20Kliger=20=28=CE=BBgeek=29?= Date: Fri, 10 Jun 2022 17:37:39 -0400 Subject: [PATCH 049/337] Mono Code Guidelines (#70507) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Mono Code Guidelines * markdownlint * Add "Naming" and "public API" sections * Add a section on assertions * Fix sentence fragment; add threading design doc link * Apply suggestions from code review Co-authored-by: Aaron Robinson Co-authored-by: Dan Moseley Co-authored-by: Alexander Köplinger --- docs/coding-guidelines/mono-code-guide.md | 253 ++++++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 docs/coding-guidelines/mono-code-guide.md diff --git a/docs/coding-guidelines/mono-code-guide.md b/docs/coding-guidelines/mono-code-guide.md new file mode 100644 index 00000000000000..8433df9f7b6554 --- /dev/null +++ b/docs/coding-guidelines/mono-code-guide.md @@ -0,0 +1,253 @@ +# Mono code guidelines + +This document is meant to capture guidelines for contributing code to +the [src/mono/mono/](../../src/mono/mono), +[src/native/public/mono](../../src/native/public/mono) areas of the +dotnet/runtime repo. + +In general this guide does not apply to: + +1. Shared native code in [src/native](../../src/native) +2. The Mono-specific C# code in [src/mono](../../src/mono) in System.Private.CoreLib or elsewhere + +## Code style + +Mono is written in C. + +We follow the [Mono Coding guidelines](https://www.mono-project.com/community/contributing/coding-guidelines/) for the C code - in particular: + +* tabs, not spaces +* space between a function name and the open parenthesis +* braces on the same line as `if`, `for`, `while` etc + +## Naming + +Mono reserves the following prefixes for symbols: `mono_`, `monovm_`, `m_`, `monoeg_` (used to remap [`eglib`](../../src/mono/mono/eglib) +functions which in source code have a `g_` prefix). + +All non-`static` symbols should use one of these prefixes. We generally use `mono_` for most +functions. `m_` is used for some inline accessor functions and macros. `g_` (`mono_eg_`) is used +for `eglib` functions. + +Types in a single C file can use any name. Types in a header should use a `Mono` (or sometimes +`mono_`) prefix. + +Public API symbols and types *must* be prefixed. + +For types Mono generally uses `typedef struct _MonoWhatever { ... } MonoWhatever`. Opaque types may +define `typedef struct _MonoWhatever MonoWhatever` in a client header and define `struct +_MonoWhatever {...}` in an implementation header. Occasionally we break `#include` cycles by adding +forward declarations for some types. + +## Macros + +Mono derives from an autotools-style project so we generally write `HOST_XYZ` for the machine on +which the runtime is executing (as opposed to the machine on which the runtime was compiled), and +`TARGET_XYZ` for the machine that will be targeted by the JIT and AOT compilers. In the case of AOT +compilation host and target might be different: the host might be Windows, and the target might be +Browser WebAssembly, for example. + +Macros generally use a `MONO_` prefix. Macros in public API headers *must* use the prefix. + +## Types + +Prefer the standard C sized types `int32_t`, `intptr_t`, etc over the eglib types `gint32`, `gsize` etc. + +One exception is `gboolean` is prefered over C `bool`. + +There are actually three boolean types to keep in mind: + +* `gboolean` used internally in the runtime +* `MonoBoolean` used as an interop type with C# bool in internal calls +* `mono_bool` used by the public C API - generally new code shouldn't use it except when adding a new public API function. + +## Utility and platform abstraction functions + +Mono generally tries to fill in POSIX-like abstractions on platforms that lack them (for example, Windows). +This is in contrast to the CoreCLR PAL which generally tries to add Windows API abstractions on top +of POSIX. + +If an existing `eglib` utility function is available, it should be used. New ones can be added. + +Other platform specific code is in `src/mono/utils` + +## Directory dependencies + +For the code in `src/mono/mono`: + +* `eglib` should not depend on other code from `src/mono` + +* `utils` can depend on `eglib` and 3rd party code from `src/native/external` + +* `sgen` depends on `eglib` and `utils` + +* `metadata` depends on all of the above (but note that some Boehm-GC files in this directory should not depend on `sgen`) + +* `mini` depends on all of the above + +* `mini/interp` depends on all of the above + +* `components` can use functions from all of the above provided they're marked with + `MONO_COMPONENT_API`, see [../design/mono/components.md](../design/mono/components.md) + +The main distinction between `metadata` and `utils` is that utils code should not assume that it is +part of an executing .NET runtime - anything that loads types, creates objects, etc does not belong +in utils but in metadata. + +The `mini` directory contains execution engines. If the execution engine has to provide some +functionality to `metadata` it generally does so by installing some callback that is invoked by +`metadata`. For example, `mini` knows how to unwind exceptions and perform stack walks - while +`metadata` decides *when* to unwind or perform a stackwalk. To coordinate, `metadata` exposes an +API to install hooks and `mini` provides the implementations. + +## Error handling + +New code should prefer to use the `MonoError` functions. + +* A non-public-API function should take a `MonoError *` argument. +* In case of an error the function should call one of the `mono_error_set_` functions from [../../src/mono/mono/utils/mono-error-internals.h](../../src/mono/mono/utils/mono-error-internals.h) +* Inside the runtime check whether there was an error by calling `is_ok (error)`, `mono_error_assert_ok (error)`, `goto_if_nok` or `return_if_nok`/`return_val_if_nok` +* If there is an error and you're handling it, call `mono_error_cleanup (error)` to dispose of the resources. +* `MonoError*` is generally one-shot: after it's been cleaned up it needs to be re-inited with `mono_error_init_reuse`, but this is discouraged. +* Instead if you intend to deal with an error, use `ERROR_DECL (local_error)` then call the + possibly-failing function and pass it `local_error`, then call `mono_error_assert_ok + (local_error)` if it "can't fail" or `mono_error_cleanup (local_error)` if you want to ignore the + failure. + +## Managed Exceptions + +New code should generally not deal with `MonoException*`, use `MonoError*` instead. + +New code should avoid using `mono_error_set_pending_exception` - it affects a thread-local flag in +a way that is not obvious to the caller of your function and may trample existing in-flight +exceptions and make your code fail in unexpected ways. + +There are two circumstances when you might need to call `mono_error_set_pending_exception`: + +1. You're working with a public Mono API that sets a pending exception +2. You're implementing an icall, but can't use `HANDLES()` (see the [internal calls](#internal-calls) section below) + +## Internal calls + +Prefer P/Invokes or QCalls over internal calls. That is, if your function only takes arguments that +are not managed objects, and does not need to interact with the runtime, it is better to define it +outside the runtime. + +Internal calls generally have at least one argument that is a managed object, or may throw a managed exception. + +Internal calls are declared in [`icall-def.h`](../../src/mono/mono/metadata/icall-def.h) See the comment in the header for details. + +There are two styles of internal calls: `NOHANDLES` and `HANDLES`. (This is a simplification as there +are also JIT internal calls added by the execution engines) + +The difference is that `HANDLES` icalls receive references to managed objects wrapped in a handle +that attempts to keep the object alive for the duration of the internal call even if the thread +blocks or is suspended, while `NOHANDLES` functions don't. Additionally `HANDLES` functions get a +`MonoError*` argument from the managed-to-native interop layer that will be converted to a managed +exception when the function returns. `NOHANDLES` functions generally have to call +`mono_error_set_pending_exception` themselves. + +## Suspend Safety + +See [Cooperative Suspend at mono-project.com](https://www.mono-project.com/docs/advanced/runtime/docs/coop-suspend/) and the [mono thread state machine design document](../design/mono/mono-thread-state-machine.md) + +In general runtime functions that may be called from the public Mono API should call +`MONO_ENTER_GC_UNSAFE`/`MONO_EXIT_GC_UNSAFE` if they call any other runtime API. Internal calls are +already in GC Unsafe on entry, but QCalls and P/Invokes aren't. + +When calling a blocking native API, wrap the call in `MONO_ENTER_GC_SAFE`/`MONO_EXIT_GC_SAFE`. + +Prefer `mono_coop_` synchronization primitives (`MonoCoopMutex`, `MonoCoopCond`, +`MonoCoopSemaphore`, etc) over `mono_os_` primitives (`mono_mutex_t`, `mono_cond_t`). The former +will automatically go into GC Safe mode before doing operations that may block. The latter should +only be used for low-level leaf locks that may need to be shared with non-runtime code. You're +responsible for switching to GC Safe mode when doing blocking operations in that case. + +## GC Memory Safety + +We have explored many different policies on how to safely access managed memory from the runtime. The existing code is not uniform. + +This is the current policy (but check with a team member as this document may need to be updated): + +1. It is never ok to access a managed object from GC Safe code. +2. Mono's GC scans the managed heap precisely. Mono does not allow heap objects to contain pointers into the interior of other managed obejcts. +3. Mono's GC scans the native stack conservatively: any value that looks like a pointer into the GC + heap, will cause the target object to be pinned and not collected. Interior pointers from the + stack into the middle of a managed object are allowed and will pin the object. + +In general one of the following should be used to ensure that an object is kept alive, particularly +across a call back into managed from native, or across a call that may trigger a GC (effectively +nearly any runtime internal API, due to assembly loading potentially triggering managed callbacks): + +* The object is pinned in managed code using `fixed` (common with strings) and the native code gets a `gunichar2*` +* a `ref` local is passed into native code and the native code gets a `MonoObject * volatile *` (the `volatile` is important) +* a `Span` is passed into native code and the native code gets a `MonoSpanOfObjects*` +* an icall is declared with `HANDLES()` and a `MonoObjectHandle` (or a more specific type such as `MonoReflectionTypeHandle` is passed in). +* a GCHandle is passed in + +Generally only functions on the boundary between managed and native should use one of the above +mechanisms (that is, it's enough that an object is pinned once). Callees can take a `MonoObject*` +argument and assume that it was pinned by the caller. + +In cases where an object is created in native code, it should be kept alive: + +1. By assigning into a `MonoObject * volatile *` (ie: use `out` or `ref` arguments in C#) +2. By creating a local handle using `MONO_HANDLE_NEW` or `MONO_HANDLE_PIN` (the function should then use `HANDLE_FUNCTION_ENTER`/`HANDLE_FUNCTION_RETURN` to set up and tear down a handle frame) +3. By creating a GCHandle +4. By assigning to a field of another managed object + +In all cases, if there is any intervening internal API call or a call to managed code, the object +must be kept alive before the call using one of the above methods. + +### Write barriers + +When writing a managed object to a field of another managed object, use one of the +`mono_gc_wbarrier_` functions (for example, `mono_gc_wbarrier_generic_store`). It is ok to call the write +barrier functions if the destination is not in the managed heap (in which case they will just do a normal write) + +## Assertions + +Mono code should use `g_assert`, `mono_error_assert_ok`, `g_assertf`, `g_assert_not_reached` etc. + +Unlike CoreCLR, Mono assertions are always included in the runtime - both in Debug and in Release builds. + +New code should try not to rely on the side-effects of assert conditions. (That is, one day we may want +to turn off assertions in Release builds.) + +## Mono Public API + +Mono maintains a public API for projects that embed the Mono runtime in order to provide the ability +to execute .NET code in the context of another application or framework. The current Mono API is +`mono-2.0`. We strive to maintain binary ABI and API stability for our embedders. + +The public API headers are defined in +[`../../src/native/public/mono`](../../src/native/public/mono). Great care should be taken when +modifying any of the functions declared in these headers. In particular breaking the ABI by +removing these functions or changing their arguments is not allowed. Semantic changes should be +avoided, or implemented in a way that is least disruptive to embedders (for example the runtime does +not support multiple appdomains anymore, but `mono_domain_get` continues to work). + +### Hidden API functions + +In practice certain functions have been tagged with `MONO_API` even if they are not declared in the +public headers. These symbols have been used by projects that embed Mono despite not being in the +public headers. They should be treated with the same care as the real public API. + +### Unstable API functions + +Functions declared in `mono-private-unstable.h` headers do not need to maintain API/ABI stability. +They are generally new APIs that have been added since .NET 5 but that have not been stabilized yet. + +As a matter of courtesy, notify the .NET macios and .NET Android teams if changing the behavior of these functions. + +### WASM + +The WASM and WASI runtimes in [`src/mono/wasm/runtime`](../../src/mono/wasm/runtime) and +`src/mono/wasi` are effectively external API clients. When possible they should use existing `MONO_API` functions. + +As a matter of expedience, the wasm project has sometimes taken advantage of static linking by +adding declarations of internal Mono functions in `src/mono/wasm/runtime/driver.c` and directly +calling Mono internals. + +In general new code should not do this. When modifying existing code, mysterious WASM failures may +be attributed to symbol signature mismatches between WASM and the Mono runtime. From 83bd401b112f2deb0db516300f72eb9d1579751d Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Fri, 10 Jun 2022 16:14:44 -0700 Subject: [PATCH 050/337] Add support for parsing and working with CustomModifiers in field signatures and make TypeSystemMetadataEmitter more flexible (#70593) - Update TypeSystemMetadataEmitter to be able to generate a field signature given an appropriate array of EmbeddedSignatureData[] - Add api to FieldDesc to allow the custom modifier data to be handled using the same scheme as custom modifier data on method signatures - Adjust TypeSystemMetadataEmitter to be able to generate metadata not just for the Mibc emitter - The current implementation has some default behavior around creating metadata that is in the constructor. Break that out into helper functions so that other scenarios don't need to run that code. - Add an entrypoint for generating metadata for an arbitrary TypeSystemEntity - Add a feature to allow it the ResolutionScope of a non-nested type to be managed specially. This will be needed by #68919 --- .../TypeLoader/NativeLayoutFieldDesc.cs | 2 + .../Common/TypeSystem/Common/FieldDesc.cs | 3 + .../Common/FieldForInstantiatedType.cs | 5 + .../tools/Common/TypeSystem/Ecma/EcmaField.cs | 13 + .../TypeSystem/Ecma/EcmaSignatureParser.cs | 19 ++ .../IL/Stubs/PInvokeLazyFixupField.cs | 2 + .../TypeSystem/Interop/IL/InlineArrayType.cs | 1 + .../TypeSystem/Interop/IL/NativeStructType.cs | 2 + .../TypeSystemMetadataEmitter.cs | 228 ++++++++++++++---- .../Compiler/ExternSymbolMappedField.cs | 1 + .../ILTestAssembly/Signature.il | 2 + .../SignatureTests.cs | 29 +++ src/coreclr/tools/dotnet-pgo/MibcEmitter.cs | 2 + .../TypeRefTypeSystemContext.cs | 4 +- .../TypeRefTypeSystemField.cs | 6 +- .../TypeRefTypeSystemType.cs | 4 +- 16 files changed, 273 insertions(+), 50 deletions(-) diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/NativeLayoutFieldDesc.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/NativeLayoutFieldDesc.cs index 056cb26016ef46..b658f1dc49c3a0 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/NativeLayoutFieldDesc.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/NativeLayoutFieldDesc.cs @@ -39,6 +39,8 @@ public override TypeDesc FieldType } } + public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => null; + public override bool HasRva { get diff --git a/src/coreclr/tools/Common/TypeSystem/Common/FieldDesc.cs b/src/coreclr/tools/Common/TypeSystem/Common/FieldDesc.cs index ad44d485747952..23bd5ba923a54d 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/FieldDesc.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/FieldDesc.cs @@ -45,6 +45,9 @@ public abstract TypeDesc FieldType get; } + // Get the embedded signature data used to hold custom modifiers and such within a field signature + public abstract EmbeddedSignatureData[] GetEmbeddedSignatureData(); + public abstract bool IsStatic { get; diff --git a/src/coreclr/tools/Common/TypeSystem/Common/FieldForInstantiatedType.cs b/src/coreclr/tools/Common/TypeSystem/Common/FieldForInstantiatedType.cs index b51d55660a6868..fbc456a830639c 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/FieldForInstantiatedType.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/FieldForInstantiatedType.cs @@ -51,6 +51,11 @@ public override TypeDesc FieldType } } + public override EmbeddedSignatureData[] GetEmbeddedSignatureData() + { + return _fieldDef.GetEmbeddedSignatureData(); + } + public override bool IsStatic { get diff --git a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaField.cs b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaField.cs index b6d5e4fd41f8b7..6ba7907106dd6f 100644 --- a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaField.cs +++ b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaField.cs @@ -113,6 +113,19 @@ public override TypeDesc FieldType } } + // This is extremely rarely needed. Don't cache it at all. + public override EmbeddedSignatureData[] GetEmbeddedSignatureData() + { + var metadataReader = MetadataReader; + BlobReader signatureReader = metadataReader.GetBlobReader(metadataReader.GetFieldDefinition(_handle).Signature); + + EcmaSignatureParser parser = new EcmaSignatureParser(Module, signatureReader, NotFoundBehavior.Throw); + var fieldType = parser.ParseFieldSignature(out var embeddedSig); + Debug.Assert(fieldType == FieldType); + return embeddedSig; + } + + [MethodImpl(MethodImplOptions.NoInlining)] private int InitializeFieldFlags(int mask) { diff --git a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs index 2247f551fc29d1..f2530ec8b19d7c 100644 --- a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs +++ b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaSignatureParser.cs @@ -471,6 +471,25 @@ public TypeDesc ParseFieldSignature() return ParseType(); } + public TypeDesc ParseFieldSignature(out EmbeddedSignatureData[] embeddedSigData) + { + try + { + _indexStack = new Stack(); + _indexStack.Push(1); + _indexStack.Push(0); + _embeddedSignatureDataList = new List(); + TypeDesc parsedType = ParseFieldSignature(); + embeddedSigData = _embeddedSignatureDataList.Count == 0 ? null : _embeddedSignatureDataList.ToArray(); + return parsedType; + } + finally + { + _indexStack = null; + _embeddedSignatureDataList = null; + } + } + public LocalVariableDefinition[] ParseLocalsSignature() { if (_reader.ReadSignatureHeader().Kind != SignatureKind.LocalVariables) diff --git a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/PInvokeLazyFixupField.cs b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/PInvokeLazyFixupField.cs index c2a44b01653a59..5b49bfdb50faaa 100644 --- a/src/coreclr/tools/Common/TypeSystem/IL/Stubs/PInvokeLazyFixupField.cs +++ b/src/coreclr/tools/Common/TypeSystem/IL/Stubs/PInvokeLazyFixupField.cs @@ -56,6 +56,8 @@ public override TypeDesc FieldType } } + public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => null; + public override bool HasRva { get diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/InlineArrayType.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/InlineArrayType.cs index 4cf06e8b6bfb4f..51ac01f9a2fb68 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/InlineArrayType.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/InlineArrayType.cs @@ -441,6 +441,7 @@ public override TypeDesc FieldType return _owningType.ElementType; } } + public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => null; public override bool HasRva { diff --git a/src/coreclr/tools/Common/TypeSystem/Interop/IL/NativeStructType.cs b/src/coreclr/tools/Common/TypeSystem/Interop/IL/NativeStructType.cs index bf5e0c6ef3d7ba..149987476b3a32 100644 --- a/src/coreclr/tools/Common/TypeSystem/Interop/IL/NativeStructType.cs +++ b/src/coreclr/tools/Common/TypeSystem/Interop/IL/NativeStructType.cs @@ -348,6 +348,8 @@ public override TypeDesc FieldType } } + public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => null; + public override bool HasRva { get diff --git a/src/coreclr/tools/Common/TypeSystem/MetadataEmitter/TypeSystemMetadataEmitter.cs b/src/coreclr/tools/Common/TypeSystem/MetadataEmitter/TypeSystemMetadataEmitter.cs index 5a47094605c9e1..46110f26bb2a88 100644 --- a/src/coreclr/tools/Common/TypeSystem/MetadataEmitter/TypeSystemMetadataEmitter.cs +++ b/src/coreclr/tools/Common/TypeSystem/MetadataEmitter/TypeSystemMetadataEmitter.cs @@ -18,14 +18,18 @@ class TypeSystemMetadataEmitter MetadataBuilder _metadataBuilder; BlobBuilder _ilBuilder; MethodBodyStreamEncoder _methodBodyStream; + Dictionary _assemblyRefNameHandles = new Dictionary(); Dictionary _assemblyRefs = new Dictionary(); Dictionary _typeRefs = new Dictionary(); Dictionary _methodRefs = new Dictionary(); + Dictionary _fieldRefs = new Dictionary(); Blob _mvidFixup; BlobHandle _noArgsVoidReturnStaticMethodSigHandle; + protected TypeSystemContext _typeSystemContext; - public TypeSystemMetadataEmitter(AssemblyName assemblyName, TypeSystemContext context, AssemblyFlags flags = default(AssemblyFlags)) + public TypeSystemMetadataEmitter(AssemblyName assemblyName, TypeSystemContext context, AssemblyFlags flags = default(AssemblyFlags), byte[] publicKeyArray = null, AssemblyHashAlgorithm hashAlgorithm = AssemblyHashAlgorithm.None) { + _typeSystemContext = context; _metadataBuilder = new MetadataBuilder(); _ilBuilder = new BlobBuilder(); _methodBodyStream = new MethodBodyStreamEncoder(_ilBuilder); @@ -33,21 +37,11 @@ class TypeSystemMetadataEmitter if (assemblyName.CultureName != null) throw new ArgumentException("assemblyName"); - if (assemblyName.GetPublicKeyToken() != null) - throw new ArgumentException("assemblyName"); - var mvid = _metadataBuilder.ReserveGuid(); _mvidFixup = mvid.Content; _metadataBuilder.AddModule(0, assemblyNameHandle, mvid.Handle, default(GuidHandle), default(GuidHandle)); - _metadataBuilder.AddAssembly(assemblyNameHandle, assemblyName.Version ?? new Version(0,0,0,0), default(StringHandle), default(BlobHandle), flags, AssemblyHashAlgorithm.None); - - var canonAssemblyNameHandle = _metadataBuilder.GetOrAddString("System.Private.Canon"); - var canonAssemblyRef = _metadataBuilder.AddAssemblyReference(canonAssemblyNameHandle, new Version(0, 0, 0, 0), default(StringHandle), default(BlobHandle), (AssemblyFlags)0, default(BlobHandle)); - var systemStringHandle = _metadataBuilder.GetOrAddString("System"); - var canonStringHandle = _metadataBuilder.GetOrAddString("__Canon"); - var canonTypeRef = _metadataBuilder.AddTypeReference(canonAssemblyRef, systemStringHandle, canonStringHandle); - _typeRefs.Add(context.CanonType, canonTypeRef); + _metadataBuilder.AddAssembly(assemblyNameHandle, assemblyName.Version ?? new Version(0,0,0,0), default(StringHandle), publicKey: publicKeyArray != null ? _metadataBuilder.GetOrAddBlob(publicKeyArray) : default(BlobHandle), flags, AssemblyHashAlgorithm.None); _metadataBuilder.AddTypeDefinition( default(TypeAttributes), @@ -56,7 +50,20 @@ class TypeSystemMetadataEmitter baseType: default(EntityHandle), fieldList: MetadataTokens.FieldDefinitionHandle(1), methodList: MetadataTokens.MethodDefinitionHandle(1)); + } + public void InjectSystemPrivateCanon() + { + var canonAssemblyNameHandle = _metadataBuilder.GetOrAddString("System.Private.Canon"); + var canonAssemblyRef = _metadataBuilder.AddAssemblyReference(canonAssemblyNameHandle, new Version(0, 0, 0, 0), default(StringHandle), default(BlobHandle), (AssemblyFlags)0, default(BlobHandle)); + var systemStringHandle = _metadataBuilder.GetOrAddString("System"); + var canonStringHandle = _metadataBuilder.GetOrAddString("__Canon"); + var canonTypeRef = _metadataBuilder.AddTypeReference(canonAssemblyRef, systemStringHandle, canonStringHandle); + _typeRefs.Add(_typeSystemContext.CanonType, canonTypeRef); + } + + public void AllowUseOfAddGlobalMethod() + { BlobBuilder noArgsNoReturnStaticMethodSig = new BlobBuilder(); BlobEncoder signatureEncoder = new BlobEncoder(noArgsNoReturnStaticMethodSig); @@ -79,6 +86,8 @@ public MethodDefinitionHandle AddGlobalMethod(string name, InstructionEncoder il private static readonly Guid s_guid = new Guid("97F4DBD4-F6D1-4FAD-91B3-1001F92068E5"); private static readonly BlobContentId s_contentId = new BlobContentId(s_guid, 0x04030201); + public MetadataBuilder Builder => _metadataBuilder; + public void SerializeToStream(Stream peStream) { var peHeaderBuilder = new PEHeaderBuilder(); @@ -91,6 +100,47 @@ public void SerializeToStream(Stream peStream) peBlob.WriteContentTo(peStream); } + // Generate only the metadata blob as a byte[] + public byte[] EmitToMetadataBlob() + { + MetadataRootBuilder metadataRootBuilder = new MetadataRootBuilder(_metadataBuilder); + BlobBuilder metadataBlobBuilder = new BlobBuilder(); + metadataRootBuilder.Serialize(metadataBlobBuilder, methodBodyStreamRva: 0, mappedFieldDataStreamRva: 0); + + // Clear some variables to catch any caller trying to emit data after writing the output file + _metadataBuilder = null; + + return metadataBlobBuilder.ToArray(); + } + + public AssemblyReferenceHandle GetAssemblyRef(AssemblyName name) + { + if (!_assemblyRefNameHandles.TryGetValue(name.FullName, out var handle)) + { + StringHandle assemblyName = _metadataBuilder.GetOrAddString(name.Name); + StringHandle cultureName = (name.CultureName != null) ? _metadataBuilder.GetOrAddString(name.CultureName) : default(StringHandle); + BlobHandle publicTokenBlob = name.GetPublicKeyToken() != null ? _metadataBuilder.GetOrAddBlob(name.GetPublicKeyToken()) : default(BlobHandle); + AssemblyFlags flags = default(AssemblyFlags); + if (name.Flags.HasFlag(AssemblyNameFlags.Retargetable)) + { + flags |= AssemblyFlags.Retargetable; + } + if (name.ContentType == AssemblyContentType.WindowsRuntime) + { + flags |= AssemblyFlags.WindowsRuntime; + } + + Version version = name.Version; + if (version == null) + version = new Version(0, 0); + + handle = _metadataBuilder.AddAssemblyReference(assemblyName, version, cultureName, publicTokenBlob, flags, default(BlobHandle)); + + _assemblyRefNameHandles[name.FullName] = handle; + } + return handle; + } + public AssemblyReferenceHandle GetAssemblyRef(IAssemblyDesc assemblyDesc) { if (_assemblyRefs.TryGetValue(assemblyDesc, out var handle)) @@ -98,26 +148,50 @@ public AssemblyReferenceHandle GetAssemblyRef(IAssemblyDesc assemblyDesc) return handle; } AssemblyName name = assemblyDesc.GetName(); - StringHandle assemblyName = _metadataBuilder.GetOrAddString(name.Name); - StringHandle cultureName = (name.CultureName != null) ? _metadataBuilder.GetOrAddString(name.CultureName) : default(StringHandle); - BlobHandle publicTokenBlob = name.GetPublicKeyToken() != null ? _metadataBuilder.GetOrAddBlob(name.GetPublicKeyToken()) : default(BlobHandle); - AssemblyFlags flags = default(AssemblyFlags); - if (name.Flags.HasFlag(AssemblyNameFlags.Retargetable)) + var referenceHandle = GetAssemblyRef(name); + _assemblyRefs.Add(assemblyDesc, referenceHandle); + return referenceHandle; + } + + public EntityHandle EmitMetadataHandleForTypeSystemEntity(TypeSystemEntity entity) + { + switch (entity) { - flags |= AssemblyFlags.Retargetable; + case FieldDesc field: return GetFieldRef(field); + case MethodDesc method: return GetMethodRef(method); + case TypeDesc type: return GetTypeRef(type); + case ModuleDesc assembly: return GetAssemblyRef(assembly.Assembly); + case MethodSignature methodSignature: return GetStandaloneSig(methodSignature); + + default: + throw new NotSupportedException(); } - if (name.ContentType == AssemblyContentType.WindowsRuntime) + } + + public IEnumerable> TypeSystemEntitiesKnown + { + get { - flags |= AssemblyFlags.WindowsRuntime; - } + foreach (var item in _typeRefs) + { + yield return new KeyValuePair(item.Key, item.Value); + } - Version version = name.Version; - if (version == null) - version = new Version(0, 0); + foreach (var item in _methodRefs) + { + yield return new KeyValuePair(item.Key, item.Value); + } - var referenceHandle = _metadataBuilder.AddAssemblyReference(assemblyName, version, cultureName, publicTokenBlob, flags, default(BlobHandle)); - _assemblyRefs.Add(assemblyDesc, referenceHandle); - return referenceHandle; + foreach (var item in _fieldRefs) + { + yield return new KeyValuePair(item.Key, item.Value); + } + } + } + + protected virtual EntityHandle GetNonNestedResolutionScope(MetadataType metadataType) + { + return GetAssemblyRef(metadataType.Module.Assembly); } public EntityHandle GetTypeRef(TypeDesc type) @@ -144,7 +218,7 @@ public EntityHandle GetTypeRef(TypeDesc type) if (metadataType.ContainingType == null) { // non-nested type - resolutionScope = GetAssemblyRef(metadataType.Module.Assembly); + resolutionScope = GetNonNestedResolutionScope(metadataType); } else { @@ -166,6 +240,58 @@ public EntityHandle GetTypeRef(TypeDesc type) return typeHandle; } + private BlobHandle GetMethodSignatureBlobHandle(MethodSignature sig) + { + EmbeddedSignatureDataEmitter signatureDataEmitter; + if (sig.HasEmbeddedSignatureData) + { + signatureDataEmitter = new EmbeddedSignatureDataEmitter(sig.GetEmbeddedSignatureData(), this); + } + else + { + signatureDataEmitter = EmbeddedSignatureDataEmitter.EmptySingleton; + } + + BlobBuilder memberRefSig = new BlobBuilder(); + EncodeMethodSignature(memberRefSig, sig, signatureDataEmitter); + + if (!signatureDataEmitter.Complete) + throw new ArgumentException(); + + var sigBlob = _metadataBuilder.GetOrAddBlob(memberRefSig); + return sigBlob; + } + + private BlobHandle GetFieldSignatureBlobHandle(FieldDesc field) + { + var fieldDef = field.GetTypicalFieldDefinition(); + var embeddedSigData = field.GetEmbeddedSignatureData(); + EmbeddedSignatureDataEmitter signatureDataEmitter; + if (embeddedSigData != null && embeddedSigData.Length != 0) + { + signatureDataEmitter = new EmbeddedSignatureDataEmitter(embeddedSigData, this); + } + else + { + signatureDataEmitter = EmbeddedSignatureDataEmitter.EmptySingleton; + } + + BlobBuilder memberRefSig = new BlobBuilder(); + EncodeFieldSignature(memberRefSig, field.FieldType, signatureDataEmitter); + + if (!signatureDataEmitter.Complete) + throw new ArgumentException(); + + var sigBlob = _metadataBuilder.GetOrAddBlob(memberRefSig); + return sigBlob; + } + + public EntityHandle GetStandaloneSig(MethodSignature sig) + { + var sigBlob = GetMethodSignatureBlobHandle(sig); + return _metadataBuilder.AddStandaloneSignature(sigBlob); + } + public EntityHandle GetMethodRef(MethodDesc method) { if (_methodRefs.TryGetValue(method, out var handle)) @@ -192,24 +318,8 @@ public EntityHandle GetMethodRef(MethodDesc method) EntityHandle typeHandle = GetTypeRef((MetadataType)method.OwningType); StringHandle methodName = _metadataBuilder.GetOrAddString(method.Name); var sig = method.GetTypicalMethodDefinition().Signature; + var sigBlob = GetMethodSignatureBlobHandle(sig); - EmbeddedSignatureDataEmitter signatureDataEmitter; - if (sig.HasEmbeddedSignatureData) - { - signatureDataEmitter = new EmbeddedSignatureDataEmitter(sig.GetEmbeddedSignatureData(), this); - } - else - { - signatureDataEmitter = EmbeddedSignatureDataEmitter.EmptySingleton; - } - - BlobBuilder memberRefSig = new BlobBuilder(); - EncodeMethodSignature(memberRefSig, sig, signatureDataEmitter); - - if (!signatureDataEmitter.Complete) - throw new ArgumentException(); - - var sigBlob = _metadataBuilder.GetOrAddBlob(memberRefSig); methodHandle = _metadataBuilder.AddMemberReference(typeHandle, methodName, sigBlob); } @@ -217,6 +327,25 @@ public EntityHandle GetMethodRef(MethodDesc method) return methodHandle; } + public EntityHandle GetFieldRef(FieldDesc field) + { + if (_fieldRefs.TryGetValue(field, out var handle)) + { + return handle; + } + + EntityHandle fieldHandle; + + EntityHandle typeHandle = GetTypeRef((MetadataType)field.OwningType); + StringHandle fieldName = _metadataBuilder.GetOrAddString(field.Name); + + var sigBlob = GetFieldSignatureBlobHandle(field.GetTypicalFieldDefinition()); + fieldHandle = _metadataBuilder.AddMemberReference(typeHandle, fieldName, sigBlob); + + _fieldRefs.Add(field, fieldHandle); + return fieldHandle; + } + private void EncodeType(BlobBuilder blobBuilder, TypeDesc type, EmbeddedSignatureDataEmitter signatureDataEmitter) { signatureDataEmitter.Push(); @@ -543,6 +672,15 @@ void EncodeMethodSignature(BlobBuilder signatureBuilder, MethodSignature sig, Em signatureDataEmitter.Pop(); } + void EncodeFieldSignature(BlobBuilder signatureBuilder, TypeDesc fieldType, EmbeddedSignatureDataEmitter signatureDataEmitter) + { + signatureDataEmitter.Push(); + BlobEncoder signatureEncoder = new BlobEncoder(signatureBuilder); + signatureEncoder.FieldSignature(); + EncodeType(signatureBuilder, fieldType, signatureDataEmitter); + signatureDataEmitter.Pop(); + } + public UserStringHandle GetUserStringHandle(string userString) { return _metadataBuilder.GetOrAddUserString(userString); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ExternSymbolMappedField.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ExternSymbolMappedField.cs index 2ee25f4dc7c3bb..8a4bce713efe4a 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ExternSymbolMappedField.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ExternSymbolMappedField.cs @@ -26,6 +26,7 @@ public ExternSymbolMappedField(TypeDesc fieldType, string symbolName) public override DefType OwningType => _fieldType.Context.SystemModule.GetGlobalModuleType(); public override TypeDesc FieldType => _fieldType; + public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => null; public override bool IsStatic => true; diff --git a/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/ILTestAssembly/Signature.il b/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/ILTestAssembly/Signature.il index 32e307b7036c87..5a528fda34d776 100644 --- a/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/ILTestAssembly/Signature.il +++ b/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/ILTestAssembly/Signature.il @@ -39,6 +39,8 @@ { ret } + + .field private bool modreq([CoreTestAssembly]System.Void) fieldWithModOpt } .class private auto ansi beforefieldinit Atom diff --git a/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/SignatureTests.cs b/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/SignatureTests.cs index ac8d2bc1683728..23e1a9f58cfe2b 100644 --- a/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/SignatureTests.cs +++ b/src/coreclr/tools/aot/ILCompiler.TypeSystem.Tests/SignatureTests.cs @@ -197,6 +197,35 @@ public void TestSerializedSignatureWithReferenceToMDIntArray() Assert.Equal(typeInLookupContext, int32ArrayFromLookup); } + [Fact] + public void TestSerializedSignatureWithReferenceToFieldWithModOpt() + { + + MetadataType modOptTester = _testModule.GetType("", "ModOptTester"); + FieldDesc fieldWithModOpt = modOptTester.GetFields().Single(m => string.Equals(m.Name, "fieldWithModOpt")); + + // Create assembly with reference to interesting method + TypeSystemMetadataEmitter metadataEmitter = new TypeSystemMetadataEmitter(new System.Reflection.AssemblyName("Lookup"), _context); + var token = metadataEmitter.GetFieldRef(fieldWithModOpt); + MemoryStream peStream = new MemoryStream(); + metadataEmitter.SerializeToStream(peStream); + + peStream.Seek(0, SeekOrigin.Begin); + + // Create new TypeSystemContext with just created assembly inside + var lookupContext = new TestTypeSystemContext(TargetArchitecture.X64); + var systemModule = lookupContext.CreateModuleForSimpleName("CoreTestAssembly"); + lookupContext.SetSystemModule(systemModule); + + lookupContext.CreateModuleForSimpleName("Lookup", peStream); + + // Use generated assembly to trigger a load through the token created above and verify that it loads correctly + var ilLookupModule = (EcmaModule)lookupContext.GetModuleForSimpleName("Lookup"); + FieldDesc fieldFound = ilLookupModule.GetField(token); + + Assert.Equal("fieldWithModOpt", fieldFound.Name); + } + [Fact] public void TestMDArrayFunctionReading() { diff --git a/src/coreclr/tools/dotnet-pgo/MibcEmitter.cs b/src/coreclr/tools/dotnet-pgo/MibcEmitter.cs index a498bfd9e21d5b..e99fc610d86ca6 100644 --- a/src/coreclr/tools/dotnet-pgo/MibcEmitter.cs +++ b/src/coreclr/tools/dotnet-pgo/MibcEmitter.cs @@ -215,6 +215,8 @@ private static void AddAssembliesAssociatedWithMethod(MethodDesc method, HashSet public static int GenerateMibcFile(TypeSystemContext tsc, FileInfo outputFileName, IEnumerable methodsToAttemptToPlaceIntoProfileData, bool validate, bool uncompressed) { TypeSystemMetadataEmitter emitter = new TypeSystemMetadataEmitter(new AssemblyName(outputFileName.Name), tsc); + emitter.InjectSystemPrivateCanon(); + emitter.AllowUseOfAddGlobalMethod(); SortedDictionary groups = new SortedDictionary(); StringBuilder mibcGroupNameBuilder = new StringBuilder(); diff --git a/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemContext.cs b/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemContext.cs index bb32521c0b750e..31a5caee14c23a 100644 --- a/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemContext.cs +++ b/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemContext.cs @@ -153,8 +153,8 @@ public TypeRefTypeSystemContext(IEnumerable refReaders) } else { - var fieldType = ecmaSigParse.ParseFieldSignature(); - ownerType.GetOrAddField(name, fieldType); + var fieldType = ecmaSigParse.ParseFieldSignature(out var embeddedSigData); + ownerType.GetOrAddField(name, fieldType, embeddedSigData); } } diff --git a/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemField.cs b/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemField.cs index 5f261b4932c3f1..a380db86080bc0 100644 --- a/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemField.cs +++ b/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemField.cs @@ -15,12 +15,14 @@ class TypeRefTypeSystemField : FieldDesc TypeRefTypeSystemType _type; string _name; TypeDesc _fieldType; + EmbeddedSignatureData[] _embeddedSignatureData; - public TypeRefTypeSystemField(TypeRefTypeSystemType type, string name, TypeDesc fieldType) + public TypeRefTypeSystemField(TypeRefTypeSystemType type, string name, TypeDesc fieldType, EmbeddedSignatureData[] embeddedSigData) { _type = type; _name = name; _fieldType = fieldType; + _embeddedSignatureData = embeddedSigData; } public override string Name => _name; @@ -28,6 +30,8 @@ public TypeRefTypeSystemField(TypeRefTypeSystemType type, string name, TypeDesc public override TypeDesc FieldType => _fieldType; + public override EmbeddedSignatureData[] GetEmbeddedSignatureData() => _embeddedSignatureData; + public override bool IsStatic => throw new NotImplementedException(); public override bool IsInitOnly => throw new NotImplementedException(); diff --git a/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemType.cs b/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemType.cs index 6b5689805e93cf..af3bb5ae72c247 100644 --- a/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemType.cs +++ b/src/coreclr/tools/dotnet-pgo/TypeRefTypeSystem/TypeRefTypeSystemType.cs @@ -119,12 +119,12 @@ public MethodDesc GetOrAddMethod(string name, MethodSignature signature) return method; } - public FieldDesc GetOrAddField(string name, TypeDesc fieldType) + public FieldDesc GetOrAddField(string name, TypeDesc fieldType, EmbeddedSignatureData[] embeddedSigData) { FieldDesc fld = GetField(name); if (fld == null) { - TypeRefTypeSystemField newField = new TypeRefTypeSystemField(this, name, fieldType); + TypeRefTypeSystemField newField = new TypeRefTypeSystemField(this, name, fieldType, embeddedSigData); fld = newField; _fields.Add(newField); } From 41c6772cb44c0977abc0b283ec346bdf70b9e348 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Fri, 10 Jun 2022 16:16:41 -0700 Subject: [PATCH 051/337] Detect inlining accurately and skip generating precode fixups for inlines that do not succeed (#70379) - Fix reporting of nested inlining to be correct - In particular, if a doubly nested inline succeeds, but the method that called it didn't succeed its inline, do not report that the inner nested inline succeeded - Fix reporting of precode fixups to only be the precode fixups needed during actual use - fix SuperPMI detected JIT assertion around vector types Also fixes #65814 --- src/coreclr/inc/corinfo.h | 14 +- src/coreclr/inc/icorjitinfoimpl_generated.h | 4 + src/coreclr/inc/jiteeversionguid.h | 10 +- src/coreclr/jit/ICorJitInfo_API_names.h | 1 + src/coreclr/jit/ICorJitInfo_API_wrapper.hpp | 9 + src/coreclr/jit/compiler.cpp | 2 +- src/coreclr/jit/fginline.cpp | 3 +- src/coreclr/jit/hwintrinsic.cpp | 43 +-- src/coreclr/jit/importer.cpp | 6 +- src/coreclr/jit/inline.cpp | 35 +- src/coreclr/jit/inline.h | 46 ++- .../tools/Common/JitInterface/CorInfoBase.cs | 349 +++++++++--------- .../tools/Common/JitInterface/CorInfoImpl.cs | 37 +- .../tools/Common/JitInterface/CorInfoTypes.cs | 6 +- .../ThunkGenerator/ThunkInput.txt | 1 + .../JitInterface/CorInfoImpl.ReadyToRun.cs | 65 +++- .../JitInterface/CorInfoImpl.RyuJit.cs | 4 + .../tools/aot/jitinterface/jitinterface.h | 10 + .../superpmi-shim-collector/icorjitinfo.cpp | 7 + .../superpmi-shim-counter/icorjitinfo.cpp | 8 + .../superpmi-shim-simple/icorjitinfo.cpp | 7 + .../tools/superpmi/superpmi/icorjitinfo.cpp | 5 + src/coreclr/vm/jitinterface.cpp | 13 +- 23 files changed, 431 insertions(+), 254 deletions(-) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 7a673e52d7cc7f..8cb56a69a17038 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -954,11 +954,14 @@ enum CorInfoClassId enum CorInfoInline { - INLINE_PASS = 0, // Inlining OK + INLINE_PASS = 0, // Inlining OK + INLINE_PREJIT_SUCCESS = 1, // Inline check for prejit checking usage succeeded + INLINE_CHECK_CAN_INLINE_SUCCESS = 2, // JIT detected it is permitted to try to actually inline + INLINE_CHECK_CAN_INLINE_VMFAIL = 3, // VM specified that inline must fail via the CanInline api // failures are negative - INLINE_FAIL = -1, // Inlining not OK for this case only - INLINE_NEVER = -2, // This method should never be inlined, regardless of context + INLINE_FAIL = -1, // Inlining not OK for this case only + INLINE_NEVER = -2, // This method should never be inlined, regardless of context }; enum CorInfoInlineTypeCheck @@ -2034,6 +2037,11 @@ class ICorStaticInfo CORINFO_METHOD_HANDLE calleeHnd /* IN */ ) = 0; + // Report that an inlining related process has begun. This will always be paired with + // a call to reportInliningDecision unless the jit fails. + virtual void beginInlining (CORINFO_METHOD_HANDLE inlinerHnd, + CORINFO_METHOD_HANDLE inlineeHnd) = 0; + // Reports whether or not a method can be inlined, and why. canInline is responsible for reporting all // inlining results when it returns INLINE_FAIL and INLINE_NEVER. All other results are reported by the // JIT. diff --git a/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/coreclr/inc/icorjitinfoimpl_generated.h index 87f3054e6269ef..4864b033096944 100644 --- a/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -44,6 +44,10 @@ CorInfoInline canInline( CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE calleeHnd) override; +void beginInlining( + CORINFO_METHOD_HANDLE inlinerHnd, + CORINFO_METHOD_HANDLE inlineeHnd) override; + void reportInliningDecision( CORINFO_METHOD_HANDLE inlinerHnd, CORINFO_METHOD_HANDLE inlineeHnd, diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index e03d9d9190c605..27f75a486cb53c 100644 --- a/src/coreclr/inc/jiteeversionguid.h +++ b/src/coreclr/inc/jiteeversionguid.h @@ -43,11 +43,11 @@ typedef const GUID *LPCGUID; #define GUID_DEFINED #endif // !GUID_DEFINED -constexpr GUID JITEEVersionIdentifier = { /* 5868685e-b877-4ef5-83f0-73d601e50013 */ - 0x5868685e, - 0xb877, - 0x4ef5, - {0x83, 0xf0, 0x73, 0xd6, 0x01, 0xe5, 0x00, 0x13} +constexpr GUID JITEEVersionIdentifier = { /* af5b6632-6fbe-4a2e-82d6-24487a138e4a */ + 0xaf5b6632, + 0x6fbe, + 0x4a2e, + {0x82, 0xd6, 0x24, 0x48, 0x7a, 0x13, 0x8e, 0x4a} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/jit/ICorJitInfo_API_names.h b/src/coreclr/jit/ICorJitInfo_API_names.h index 520315b89f82a0..2549835cefbf8f 100644 --- a/src/coreclr/jit/ICorJitInfo_API_names.h +++ b/src/coreclr/jit/ICorJitInfo_API_names.h @@ -10,6 +10,7 @@ DEF_CLR_API(setMethodAttribs) DEF_CLR_API(getMethodSig) DEF_CLR_API(getMethodInfo) DEF_CLR_API(canInline) +DEF_CLR_API(beginInlining) DEF_CLR_API(reportInliningDecision) DEF_CLR_API(canTailCall) DEF_CLR_API(reportTailCallDecision) diff --git a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp index e65d1be26b3a0e..f6a7b39b1590aa 100644 --- a/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp +++ b/src/coreclr/jit/ICorJitInfo_API_wrapper.hpp @@ -69,6 +69,15 @@ CorInfoInline WrapICorJitInfo::canInline( return temp; } +void WrapICorJitInfo::beginInlining( + CORINFO_METHOD_HANDLE inlinerHnd, + CORINFO_METHOD_HANDLE inlineeHnd) +{ + API_ENTER(beginInlining); + wrapHnd->beginInlining(inlinerHnd, inlineeHnd); + API_LEAVE(beginInlining); +} + void WrapICorJitInfo::reportInliningDecision( CORINFO_METHOD_HANDLE inlinerHnd, CORINFO_METHOD_HANDLE inlineeHnd, diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index 2201c3a7d1e8d9..652d560409c0f5 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -6563,7 +6563,7 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr, { // This looks like a viable inline candidate. Since // we're not actually inlining, don't report anything. - prejitResult.SetReported(); + prejitResult.SetSuccessResult(INLINE_PREJIT_SUCCESS); } } else diff --git a/src/coreclr/jit/fginline.cpp b/src/coreclr/jit/fginline.cpp index fe0746aa26d72e..d59301991aaa61 100644 --- a/src/coreclr/jit/fginline.cpp +++ b/src/coreclr/jit/fginline.cpp @@ -274,7 +274,7 @@ void Compiler::fgNoteNonInlineCandidate(Statement* stmt, GenTreeCall* call) return; } - InlineResult inlineResult(this, call, nullptr, "fgNoteNonInlineCandidate"); + InlineResult inlineResult(this, call, nullptr, "fgNoteNonInlineCandidate", false); InlineObservation currentObservation = InlineObservation::CALLSITE_NOT_CANDIDATE; // Try and recover the reason left behind when the jit decided @@ -288,7 +288,6 @@ void Compiler::fgNoteNonInlineCandidate(Statement* stmt, GenTreeCall* call) // Propagate the prior failure observation to this result. inlineResult.NotePriorFailure(currentObservation); - inlineResult.SetReported(); if (call->gtCallType == CT_USER_FUNC) { diff --git a/src/coreclr/jit/hwintrinsic.cpp b/src/coreclr/jit/hwintrinsic.cpp index 0885892bcd6304..1cec85df393a1c 100644 --- a/src/coreclr/jit/hwintrinsic.cpp +++ b/src/coreclr/jit/hwintrinsic.cpp @@ -640,48 +640,15 @@ static bool isSupportedBaseType(NamedIntrinsic intrinsic, CorInfoType baseJitTyp return true; } +#ifdef DEBUG + CORINFO_InstructionSet isa = HWIntrinsicInfo::lookupIsa(intrinsic); #ifdef TARGET_XARCH - assert((intrinsic == NI_Vector128_As) || (intrinsic == NI_Vector128_AsByte) || - (intrinsic == NI_Vector128_AsDouble) || (intrinsic == NI_Vector128_AsInt16) || - (intrinsic == NI_Vector128_AsInt32) || (intrinsic == NI_Vector128_AsInt64) || - (intrinsic == NI_Vector128_AsSByte) || (intrinsic == NI_Vector128_AsSingle) || - (intrinsic == NI_Vector128_AsUInt16) || (intrinsic == NI_Vector128_AsUInt32) || - (intrinsic == NI_Vector128_AsUInt64) || (intrinsic == NI_Vector128_get_AllBitsSet) || - (intrinsic == NI_Vector128_get_Count) || (intrinsic == NI_Vector128_get_Zero) || - (intrinsic == NI_Vector128_GetElement) || (intrinsic == NI_Vector128_WithElement) || - (intrinsic == NI_Vector128_ToScalar) || (intrinsic == NI_Vector128_ToVector256) || - (intrinsic == NI_Vector128_ToVector256Unsafe) || (intrinsic == NI_Vector256_As) || - (intrinsic == NI_Vector256_AsByte) || (intrinsic == NI_Vector256_AsDouble) || - (intrinsic == NI_Vector256_AsInt16) || (intrinsic == NI_Vector256_AsInt32) || - (intrinsic == NI_Vector256_AsInt64) || (intrinsic == NI_Vector256_AsSByte) || - (intrinsic == NI_Vector256_AsSingle) || (intrinsic == NI_Vector256_AsUInt16) || - (intrinsic == NI_Vector256_AsUInt32) || (intrinsic == NI_Vector256_AsUInt64) || - (intrinsic == NI_Vector256_get_AllBitsSet) || (intrinsic == NI_Vector256_get_Count) || - (intrinsic == NI_Vector256_get_Zero) || (intrinsic == NI_Vector256_GetElement) || - (intrinsic == NI_Vector256_WithElement) || (intrinsic == NI_Vector256_GetLower) || - (intrinsic == NI_Vector256_ToScalar)); + assert((isa == InstructionSet_Vector256) || (isa == InstructionSet_Vector128)); #endif // TARGET_XARCH #ifdef TARGET_ARM64 - assert((intrinsic == NI_Vector64_As) || (intrinsic == NI_Vector64_AsByte) || (intrinsic == NI_Vector64_AsDouble) || - (intrinsic == NI_Vector64_AsInt16) || (intrinsic == NI_Vector64_AsInt32) || - (intrinsic == NI_Vector64_AsInt64) || (intrinsic == NI_Vector64_AsSByte) || - (intrinsic == NI_Vector64_AsSingle) || (intrinsic == NI_Vector64_AsUInt16) || - (intrinsic == NI_Vector64_AsUInt32) || (intrinsic == NI_Vector64_AsUInt64) || - (intrinsic == NI_Vector64_get_AllBitsSet) || (intrinsic == NI_Vector64_get_Count) || - (intrinsic == NI_Vector64_get_Zero) || (intrinsic == NI_Vector64_GetElement) || - (intrinsic == NI_Vector64_ToScalar) || (intrinsic == NI_Vector64_ToVector128) || - (intrinsic == NI_Vector64_ToVector128Unsafe) || (intrinsic == NI_Vector64_WithElement) || - (intrinsic == NI_Vector128_As) || (intrinsic == NI_Vector128_AsByte) || - (intrinsic == NI_Vector128_AsDouble) || (intrinsic == NI_Vector128_AsInt16) || - (intrinsic == NI_Vector128_AsInt32) || (intrinsic == NI_Vector128_AsInt64) || - (intrinsic == NI_Vector128_AsSByte) || (intrinsic == NI_Vector128_AsSingle) || - (intrinsic == NI_Vector128_AsUInt16) || (intrinsic == NI_Vector128_AsUInt32) || - (intrinsic == NI_Vector128_AsUInt64) || (intrinsic == NI_Vector128_get_AllBitsSet) || - (intrinsic == NI_Vector128_get_Count) || (intrinsic == NI_Vector128_get_Zero) || - (intrinsic == NI_Vector128_GetElement) || (intrinsic == NI_Vector128_GetLower) || - (intrinsic == NI_Vector128_GetUpper) || (intrinsic == NI_Vector128_ToScalar) || - (intrinsic == NI_Vector128_WithElement)); + assert((isa == InstructionSet_Vector64) || (isa == InstructionSet_Vector128)); #endif // TARGET_ARM64 +#endif // DEBUG return false; } diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 5ddc2eed4f144f..0a774bdfcc7b70 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -19905,8 +19905,8 @@ void Compiler::impCheckCanInline(GenTreeCall* call, if (pParam->result->IsFailure()) { - // Make sure not to report this one. It was already reported by the VM. - pParam->result->SetReported(); + // Do not report this as a failure. Instead report as a "VM failure" + pParam->result->SetVMFailure(); goto _exit; } @@ -21199,7 +21199,7 @@ void Compiler::impMarkInlineCandidateHelper(GenTreeCall* call, // Since we're not actually inlining yet, and this call site is // still just an inline candidate, there's nothing to report. - inlineResult.SetReported(); + inlineResult.SetSuccessResult(INLINE_CHECK_CAN_INLINE_SUCCESS); } /******************************************************************************/ diff --git a/src/coreclr/jit/inline.cpp b/src/coreclr/jit/inline.cpp index 546eb2aa376f9d..7f3c65fde97ff4 100644 --- a/src/coreclr/jit/inline.cpp +++ b/src/coreclr/jit/inline.cpp @@ -643,7 +643,8 @@ void InlineContext::DumpXml(FILE* file, unsigned indent) // stmt - statement containing the call (if known) // description - string describing the context of the decision -InlineResult::InlineResult(Compiler* compiler, GenTreeCall* call, Statement* stmt, const char* description) +InlineResult::InlineResult( + Compiler* compiler, GenTreeCall* call, Statement* stmt, const char* description, bool doNotReport) : m_RootCompiler(nullptr) , m_Policy(nullptr) , m_Call(call) @@ -652,7 +653,9 @@ InlineResult::InlineResult(Compiler* compiler, GenTreeCall* call, Statement* stm , m_Callee(nullptr) , m_ImportedILSize(0) , m_Description(description) - , m_Reported(false) + , m_successResult(INLINE_PASS) + , m_DoNotReport(doNotReport) + , m_reportFailureAsVmFailure(false) { // Set the compiler instance m_RootCompiler = compiler->impInlineRoot(); @@ -683,6 +686,12 @@ InlineResult::InlineResult(Compiler* compiler, GenTreeCall* call, Statement* stm { m_Callee = m_Call->AsCall()->gtCallMethHnd; } + + if (!m_DoNotReport) + { + COMP_HANDLE comp = m_RootCompiler->info.compCompHnd; + comp->beginInlining(m_Caller, m_Callee); + } } //------------------------------------------------------------------------ @@ -701,7 +710,7 @@ InlineResult::InlineResult(Compiler* compiler, GenTreeCall* call, Statement* stm // We use the inlCallee member to track the method since logically // it is the callee here. -InlineResult::InlineResult(Compiler* compiler, CORINFO_METHOD_HANDLE method, const char* description) +InlineResult::InlineResult(Compiler* compiler, CORINFO_METHOD_HANDLE method, const char* description, bool doNotReport) : m_RootCompiler(nullptr) , m_Policy(nullptr) , m_Call(nullptr) @@ -709,7 +718,9 @@ InlineResult::InlineResult(Compiler* compiler, CORINFO_METHOD_HANDLE method, con , m_Caller(nullptr) , m_Callee(method) , m_Description(description) - , m_Reported(false) + , m_successResult(INLINE_PASS) + , m_DoNotReport(doNotReport) + , m_reportFailureAsVmFailure(false) { // Set the compiler instance m_RootCompiler = compiler->impInlineRoot(); @@ -717,6 +728,12 @@ InlineResult::InlineResult(Compiler* compiler, CORINFO_METHOD_HANDLE method, con // Set the policy const bool isPrejitRoot = true; m_Policy = InlinePolicy::GetPolicy(m_RootCompiler, isPrejitRoot); + + if (!m_DoNotReport) + { + COMP_HANDLE comp = m_RootCompiler->info.compCompHnd; + comp->beginInlining(m_Caller, m_Callee); + } } //------------------------------------------------------------------------ @@ -731,8 +748,6 @@ InlineResult::InlineResult(Compiler* compiler, CORINFO_METHOD_HANDLE method, con // EE. Optionally update the method attribute to NOINLINE if // observation and policy warrant. // -// All this can be suppressed if desired by calling setReported() -// before the InlineResult goes out of scope. void InlineResult::Report() { @@ -753,13 +768,13 @@ void InlineResult::Report() #endif // DEBUG // If we weren't actually inlining, user may have suppressed - // reporting via setReported(). If so, do nothing. - if (m_Reported) + // reporting. If so, do nothing. + if (m_DoNotReport) { return; } - m_Reported = true; + m_DoNotReport = true; #ifdef DEBUG const char* callee = nullptr; @@ -798,7 +813,7 @@ void InlineResult::Report() } } - if (IsDecided()) + if (IsDecided() || m_reportFailureAsVmFailure || m_successResult != INLINE_PASS) { const char* format = "INLINER: during '%s' result '%s' reason '%s'\n"; JITLOG_THIS(m_RootCompiler, (LL_INFO100000, format, m_Description, ResultString(), ReasonString())); diff --git a/src/coreclr/jit/inline.h b/src/coreclr/jit/inline.h index e5ec2ea3cc10e5..763f5bc382c46b 100644 --- a/src/coreclr/jit/inline.h +++ b/src/coreclr/jit/inline.h @@ -344,11 +344,12 @@ class InlineResult public: // Construct a new InlineResult to help evaluate a // particular call for inlining. - InlineResult(Compiler* compiler, GenTreeCall* call, Statement* stmt, const char* description); + InlineResult( + Compiler* compiler, GenTreeCall* call, Statement* stmt, const char* description, bool doNotReport = false); // Construct a new InlineResult to evaluate a particular // method to see if it is inlineable. - InlineResult(Compiler* compiler, CORINFO_METHOD_HANDLE method, const char* description); + InlineResult(Compiler* compiler, CORINFO_METHOD_HANDLE method, const char* description, bool doNotReport = false); // Has the policy determined this inline should fail? bool IsFailure() const @@ -483,18 +484,42 @@ class InlineResult // Result that can be reported back to the runtime CorInfoInline Result() const { + if (m_reportFailureAsVmFailure) + return INLINE_CHECK_CAN_INLINE_VMFAIL; + + if (m_successResult != INLINE_PASS) + return m_successResult; + return InlGetCorInfoInlineDecision(m_Policy->GetDecision()); } // String describing the decision made const char* ResultString() const { + if (m_reportFailureAsVmFailure) + return "VM Reported !CanInline"; + + if (m_successResult == INLINE_PREJIT_SUCCESS) + return "PreJIT Success"; + + if (m_successResult == INLINE_CHECK_CAN_INLINE_SUCCESS) + return "CheckCanInline Success"; + return InlGetDecisionString(m_Policy->GetDecision()); } // String describing the reason for the decision const char* ReasonString() const { + if (m_reportFailureAsVmFailure) + return "VM Reported !CanInline"; + + if (m_successResult == INLINE_PREJIT_SUCCESS) + return "PreJIT Success"; + + if (m_successResult == INLINE_CHECK_CAN_INLINE_SUCCESS) + return "CheckCanInline Success"; + return InlGetObservationString(m_Policy->GetObservation()); } @@ -504,12 +529,15 @@ class InlineResult return m_Policy; } - // SetReported indicates that this particular result doesn't need - // to be reported back to the runtime, either because the runtime - // already knows, or we aren't actually inlining yet. - void SetReported() + // Set the code that shall be reported if the InlineResult is a success + void SetSuccessResult(CorInfoInline inlineSuccessCode) + { + m_successResult = inlineSuccessCode; + } + + void SetVMFailure() { - m_Reported = true; + m_reportFailureAsVmFailure = true; } // Get the InlineContext for this inline. @@ -544,7 +572,9 @@ class InlineResult CORINFO_METHOD_HANDLE m_Callee; unsigned m_ImportedILSize; // estimated size of imported IL const char* m_Description; - bool m_Reported; + CorInfoInline m_successResult; + bool m_DoNotReport; + bool m_reportFailureAsVmFailure; }; // ClassProfileCandidateInfo provides information about diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs index fa7a9f8688d507..c618b888595851 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoBase.cs @@ -100,6 +100,20 @@ static CorInfoInline _canInline(IntPtr thisHandle, IntPtr* ppException, CORINFO_ } } + [UnmanagedCallersOnly] + static void _beginInlining(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* inlinerHnd, CORINFO_METHOD_STRUCT_* inlineeHnd) + { + var _this = GetThis(thisHandle); + try + { + _this.beginInlining(inlinerHnd, inlineeHnd); + } + catch (Exception ex) + { + *ppException = _this.AllocException(ex); + } + } + [UnmanagedCallersOnly] static void _reportInliningDecision(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* inlinerHnd, CORINFO_METHOD_STRUCT_* inlineeHnd, CorInfoInline inlineResult, byte* reason) { @@ -2552,7 +2566,7 @@ static uint _getJitFlags(IntPtr thisHandle, IntPtr* ppException, CORJIT_FLAGS* f static IntPtr GetUnmanagedCallbacks() { - void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 172); + void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 173); callbacks[0] = (delegate* unmanaged)&_isIntrinsic; callbacks[1] = (delegate* unmanaged)&_getMethodAttribs; @@ -2560,172 +2574,173 @@ static IntPtr GetUnmanagedCallbacks() callbacks[3] = (delegate* unmanaged)&_getMethodSig; callbacks[4] = (delegate* unmanaged)&_getMethodInfo; callbacks[5] = (delegate* unmanaged)&_canInline; - callbacks[6] = (delegate* unmanaged)&_reportInliningDecision; - callbacks[7] = (delegate* unmanaged)&_canTailCall; - callbacks[8] = (delegate* unmanaged)&_reportTailCallDecision; - callbacks[9] = (delegate* unmanaged)&_getEHinfo; - callbacks[10] = (delegate* unmanaged)&_getMethodClass; - callbacks[11] = (delegate* unmanaged)&_getMethodModule; - callbacks[12] = (delegate* unmanaged)&_getMethodVTableOffset; - callbacks[13] = (delegate* unmanaged)&_resolveVirtualMethod; - callbacks[14] = (delegate* unmanaged)&_getUnboxedEntry; - callbacks[15] = (delegate* unmanaged)&_getDefaultComparerClass; - callbacks[16] = (delegate* unmanaged)&_getDefaultEqualityComparerClass; - callbacks[17] = (delegate* unmanaged)&_expandRawHandleIntrinsic; - callbacks[18] = (delegate* unmanaged)&_isIntrinsicType; - callbacks[19] = (delegate* unmanaged)&_getUnmanagedCallConv; - callbacks[20] = (delegate* unmanaged)&_pInvokeMarshalingRequired; - callbacks[21] = (delegate* unmanaged)&_satisfiesMethodConstraints; - callbacks[22] = (delegate* unmanaged)&_isCompatibleDelegate; - callbacks[23] = (delegate* unmanaged)&_methodMustBeLoadedBeforeCodeIsRun; - callbacks[24] = (delegate* unmanaged)&_mapMethodDeclToMethodImpl; - callbacks[25] = (delegate* unmanaged)&_getGSCookie; - callbacks[26] = (delegate* unmanaged)&_setPatchpointInfo; - callbacks[27] = (delegate* unmanaged)&_getOSRInfo; - callbacks[28] = (delegate* unmanaged)&_resolveToken; - callbacks[29] = (delegate* unmanaged)&_tryResolveToken; - callbacks[30] = (delegate* unmanaged)&_findSig; - callbacks[31] = (delegate* unmanaged)&_findCallSiteSig; - callbacks[32] = (delegate* unmanaged)&_getTokenTypeAsHandle; - callbacks[33] = (delegate* unmanaged)&_isValidToken; - callbacks[34] = (delegate* unmanaged)&_isValidStringRef; - callbacks[35] = (delegate* unmanaged)&_getStringLiteral; - callbacks[36] = (delegate* unmanaged)&_asCorInfoType; - callbacks[37] = (delegate* unmanaged)&_getClassName; - callbacks[38] = (delegate* unmanaged)&_getClassNameFromMetadata; - callbacks[39] = (delegate* unmanaged)&_getTypeInstantiationArgument; - callbacks[40] = (delegate* unmanaged)&_appendClassName; - callbacks[41] = (delegate* unmanaged)&_isValueClass; - callbacks[42] = (delegate* unmanaged)&_canInlineTypeCheck; - callbacks[43] = (delegate* unmanaged)&_getClassAttribs; - callbacks[44] = (delegate* unmanaged)&_getClassModule; - callbacks[45] = (delegate* unmanaged)&_getModuleAssembly; - callbacks[46] = (delegate* unmanaged)&_getAssemblyName; - callbacks[47] = (delegate* unmanaged)&_LongLifetimeMalloc; - callbacks[48] = (delegate* unmanaged)&_LongLifetimeFree; - callbacks[49] = (delegate* unmanaged)&_getClassModuleIdForStatics; - callbacks[50] = (delegate* unmanaged)&_getClassSize; - callbacks[51] = (delegate* unmanaged)&_getHeapClassSize; - callbacks[52] = (delegate* unmanaged)&_canAllocateOnStack; - callbacks[53] = (delegate* unmanaged)&_getClassAlignmentRequirement; - callbacks[54] = (delegate* unmanaged)&_getClassGClayout; - callbacks[55] = (delegate* unmanaged)&_getClassNumInstanceFields; - callbacks[56] = (delegate* unmanaged)&_getFieldInClass; - callbacks[57] = (delegate* unmanaged)&_checkMethodModifier; - callbacks[58] = (delegate* unmanaged)&_getNewHelper; - callbacks[59] = (delegate* unmanaged)&_getNewArrHelper; - callbacks[60] = (delegate* unmanaged)&_getCastingHelper; - callbacks[61] = (delegate* unmanaged)&_getSharedCCtorHelper; - callbacks[62] = (delegate* unmanaged)&_getTypeForBox; - callbacks[63] = (delegate* unmanaged)&_getBoxHelper; - callbacks[64] = (delegate* unmanaged)&_getUnBoxHelper; - callbacks[65] = (delegate* unmanaged)&_getReadyToRunHelper; - callbacks[66] = (delegate* unmanaged)&_getReadyToRunDelegateCtorHelper; - callbacks[67] = (delegate* unmanaged)&_getHelperName; - callbacks[68] = (delegate* unmanaged)&_initClass; - callbacks[69] = (delegate* unmanaged)&_classMustBeLoadedBeforeCodeIsRun; - callbacks[70] = (delegate* unmanaged)&_getBuiltinClass; - callbacks[71] = (delegate* unmanaged)&_getTypeForPrimitiveValueClass; - callbacks[72] = (delegate* unmanaged)&_getTypeForPrimitiveNumericClass; - callbacks[73] = (delegate* unmanaged)&_canCast; - callbacks[74] = (delegate* unmanaged)&_areTypesEquivalent; - callbacks[75] = (delegate* unmanaged)&_compareTypesForCast; - callbacks[76] = (delegate* unmanaged)&_compareTypesForEquality; - callbacks[77] = (delegate* unmanaged)&_mergeClasses; - callbacks[78] = (delegate* unmanaged)&_isMoreSpecificType; - callbacks[79] = (delegate* unmanaged)&_getParentType; - callbacks[80] = (delegate* unmanaged)&_getChildType; - callbacks[81] = (delegate* unmanaged)&_satisfiesClassConstraints; - callbacks[82] = (delegate* unmanaged)&_isSDArray; - callbacks[83] = (delegate* unmanaged)&_getArrayRank; - callbacks[84] = (delegate* unmanaged)&_getArrayIntrinsicID; - callbacks[85] = (delegate* unmanaged)&_getArrayInitializationData; - callbacks[86] = (delegate* unmanaged)&_canAccessClass; - callbacks[87] = (delegate* unmanaged)&_getFieldName; - callbacks[88] = (delegate* unmanaged)&_getFieldClass; - callbacks[89] = (delegate* unmanaged)&_getFieldType; - callbacks[90] = (delegate* unmanaged)&_getFieldOffset; - callbacks[91] = (delegate* unmanaged)&_getFieldInfo; - callbacks[92] = (delegate* unmanaged)&_isFieldStatic; - callbacks[93] = (delegate* unmanaged)&_getBoundaries; - callbacks[94] = (delegate* unmanaged)&_setBoundaries; - callbacks[95] = (delegate* unmanaged)&_getVars; - callbacks[96] = (delegate* unmanaged)&_setVars; - callbacks[97] = (delegate* unmanaged)&_allocateArray; - callbacks[98] = (delegate* unmanaged)&_freeArray; - callbacks[99] = (delegate* unmanaged)&_getArgNext; - callbacks[100] = (delegate* unmanaged)&_getArgType; - callbacks[101] = (delegate* unmanaged)&_getArgClass; - callbacks[102] = (delegate* unmanaged)&_getHFAType; - callbacks[103] = (delegate* unmanaged)&_GetErrorHRESULT; - callbacks[104] = (delegate* unmanaged)&_GetErrorMessage; - callbacks[105] = (delegate* unmanaged)&_FilterException; - callbacks[106] = (delegate* unmanaged)&_ThrowExceptionForJitResult; - callbacks[107] = (delegate* unmanaged)&_ThrowExceptionForHelper; - callbacks[108] = (delegate* unmanaged)&_runWithErrorTrap; - callbacks[109] = (delegate* unmanaged)&_runWithSPMIErrorTrap; - callbacks[110] = (delegate* unmanaged)&_getEEInfo; - callbacks[111] = (delegate* unmanaged)&_getJitTimeLogFilename; - callbacks[112] = (delegate* unmanaged)&_getMethodDefFromMethod; - callbacks[113] = (delegate* unmanaged)&_getMethodName; - callbacks[114] = (delegate* unmanaged)&_getMethodNameFromMetadata; - callbacks[115] = (delegate* unmanaged)&_getMethodHash; - callbacks[116] = (delegate* unmanaged)&_findNameOfToken; - callbacks[117] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor; - callbacks[118] = (delegate* unmanaged)&_getLoongArch64PassStructInRegisterFlags; - callbacks[119] = (delegate* unmanaged)&_getThreadTLSIndex; - callbacks[120] = (delegate* unmanaged)&_getInlinedCallFrameVptr; - callbacks[121] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal; - callbacks[122] = (delegate* unmanaged)&_getHelperFtn; - callbacks[123] = (delegate* unmanaged)&_getFunctionEntryPoint; - callbacks[124] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; - callbacks[125] = (delegate* unmanaged)&_getMethodSync; - callbacks[126] = (delegate* unmanaged)&_getLazyStringLiteralHelper; - callbacks[127] = (delegate* unmanaged)&_embedModuleHandle; - callbacks[128] = (delegate* unmanaged)&_embedClassHandle; - callbacks[129] = (delegate* unmanaged)&_embedMethodHandle; - callbacks[130] = (delegate* unmanaged)&_embedFieldHandle; - callbacks[131] = (delegate* unmanaged)&_embedGenericHandle; - callbacks[132] = (delegate* unmanaged)&_getLocationOfThisType; - callbacks[133] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; - callbacks[134] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; - callbacks[135] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; - callbacks[136] = (delegate* unmanaged)&_getJustMyCodeHandle; - callbacks[137] = (delegate* unmanaged)&_GetProfilingHandle; - callbacks[138] = (delegate* unmanaged)&_getCallInfo; - callbacks[139] = (delegate* unmanaged)&_canAccessFamily; - callbacks[140] = (delegate* unmanaged)&_isRIDClassDomainID; - callbacks[141] = (delegate* unmanaged)&_getClassDomainID; - callbacks[142] = (delegate* unmanaged)&_getFieldAddress; - callbacks[143] = (delegate* unmanaged)&_getStaticFieldCurrentClass; - callbacks[144] = (delegate* unmanaged)&_getVarArgsHandle; - callbacks[145] = (delegate* unmanaged)&_canGetVarArgsHandle; - callbacks[146] = (delegate* unmanaged)&_constructStringLiteral; - callbacks[147] = (delegate* unmanaged)&_emptyStringLiteral; - callbacks[148] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; - callbacks[149] = (delegate* unmanaged)&_addActiveDependency; - callbacks[150] = (delegate* unmanaged)&_GetDelegateCtor; - callbacks[151] = (delegate* unmanaged)&_MethodCompileComplete; - callbacks[152] = (delegate* unmanaged)&_getTailCallHelpers; - callbacks[153] = (delegate* unmanaged)&_convertPInvokeCalliToCall; - callbacks[154] = (delegate* unmanaged)&_notifyInstructionSetUsage; - callbacks[155] = (delegate* unmanaged)&_updateEntryPointForTailCall; - callbacks[156] = (delegate* unmanaged)&_allocMem; - callbacks[157] = (delegate* unmanaged)&_reserveUnwindInfo; - callbacks[158] = (delegate* unmanaged)&_allocUnwindInfo; - callbacks[159] = (delegate* unmanaged)&_allocGCInfo; - callbacks[160] = (delegate* unmanaged)&_setEHcount; - callbacks[161] = (delegate* unmanaged)&_setEHinfo; - callbacks[162] = (delegate* unmanaged)&_logMsg; - callbacks[163] = (delegate* unmanaged)&_doAssert; - callbacks[164] = (delegate* unmanaged)&_reportFatalError; - callbacks[165] = (delegate* unmanaged)&_getPgoInstrumentationResults; - callbacks[166] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema; - callbacks[167] = (delegate* unmanaged)&_recordCallSite; - callbacks[168] = (delegate* unmanaged)&_recordRelocation; - callbacks[169] = (delegate* unmanaged)&_getRelocTypeHint; - callbacks[170] = (delegate* unmanaged)&_getExpectedTargetArchitecture; - callbacks[171] = (delegate* unmanaged)&_getJitFlags; + callbacks[6] = (delegate* unmanaged)&_beginInlining; + callbacks[7] = (delegate* unmanaged)&_reportInliningDecision; + callbacks[8] = (delegate* unmanaged)&_canTailCall; + callbacks[9] = (delegate* unmanaged)&_reportTailCallDecision; + callbacks[10] = (delegate* unmanaged)&_getEHinfo; + callbacks[11] = (delegate* unmanaged)&_getMethodClass; + callbacks[12] = (delegate* unmanaged)&_getMethodModule; + callbacks[13] = (delegate* unmanaged)&_getMethodVTableOffset; + callbacks[14] = (delegate* unmanaged)&_resolveVirtualMethod; + callbacks[15] = (delegate* unmanaged)&_getUnboxedEntry; + callbacks[16] = (delegate* unmanaged)&_getDefaultComparerClass; + callbacks[17] = (delegate* unmanaged)&_getDefaultEqualityComparerClass; + callbacks[18] = (delegate* unmanaged)&_expandRawHandleIntrinsic; + callbacks[19] = (delegate* unmanaged)&_isIntrinsicType; + callbacks[20] = (delegate* unmanaged)&_getUnmanagedCallConv; + callbacks[21] = (delegate* unmanaged)&_pInvokeMarshalingRequired; + callbacks[22] = (delegate* unmanaged)&_satisfiesMethodConstraints; + callbacks[23] = (delegate* unmanaged)&_isCompatibleDelegate; + callbacks[24] = (delegate* unmanaged)&_methodMustBeLoadedBeforeCodeIsRun; + callbacks[25] = (delegate* unmanaged)&_mapMethodDeclToMethodImpl; + callbacks[26] = (delegate* unmanaged)&_getGSCookie; + callbacks[27] = (delegate* unmanaged)&_setPatchpointInfo; + callbacks[28] = (delegate* unmanaged)&_getOSRInfo; + callbacks[29] = (delegate* unmanaged)&_resolveToken; + callbacks[30] = (delegate* unmanaged)&_tryResolveToken; + callbacks[31] = (delegate* unmanaged)&_findSig; + callbacks[32] = (delegate* unmanaged)&_findCallSiteSig; + callbacks[33] = (delegate* unmanaged)&_getTokenTypeAsHandle; + callbacks[34] = (delegate* unmanaged)&_isValidToken; + callbacks[35] = (delegate* unmanaged)&_isValidStringRef; + callbacks[36] = (delegate* unmanaged)&_getStringLiteral; + callbacks[37] = (delegate* unmanaged)&_asCorInfoType; + callbacks[38] = (delegate* unmanaged)&_getClassName; + callbacks[39] = (delegate* unmanaged)&_getClassNameFromMetadata; + callbacks[40] = (delegate* unmanaged)&_getTypeInstantiationArgument; + callbacks[41] = (delegate* unmanaged)&_appendClassName; + callbacks[42] = (delegate* unmanaged)&_isValueClass; + callbacks[43] = (delegate* unmanaged)&_canInlineTypeCheck; + callbacks[44] = (delegate* unmanaged)&_getClassAttribs; + callbacks[45] = (delegate* unmanaged)&_getClassModule; + callbacks[46] = (delegate* unmanaged)&_getModuleAssembly; + callbacks[47] = (delegate* unmanaged)&_getAssemblyName; + callbacks[48] = (delegate* unmanaged)&_LongLifetimeMalloc; + callbacks[49] = (delegate* unmanaged)&_LongLifetimeFree; + callbacks[50] = (delegate* unmanaged)&_getClassModuleIdForStatics; + callbacks[51] = (delegate* unmanaged)&_getClassSize; + callbacks[52] = (delegate* unmanaged)&_getHeapClassSize; + callbacks[53] = (delegate* unmanaged)&_canAllocateOnStack; + callbacks[54] = (delegate* unmanaged)&_getClassAlignmentRequirement; + callbacks[55] = (delegate* unmanaged)&_getClassGClayout; + callbacks[56] = (delegate* unmanaged)&_getClassNumInstanceFields; + callbacks[57] = (delegate* unmanaged)&_getFieldInClass; + callbacks[58] = (delegate* unmanaged)&_checkMethodModifier; + callbacks[59] = (delegate* unmanaged)&_getNewHelper; + callbacks[60] = (delegate* unmanaged)&_getNewArrHelper; + callbacks[61] = (delegate* unmanaged)&_getCastingHelper; + callbacks[62] = (delegate* unmanaged)&_getSharedCCtorHelper; + callbacks[63] = (delegate* unmanaged)&_getTypeForBox; + callbacks[64] = (delegate* unmanaged)&_getBoxHelper; + callbacks[65] = (delegate* unmanaged)&_getUnBoxHelper; + callbacks[66] = (delegate* unmanaged)&_getReadyToRunHelper; + callbacks[67] = (delegate* unmanaged)&_getReadyToRunDelegateCtorHelper; + callbacks[68] = (delegate* unmanaged)&_getHelperName; + callbacks[69] = (delegate* unmanaged)&_initClass; + callbacks[70] = (delegate* unmanaged)&_classMustBeLoadedBeforeCodeIsRun; + callbacks[71] = (delegate* unmanaged)&_getBuiltinClass; + callbacks[72] = (delegate* unmanaged)&_getTypeForPrimitiveValueClass; + callbacks[73] = (delegate* unmanaged)&_getTypeForPrimitiveNumericClass; + callbacks[74] = (delegate* unmanaged)&_canCast; + callbacks[75] = (delegate* unmanaged)&_areTypesEquivalent; + callbacks[76] = (delegate* unmanaged)&_compareTypesForCast; + callbacks[77] = (delegate* unmanaged)&_compareTypesForEquality; + callbacks[78] = (delegate* unmanaged)&_mergeClasses; + callbacks[79] = (delegate* unmanaged)&_isMoreSpecificType; + callbacks[80] = (delegate* unmanaged)&_getParentType; + callbacks[81] = (delegate* unmanaged)&_getChildType; + callbacks[82] = (delegate* unmanaged)&_satisfiesClassConstraints; + callbacks[83] = (delegate* unmanaged)&_isSDArray; + callbacks[84] = (delegate* unmanaged)&_getArrayRank; + callbacks[85] = (delegate* unmanaged)&_getArrayIntrinsicID; + callbacks[86] = (delegate* unmanaged)&_getArrayInitializationData; + callbacks[87] = (delegate* unmanaged)&_canAccessClass; + callbacks[88] = (delegate* unmanaged)&_getFieldName; + callbacks[89] = (delegate* unmanaged)&_getFieldClass; + callbacks[90] = (delegate* unmanaged)&_getFieldType; + callbacks[91] = (delegate* unmanaged)&_getFieldOffset; + callbacks[92] = (delegate* unmanaged)&_getFieldInfo; + callbacks[93] = (delegate* unmanaged)&_isFieldStatic; + callbacks[94] = (delegate* unmanaged)&_getBoundaries; + callbacks[95] = (delegate* unmanaged)&_setBoundaries; + callbacks[96] = (delegate* unmanaged)&_getVars; + callbacks[97] = (delegate* unmanaged)&_setVars; + callbacks[98] = (delegate* unmanaged)&_allocateArray; + callbacks[99] = (delegate* unmanaged)&_freeArray; + callbacks[100] = (delegate* unmanaged)&_getArgNext; + callbacks[101] = (delegate* unmanaged)&_getArgType; + callbacks[102] = (delegate* unmanaged)&_getArgClass; + callbacks[103] = (delegate* unmanaged)&_getHFAType; + callbacks[104] = (delegate* unmanaged)&_GetErrorHRESULT; + callbacks[105] = (delegate* unmanaged)&_GetErrorMessage; + callbacks[106] = (delegate* unmanaged)&_FilterException; + callbacks[107] = (delegate* unmanaged)&_ThrowExceptionForJitResult; + callbacks[108] = (delegate* unmanaged)&_ThrowExceptionForHelper; + callbacks[109] = (delegate* unmanaged)&_runWithErrorTrap; + callbacks[110] = (delegate* unmanaged)&_runWithSPMIErrorTrap; + callbacks[111] = (delegate* unmanaged)&_getEEInfo; + callbacks[112] = (delegate* unmanaged)&_getJitTimeLogFilename; + callbacks[113] = (delegate* unmanaged)&_getMethodDefFromMethod; + callbacks[114] = (delegate* unmanaged)&_getMethodName; + callbacks[115] = (delegate* unmanaged)&_getMethodNameFromMetadata; + callbacks[116] = (delegate* unmanaged)&_getMethodHash; + callbacks[117] = (delegate* unmanaged)&_findNameOfToken; + callbacks[118] = (delegate* unmanaged)&_getSystemVAmd64PassStructInRegisterDescriptor; + callbacks[119] = (delegate* unmanaged)&_getLoongArch64PassStructInRegisterFlags; + callbacks[120] = (delegate* unmanaged)&_getThreadTLSIndex; + callbacks[121] = (delegate* unmanaged)&_getInlinedCallFrameVptr; + callbacks[122] = (delegate* unmanaged)&_getAddrOfCaptureThreadGlobal; + callbacks[123] = (delegate* unmanaged)&_getHelperFtn; + callbacks[124] = (delegate* unmanaged)&_getFunctionEntryPoint; + callbacks[125] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; + callbacks[126] = (delegate* unmanaged)&_getMethodSync; + callbacks[127] = (delegate* unmanaged)&_getLazyStringLiteralHelper; + callbacks[128] = (delegate* unmanaged)&_embedModuleHandle; + callbacks[129] = (delegate* unmanaged)&_embedClassHandle; + callbacks[130] = (delegate* unmanaged)&_embedMethodHandle; + callbacks[131] = (delegate* unmanaged)&_embedFieldHandle; + callbacks[132] = (delegate* unmanaged)&_embedGenericHandle; + callbacks[133] = (delegate* unmanaged)&_getLocationOfThisType; + callbacks[134] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; + callbacks[135] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; + callbacks[136] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; + callbacks[137] = (delegate* unmanaged)&_getJustMyCodeHandle; + callbacks[138] = (delegate* unmanaged)&_GetProfilingHandle; + callbacks[139] = (delegate* unmanaged)&_getCallInfo; + callbacks[140] = (delegate* unmanaged)&_canAccessFamily; + callbacks[141] = (delegate* unmanaged)&_isRIDClassDomainID; + callbacks[142] = (delegate* unmanaged)&_getClassDomainID; + callbacks[143] = (delegate* unmanaged)&_getFieldAddress; + callbacks[144] = (delegate* unmanaged)&_getStaticFieldCurrentClass; + callbacks[145] = (delegate* unmanaged)&_getVarArgsHandle; + callbacks[146] = (delegate* unmanaged)&_canGetVarArgsHandle; + callbacks[147] = (delegate* unmanaged)&_constructStringLiteral; + callbacks[148] = (delegate* unmanaged)&_emptyStringLiteral; + callbacks[149] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; + callbacks[150] = (delegate* unmanaged)&_addActiveDependency; + callbacks[151] = (delegate* unmanaged)&_GetDelegateCtor; + callbacks[152] = (delegate* unmanaged)&_MethodCompileComplete; + callbacks[153] = (delegate* unmanaged)&_getTailCallHelpers; + callbacks[154] = (delegate* unmanaged)&_convertPInvokeCalliToCall; + callbacks[155] = (delegate* unmanaged)&_notifyInstructionSetUsage; + callbacks[156] = (delegate* unmanaged)&_updateEntryPointForTailCall; + callbacks[157] = (delegate* unmanaged)&_allocMem; + callbacks[158] = (delegate* unmanaged)&_reserveUnwindInfo; + callbacks[159] = (delegate* unmanaged)&_allocUnwindInfo; + callbacks[160] = (delegate* unmanaged)&_allocGCInfo; + callbacks[161] = (delegate* unmanaged)&_setEHcount; + callbacks[162] = (delegate* unmanaged)&_setEHinfo; + callbacks[163] = (delegate* unmanaged)&_logMsg; + callbacks[164] = (delegate* unmanaged)&_doAssert; + callbacks[165] = (delegate* unmanaged)&_reportFatalError; + callbacks[166] = (delegate* unmanaged)&_getPgoInstrumentationResults; + callbacks[167] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema; + callbacks[168] = (delegate* unmanaged)&_recordCallSite; + callbacks[169] = (delegate* unmanaged)&_recordRelocation; + callbacks[170] = (delegate* unmanaged)&_getRelocTypeHint; + callbacks[171] = (delegate* unmanaged)&_getExpectedTargetArchitecture; + callbacks[172] = (delegate* unmanaged)&_getJitFlags; return (IntPtr)callbacks; } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index bb822b46555068..3c1eb891ac4f81 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -431,7 +431,18 @@ private void PublishCode() _methodCodeNode.InitializeDebugLocInfos(_debugLocInfos); _methodCodeNode.InitializeDebugVarInfos(_debugVarInfos); #if READYTORUN - _methodCodeNode.InitializeInliningInfo(_inlinedMethods.ToArray(), _compilation.NodeFactory); + MethodDesc[] inlineeArray; + if (_inlinedMethods != null) + { + inlineeArray = new MethodDesc[_inlinedMethods.Count]; + _inlinedMethods.CopyTo(inlineeArray); + Array.Sort(inlineeArray, TypeSystemComparer.Instance.Compare); + } + else + { + inlineeArray = Array.Empty(); + } + _methodCodeNode.InitializeInliningInfo(inlineeArray, _compilation.NodeFactory); // Detect cases where the instruction set support used is a superset of the baseline instruction set specification var baselineSupport = _compilation.InstructionSetSupport; @@ -460,7 +471,20 @@ private void PublishCode() InstructionSetSupport actualSupport = new InstructionSetSupport(_actualInstructionSetSupported, _actualInstructionSetUnsupported, architecture); var node = _compilation.SymbolNodeFactory.PerMethodInstructionSetSupportFixup(actualSupport); - _methodCodeNode.Fixups.Add(node); + AddPrecodeFixup(node); + } + + Debug.Assert(_stashedPrecodeFixups.Count == 0); + if (_precodeFixups != null) + { + HashSet computedNodes = new HashSet(); + foreach (var fixup in _precodeFixups) + { + if (computedNodes.Add(fixup)) + { + _methodCodeNode.Fixups.Add(fixup); + } + } } #else var methodIL = (MethodIL)HandleToObject((IntPtr)_methodScope); @@ -566,9 +590,12 @@ private void CompileMethodCleanup() _lastException = null; #if READYTORUN - _inlinedMethods = new ArrayBuilder(); + _inlinedMethods = null; _actualInstructionSetSupported = default(InstructionSetFlags); _actualInstructionSetUnsupported = default(InstructionSetFlags); + _precodeFixups = null; + _stashedPrecodeFixups.Clear(); + _stashedInlinedMethods.Clear(); #endif _instantiationToJitVisibleInstantiation = null; @@ -1381,7 +1408,7 @@ private bool resolveVirtualMethod(CORINFO_DEVIRTUALIZATION_INFO* info) if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout) { ISymbolNode virtualResolutionNode = _compilation.SymbolNodeFactory.CheckVirtualFunctionOverride(methodWithTokenDecl, objType, methodWithTokenImpl); - _methodCodeNode.Fixups.Add(virtualResolutionNode); + AddPrecodeFixup(virtualResolutionNode); } #endif info->detail = CORINFO_DEVIRTUALIZATION_DETAIL.CORINFO_DEVIRTUALIZATION_SUCCESS; @@ -2084,7 +2111,7 @@ private uint getClassSize(CORINFO_CLASS_STRUCT_* cls) if (NeedsTypeLayoutCheck(type)) { ISymbolNode node = _compilation.SymbolNodeFactory.CheckTypeLayout(type); - _methodCodeNode.Fixups.Add(node); + AddPrecodeFixup(node); } #endif return (uint)classSize.AsInt; diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs index 9a173957fa007a..1f65d5e5f83549 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs @@ -478,7 +478,11 @@ public enum CorInfoClassId } public enum CorInfoInline { - INLINE_PASS = 0, // Inlining OK + INLINE_PASS = 0, // Inlining OK + INLINE_PREJIT_SUCCESS = 1, // Inline check for prejit checking usage succeeded + INLINE_CHECK_CAN_INLINE_SUCCESS = 2, // JIT detected it is permitted to try to actually inline + INLINE_CHECK_CAN_INLINE_VMFAIL = 3, // VM specified that inline must fail via the CanInline api + // failures are negative INLINE_FAIL = -1, // Inlining not OK for this case only diff --git a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 45fcdef14faaf8..f1393ad2095a72 100644 --- a/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -159,6 +159,7 @@ FUNCTIONS void getMethodSig( CORINFO_METHOD_HANDLE ftn, CORINFO_SIG_INFO *sig, CORINFO_CLASS_HANDLE memberParent ); bool getMethodInfo( CORINFO_METHOD_HANDLE ftn, CORINFO_METHOD_INFO* info ); CorInfoInline canInline( CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE calleeHnd); + void beginInlining(CORINFO_METHOD_HANDLE inlinerHnd, CORINFO_METHOD_HANDLE inlineeHnd); void reportInliningDecision(CORINFO_METHOD_HANDLE inlinerHnd, CORINFO_METHOD_HANDLE inlineeHnd, CorInfoInline inlineResult, const char * reason); bool canTailCall( CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE declaredCalleeHnd, CORINFO_METHOD_HANDLE exactCalleeHnd, bool fIsTailPrefix ); void reportTailCallDecision(CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE calleeHnd, bool fIsTailPrefix, CorInfoTailCall tailCallResult, const char * reason); diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs index 2e7452815e652d..6e62f81bdbf34a 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -361,8 +361,9 @@ unsafe partial class CorInfoImpl private MethodWithGCInfo _methodCodeNode; private OffsetMapping[] _debugLocInfos; private NativeVarInfo[] _debugVarInfos; - private ArrayBuilder _inlinedMethods; + private HashSet _inlinedMethods; private UnboxingMethodDescFactory _unboxingThunkFactory = new UnboxingMethodDescFactory(); + private List _precodeFixups; public CorInfoImpl(ReadyToRunCodegenCompilation compilation) : this() @@ -370,6 +371,12 @@ public CorInfoImpl(ReadyToRunCodegenCompilation compilation) _compilation = compilation; } + private void AddPrecodeFixup(ISymbolNode node) + { + _precodeFixups = _precodeFixups ?? new List(); + _precodeFixups.Add(node); + } + private static mdToken FindGenericMethodArgTypeSpec(EcmaModule module) { // Find the TypeSpec for "!!0" @@ -1327,7 +1334,7 @@ private void getFieldInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_MET if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout && (fieldOffset <= FieldFixupSignature.MaxCheckableOffset)) { // ENCODE_CHECK_FIELD_OFFSET - _methodCodeNode.Fixups.Add(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); + AddPrecodeFixup(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); } } else @@ -1381,7 +1388,7 @@ private void getFieldInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_MET if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout && (fieldOffset <= FieldFixupSignature.MaxCheckableOffset)) { // ENCODE_CHECK_FIELD_OFFSET - _methodCodeNode.Fixups.Add(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); + AddPrecodeFixup(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); } pResult->fieldLookup = CreateConstLookupToSymbol( @@ -1843,7 +1850,7 @@ private void classMustBeLoadedBeforeCodeIsRun(TypeDesc type) if (!type.IsPrimitive) { ISymbolNode node = _compilation.SymbolNodeFactory.CreateReadyToRunHelper(ReadyToRunHelperId.TypeHandle, type); - _methodCodeNode.Fixups.Add(node); + AddPrecodeFixup(node); } } @@ -2365,7 +2372,7 @@ private void EncodeFieldBaseOffset(FieldDesc field, CORINFO_FIELD_INFO* pResult, if (pResult->offset > FieldFixupSignature.MaxCheckableOffset) throw new RequiresRuntimeJitException(callerMethod.ToString() + " -> " + field.ToString()); - _methodCodeNode.Fixups.Add(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); + AddPrecodeFixup(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); // No-op other than generating the check field offset fixup } else @@ -2383,7 +2390,7 @@ private void EncodeFieldBaseOffset(FieldDesc field, CORINFO_FIELD_INFO* pResult, if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout && !callerMethod.IsNonVersionable() && (pResult->offset <= FieldFixupSignature.MaxCheckableOffset)) { // ENCODE_CHECK_FIELD_OFFSET - _methodCodeNode.Fixups.Add(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); + AddPrecodeFixup(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); } // ENCODE_NONE } @@ -2392,7 +2399,7 @@ private void EncodeFieldBaseOffset(FieldDesc field, CORINFO_FIELD_INFO* pResult, if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout && !callerMethod.IsNonVersionable() && (pResult->offset <= FieldFixupSignature.MaxCheckableOffset)) { // ENCODE_CHECK_FIELD_OFFSET - _methodCodeNode.Fixups.Add(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); + AddPrecodeFixup(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); } // ENCODE_NONE } @@ -2403,7 +2410,7 @@ private void EncodeFieldBaseOffset(FieldDesc field, CORINFO_FIELD_INFO* pResult, if (_compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout && !callerMethod.IsNonVersionable() && (pResult->offset <= FieldFixupSignature.MaxCheckableOffset)) { // ENCODE_CHECK_FIELD_OFFSET - _methodCodeNode.Fixups.Add(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); + AddPrecodeFixup(_compilation.SymbolNodeFactory.CheckFieldOffset(field)); } // ENCODE_FIELD_BASE_OFFSET @@ -2636,14 +2643,56 @@ private void setEHinfo(uint EHnumber, ref CORINFO_EH_CLAUSE clause) _ehClauses[EHnumber] = clause; } + private readonly Stack> _stashedPrecodeFixups = new Stack>(); + private readonly Stack> _stashedInlinedMethods = new Stack>(); + + private void beginInlining(CORINFO_METHOD_STRUCT_* inlinerHnd, CORINFO_METHOD_STRUCT_* inlineeHnd) + { + _stashedPrecodeFixups.Push(_precodeFixups); + _precodeFixups = null; + _stashedInlinedMethods.Push(_inlinedMethods); + _inlinedMethods = null; + } + private void reportInliningDecision(CORINFO_METHOD_STRUCT_* inlinerHnd, CORINFO_METHOD_STRUCT_* inlineeHnd, CorInfoInline inlineResult, byte* reason) { if (inlineResult == CorInfoInline.INLINE_PASS) { // We deliberately ignore inlinerHnd because we have no interest to track intermediate links now. MethodDesc inlinee = HandleToObject(inlineeHnd); + + // If during inlining we found Precode fixups, then only if the inline was successful, add them to the set of + // fixups that will be used for the entire method + List previouslyStashedFixups = _stashedPrecodeFixups.Pop(); + + if (_precodeFixups != null) + { + previouslyStashedFixups = previouslyStashedFixups ?? new List(); + previouslyStashedFixups.AddRange(_precodeFixups); + } + _precodeFixups = previouslyStashedFixups; + + // If during inlining we found new inlinees, then if the inline was successful, add them to the set of fixups + // for the entire method. + HashSet previouslyStashedInlinees = _stashedInlinedMethods.Pop(); + if (_inlinedMethods != null) + { + previouslyStashedInlinees = previouslyStashedInlinees ?? new HashSet(); + foreach (var inlineeInHashSet in _inlinedMethods) + previouslyStashedInlinees.Add(inlineeInHashSet); + } + _inlinedMethods = previouslyStashedInlinees; + + // Then add the fact we inlined this method. + _inlinedMethods = _inlinedMethods ?? new HashSet(); _inlinedMethods.Add(inlinee); } + else + { + // If we didn't succeed on the inline, just pop back to the state before inlining + _precodeFixups = _stashedPrecodeFixups.Pop(); + _inlinedMethods = _stashedInlinedMethods.Pop(); + } } private void updateEntryPointForTailCall(ref CORINFO_CONST_LOOKUP entryPoint) diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs index f6eeb8343c0b19..d7b153f0e10f27 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -1979,6 +1979,10 @@ private void setEHinfo(uint EHnumber, ref CORINFO_EH_CLAUSE clause) _ehClauses[EHnumber] = clause; } + private void beginInlining(CORINFO_METHOD_STRUCT_* inlinerHnd, CORINFO_METHOD_STRUCT_* inlineeHnd) + { + } + private void reportInliningDecision(CORINFO_METHOD_STRUCT_* inlinerHnd, CORINFO_METHOD_STRUCT_* inlineeHnd, CorInfoInline inlineResult, byte* reason) { } diff --git a/src/coreclr/tools/aot/jitinterface/jitinterface.h b/src/coreclr/tools/aot/jitinterface/jitinterface.h index d182b8fee80eee..bad094900a0909 100644 --- a/src/coreclr/tools/aot/jitinterface/jitinterface.h +++ b/src/coreclr/tools/aot/jitinterface/jitinterface.h @@ -17,6 +17,7 @@ struct JitInterfaceCallbacks void (* getMethodSig)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftn, CORINFO_SIG_INFO* sig, CORINFO_CLASS_HANDLE memberParent); bool (* getMethodInfo)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftn, CORINFO_METHOD_INFO* info); CorInfoInline (* canInline)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE calleeHnd); + void (* beginInlining)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE inlinerHnd, CORINFO_METHOD_HANDLE inlineeHnd); void (* reportInliningDecision)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE inlinerHnd, CORINFO_METHOD_HANDLE inlineeHnd, CorInfoInline inlineResult, const char* reason); bool (* canTailCall)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE declaredCalleeHnd, CORINFO_METHOD_HANDLE exactCalleeHnd, bool fIsTailPrefix); void (* reportTailCallDecision)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE callerHnd, CORINFO_METHOD_HANDLE calleeHnd, bool fIsTailPrefix, CorInfoTailCall tailCallResult, const char* reason); @@ -255,6 +256,15 @@ class JitInterfaceWrapper : public ICorJitInfo return temp; } + virtual void beginInlining( + CORINFO_METHOD_HANDLE inlinerHnd, + CORINFO_METHOD_HANDLE inlineeHnd) +{ + CorInfoExceptionClass* pException = nullptr; + _callbacks->beginInlining(_thisHandle, &pException, inlinerHnd, inlineeHnd); + if (pException != nullptr) throw pException; +} + virtual void reportInliningDecision( CORINFO_METHOD_HANDLE inlinerHnd, CORINFO_METHOD_HANDLE inlineeHnd, diff --git a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index 4ce8db665615b0..b939f4cb844fb2 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -115,6 +115,13 @@ CorInfoInline interceptor_ICJI::canInline(CORINFO_METHOD_HANDLE callerHnd, /* return temp; } +void interceptor_ICJI::beginInlining(CORINFO_METHOD_HANDLE inlinerHnd, + CORINFO_METHOD_HANDLE inlineeHnd) +{ + mc->cr->AddCall("beginInlining"); + original_ICorJitInfo->beginInlining(inlinerHnd, inlineeHnd); +} + // Reports whether or not a method can be inlined, and why. canInline is responsible for reporting all // inlining results when it returns INLINE_FAIL and INLINE_NEVER. All other results are reported by the // JIT. diff --git a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo.cpp index 79e3536ba524c8..af768ca0933b17 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo.cpp @@ -59,6 +59,14 @@ CorInfoInline interceptor_ICJI::canInline( return original_ICorJitInfo->canInline(callerHnd, calleeHnd); } +void interceptor_ICJI::beginInlining( + CORINFO_METHOD_HANDLE inlinerHnd, + CORINFO_METHOD_HANDLE inlineeHnd) +{ + mcs->AddCall("beginInlining"); + original_ICorJitInfo->beginInlining(inlinerHnd, inlineeHnd); +} + void interceptor_ICJI::reportInliningDecision( CORINFO_METHOD_HANDLE inlinerHnd, CORINFO_METHOD_HANDLE inlineeHnd, diff --git a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo.cpp index 7d4feacc10d6e9..957cadd8c57c3c 100644 --- a/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo.cpp @@ -53,6 +53,13 @@ CorInfoInline interceptor_ICJI::canInline( return original_ICorJitInfo->canInline(callerHnd, calleeHnd); } +void interceptor_ICJI::beginInlining( + CORINFO_METHOD_HANDLE inlinerHnd, + CORINFO_METHOD_HANDLE inlineeHnd) +{ + original_ICorJitInfo->beginInlining(inlinerHnd, inlineeHnd); +} + void interceptor_ICJI::reportInliningDecision( CORINFO_METHOD_HANDLE inlinerHnd, CORINFO_METHOD_HANDLE inlineeHnd, diff --git a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index 7f2203edd7ac18..bb6592bb8b39b1 100644 --- a/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -100,6 +100,11 @@ CorInfoInline MyICJI::canInline(CORINFO_METHOD_HANDLE callerHnd, /* IN */ return result; } +void MyICJI::beginInlining(CORINFO_METHOD_HANDLE inlinerHnd, + CORINFO_METHOD_HANDLE inlineeHnd) +{ + // do nothing +} // Reports whether or not a method can be inlined, and why. canInline is responsible for reporting all // inlining results when it returns INLINE_FAIL and INLINE_NEVER. All other results are reported by the // JIT. diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 7026aae2953ce1..bc06ec12eb4cfa 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -7944,6 +7944,12 @@ exit: ; return result; } +void CEEInfo::beginInlining(CORINFO_METHOD_HANDLE inlinerHnd, + CORINFO_METHOD_HANDLE inlineeHnd) +{ + // do nothing +} + void CEEInfo::reportInliningDecision (CORINFO_METHOD_HANDLE inlinerHnd, CORINFO_METHOD_HANDLE inlineeHnd, CorInfoInline inlineResult, @@ -7993,7 +7999,7 @@ void CEEInfo::reportInliningDecision (CORINFO_METHOD_HANDLE inlinerHnd, currentMethodName.GetUnicode(), inlineeMethodName.GetUnicode(), inlinerMethodName.GetUnicode(), reason)); } - else + else if(inlineResult == INLINE_PASS) { LOG((LF_JIT, LL_INFO100000, "While compiling '%S', inline of '%S' into '%S' succeeded.\n", currentMethodName.GetUnicode(), inlineeMethodName.GetUnicode(), @@ -8006,7 +8012,8 @@ void CEEInfo::reportInliningDecision (CORINFO_METHOD_HANDLE inlinerHnd, //I'm gonna duplicate this code because the format is slightly different. And LoggingOn is debug only. if (ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context, TRACE_LEVEL_VERBOSE, - CLR_JITTRACING_KEYWORD)) + CLR_JITTRACING_KEYWORD) && + (inlineResult <= INLINE_PASS)) // Only report pass, and failure inliner information. The various informative reports such as INLINE_CHECK_CAN_INLINE_SUCCESS are not to be reported via ETW { SString methodBeingCompiledNames[3]; SString inlinerNames[3]; @@ -8046,7 +8053,7 @@ void CEEInfo::reportInliningDecision (CORINFO_METHOD_HANDLE inlinerHnd, strReason.GetUnicode(), GetClrInstanceId()); } - else + else if(inlineResult == INLINE_PASS) { FireEtwMethodJitInliningSucceeded(methodBeingCompiledNames[0].GetUnicode(), methodBeingCompiledNames[1].GetUnicode(), From 117d31a6cf03b89d77b8608b6dd353a834f68566 Mon Sep 17 00:00:00 2001 From: Brennan Date: Fri, 10 Jun 2022 17:05:35 -0700 Subject: [PATCH 052/337] Cleanup idle rate limiters (#69677) --- .../RateLimiting/PartitionedRateLimiter.cs | 126 ++++++-- .../tests/PartitionedRateLimiterTests.cs | 284 +++++++++++++++++- 2 files changed, 377 insertions(+), 33 deletions(-) diff --git a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/PartitionedRateLimiter.cs b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/PartitionedRateLimiter.cs index 9fb634ddaddc3f..71db0d425e57bf 100644 --- a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/PartitionedRateLimiter.cs +++ b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/PartitionedRateLimiter.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using System.Runtime.CompilerServices; using System.Threading.Tasks; @@ -33,6 +34,7 @@ public static PartitionedRateLimiter Create internal sealed class DefaultPartitionedRateLimiter : PartitionedRateLimiter where TKey : notnull { private readonly Func> _partitioner; + private static TimeSpan _idleTimeLimit = TimeSpan.FromSeconds(10); // TODO: Look at ConcurrentDictionary to try and avoid a global lock private Dictionary> _limiters; @@ -42,8 +44,9 @@ internal sealed class DefaultPartitionedRateLimiter : Partition // Used by the Timer to call TryRelenish on ReplenishingRateLimiters // We use a separate list to avoid running TryReplenish (which might be user code) inside our lock // And we cache the list to amortize the allocation cost to as close to 0 as we can get - private List> _cachedLimiters = new(); + private List>> _cachedLimiters = new(); private bool _cacheInvalid; + private List _limitersToDispose = new(); private TimerAwaitable _timer; private Task _timerTask; @@ -68,7 +71,7 @@ private async Task RunTimer() { try { - Replenish(this); + await Heartbeat().ConfigureAwait(false); } // TODO: Can we log to EventSource or somewhere? Maybe dispatch throwing the exception so it is at least an unhandled exception? catch { } @@ -128,14 +131,29 @@ protected override void Dispose(bool disposing) return; } + List? exceptions = null; + // Safe to access _limiters outside the lock // The timer is no longer running and _disposed is set so anyone trying to access fields will be checking that first foreach (KeyValuePair> limiter in _limiters) { - limiter.Value.Value.Dispose(); + try + { + limiter.Value.Value.Dispose(); + } + catch (Exception ex) + { + exceptions ??= new List(); + exceptions.Add(ex); + } } _limiters.Clear(); _disposeComplete.TrySetResult(null); + + if (exceptions is not null) + { + throw new AggregateException(exceptions); + } } protected override async ValueTask DisposeAsyncCore() @@ -151,12 +169,26 @@ protected override async ValueTask DisposeAsyncCore() return; } + List? exceptions = null; foreach (KeyValuePair> limiter in _limiters) { - await limiter.Value.Value.DisposeAsync().ConfigureAwait(false); + try + { + await limiter.Value.Value.DisposeAsync().ConfigureAwait(false); + } + catch (Exception ex) + { + exceptions ??= new List(); + exceptions.Add(ex); + } } _limiters.Clear(); _disposeComplete.TrySetResult(null); + + if (exceptions is not null) + { + throw new AggregateException(exceptions); + } } // This handles the common state changes that Dispose and DisposeAsync need to do, the individual limiters still need to be Disposed after this call @@ -182,48 +214,82 @@ private void ThrowIfDisposed() } } - private static void Replenish(DefaultPartitionedRateLimiter limiter) + private async Task Heartbeat() { - lock (limiter.Lock) + lock (Lock) { - if (limiter._disposed) + if (_disposed) { return; } // If the cache has been invalidated we need to recreate it - if (limiter._cacheInvalid) + if (_cacheInvalid) + { + _cachedLimiters.Clear(); + _cachedLimiters.AddRange(_limiters); + } + } + + List? aggregateExceptions = null; + + // cachedLimiters is safe to use outside the lock because it is only updated by the Timer + foreach (KeyValuePair> rateLimiter in _cachedLimiters) + { + if (!rateLimiter.Value.IsValueCreated) { - limiter._cachedLimiters.Clear(); - bool cacheStillInvalid = false; - foreach (KeyValuePair> kvp in limiter._limiters) + continue; + } + if (rateLimiter.Value.Value.IdleDuration is TimeSpan idleDuration && idleDuration > _idleTimeLimit) + { + lock (Lock) { - if (kvp.Value.IsValueCreated) - { - if (kvp.Value.Value is ReplenishingRateLimiter) - { - limiter._cachedLimiters.Add(kvp.Value); - } - } - else + // Check time again under lock to make sure no one calls Acquire or WaitAsync after checking the time and removing the limiter + idleDuration = rateLimiter.Value.Value.IdleDuration ?? TimeSpan.Zero; + if (idleDuration > _idleTimeLimit) { - // In rare cases the RateLimiter will be added to the storage but not be initialized yet - // keep cache invalid if there was a non-initialized RateLimiter - // the next time we run the timer the cache will be updated - // with the initialized RateLimiter - cacheStillInvalid = true; + // Remove limiter from the lookup table and mark cache as invalid + // If a request for this partition comes in it will have to create a new limiter now + // And the next time the timer runs the cache needs to be updated to no longer have a reference to this limiter + _cacheInvalid = true; + _limiters.Remove(rateLimiter.Key); + + // We don't want to dispose inside the lock so we need to defer it + _limitersToDispose.Add(rateLimiter.Value.Value); } } - limiter._cacheInvalid = cacheStillInvalid; + } + else if (rateLimiter.Value.Value is ReplenishingRateLimiter replenishingRateLimiter) + { + try + { + replenishingRateLimiter.TryReplenish(); + } + catch (Exception ex) + { + aggregateExceptions ??= new List(); + aggregateExceptions.Add(ex); + } } } - // cachedLimiters is safe to use outside the lock because it is only updated by the Timer - // and the Timer avoids re-entrancy issues via the _executingTimer field - foreach (Lazy rateLimiter in limiter._cachedLimiters) + foreach (RateLimiter limiter in _limitersToDispose) + { + try + { + await limiter.DisposeAsync().ConfigureAwait(false); + } + catch (Exception ex) + { + aggregateExceptions ??= new List(); + aggregateExceptions.Add(ex); + } + } + _limitersToDispose.Clear(); + + if (aggregateExceptions is not null) { - Debug.Assert(rateLimiter.IsValueCreated && rateLimiter.Value is ReplenishingRateLimiter); - ((ReplenishingRateLimiter)rateLimiter.Value).TryReplenish(); + throw new AggregateException(aggregateExceptions); } } } diff --git a/src/libraries/System.Threading.RateLimiting/tests/PartitionedRateLimiterTests.cs b/src/libraries/System.Threading.RateLimiting/tests/PartitionedRateLimiterTests.cs index 47ccdc5c376c53..2818876d203d5a 100644 --- a/src/libraries/System.Threading.RateLimiting/tests/PartitionedRateLimiterTests.cs +++ b/src/libraries/System.Threading.RateLimiting/tests/PartitionedRateLimiterTests.cs @@ -32,8 +32,6 @@ await Assert.ThrowsAsync( async () => await limiter.WaitAsync(string.Empty, 1, new CancellationToken(true))); } - // Create - [Fact] public void Create_AcquireCallsUnderlyingPartitionsLimiter() { @@ -276,6 +274,29 @@ public void Create_DisposeDisposesAllLimiters() Assert.Equal(1, limiterFactory.Limiters[1].Limiter.DisposeCallCount); } + [Fact] + public void Create_DisposeWithThrowingDisposes_DisposesAllLimiters() + { + var limiter1 = new CustomizableLimiter(); + limiter1.DisposeImpl = _ => throw new Exception(); + var limiter2 = new CustomizableLimiter(); + limiter2.DisposeImpl = _ => throw new Exception(); + using var limiter = PartitionedRateLimiter.Create(resource => + { + if (resource == "1") + { + return RateLimitPartition.Create(1, _ => limiter1); + } + return RateLimitPartition.Create(2, _ => limiter2); + }); + + limiter.Acquire("1"); + limiter.Acquire("2"); + + var ex = Assert.Throws(() => limiter.Dispose()); + Assert.Equal(2, ex.InnerExceptions.Count); + } + [Fact] public void Create_DisposeThrowsForFutureMethodCalls() { @@ -320,6 +341,29 @@ public async Task Create_DisposeAsyncDisposesAllLimiters() Assert.Equal(1, limiterFactory.Limiters[1].Limiter.DisposeAsyncCallCount); } + [Fact] + public async Task Create_DisposeAsyncWithThrowingDisposes_DisposesAllLimiters() + { + var limiter1 = new CustomizableLimiter(); + limiter1.DisposeAsyncCoreImpl = () => throw new Exception(); + var limiter2 = new CustomizableLimiter(); + limiter2.DisposeAsyncCoreImpl = () => throw new Exception(); + using var limiter = PartitionedRateLimiter.Create(resource => + { + if (resource == "1") + { + return RateLimitPartition.Create(1, _ => limiter1); + } + return RateLimitPartition.Create(2, _ => limiter2); + }); + + limiter.Acquire("1"); + limiter.Acquire("2"); + + var ex = await Assert.ThrowsAsync(() => limiter.DisposeAsync().AsTask()); + Assert.Equal(2, ex.InnerExceptions.Count); + } + [Fact] public async Task Create_WithTokenBucketReplenishesAutomatically() { @@ -403,6 +447,155 @@ public async Task Create_CancellationTokenPassedToUnderlyingLimiter() await Assert.ThrowsAsync(async () => await waitTask); } + [Fact] + public async Task IdleLimiterIsCleanedUp() + { + CustomizableLimiter innerLimiter = null; + var factoryCallCount = 0; + using var limiter = PartitionedRateLimiter.Create(resource => + { + return RateLimitPartition.Create(1, _ => + { + factoryCallCount++; + innerLimiter = new CustomizableLimiter(); + return innerLimiter; + }); + }); + + var timerLoopMethod = StopTimerAndGetTimerFunc(limiter); + + var lease = limiter.Acquire(""); + Assert.True(lease.IsAcquired); + + Assert.Equal(1, factoryCallCount); + + var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + innerLimiter.DisposeAsyncCoreImpl = () => + { + tcs.SetResult(null); + return default; + }; + innerLimiter.IdleDurationImpl = () => TimeSpan.FromMinutes(1); + + await timerLoopMethod(); + + // Limiter is disposed when timer runs and sees that IdleDuration is greater than idle limit + await tcs.Task; + innerLimiter.DisposeAsyncCoreImpl = () => default; + + // Acquire will call limiter factory again as the limiter was disposed and removed + lease = limiter.Acquire(""); + Assert.True(lease.IsAcquired); + Assert.Equal(2, factoryCallCount); + } + + [Fact] + public async Task AllIdleLimitersCleanedUp_DisposeThrows() + { + CustomizableLimiter innerLimiter1 = null; + CustomizableLimiter innerLimiter2 = null; + using var limiter = PartitionedRateLimiter.Create(resource => + { + if (resource == "1") + { + return RateLimitPartition.Create(1, _ => + { + innerLimiter1 = new CustomizableLimiter(); + return innerLimiter1; + }); + } + else + { + return RateLimitPartition.Create(2, _ => + { + innerLimiter2 = new CustomizableLimiter(); + return innerLimiter2; + }); + } + }); + + var timerLoopMethod = StopTimerAndGetTimerFunc(limiter); + + var lease = limiter.Acquire("1"); + Assert.True(lease.IsAcquired); + Assert.NotNull(innerLimiter1); + limiter.Acquire("2"); + Assert.NotNull(innerLimiter2); + + var dispose1Called = false; + var dispose2Called = false; + innerLimiter1.DisposeAsyncCoreImpl = () => + { + dispose1Called = true; + throw new Exception(); + }; + innerLimiter1.IdleDurationImpl = () => TimeSpan.FromMinutes(1); + innerLimiter2.DisposeAsyncCoreImpl = () => + { + dispose2Called = true; + throw new Exception(); + }; + innerLimiter2.IdleDurationImpl = () => TimeSpan.FromMinutes(1); + + // Run Timer + var ex = await Assert.ThrowsAsync(() => timerLoopMethod()); + + Assert.True(dispose1Called); + Assert.True(dispose2Called); + + Assert.Equal(2, ex.InnerExceptions.Count); + } + + [Fact] + public async Task ThrowingTryReplenishDoesNotPreventIdleLimiterBeingCleanedUp() + { + CustomizableReplenishingLimiter replenishLimiter = new CustomizableReplenishingLimiter(); + CustomizableLimiter idleLimiter = null; + var factoryCallCount = 0; + using var limiter = PartitionedRateLimiter.Create(resource => + { + if (resource == "1") + { + return RateLimitPartition.Create(1, _ => + { + factoryCallCount++; + idleLimiter = new CustomizableLimiter(); + return idleLimiter; + }); + } + return RateLimitPartition.Create(2, _ => + { + return replenishLimiter; + }); + }); + + var timerLoopMethod = StopTimerAndGetTimerFunc(limiter); + + // Add the replenishing limiter to the internal storage + limiter.Acquire("2"); + var lease = limiter.Acquire("1"); + Assert.True(lease.IsAcquired); + Assert.Equal(1, factoryCallCount); + + // Start throwing from TryReplenish, this will happen the next time the Timer runs + replenishLimiter.TryReplenishImpl = () => throw new Exception(); + + var disposeTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + // This DisposeAsync will be called in the same Timer iteration as the throwing TryReplenish, so we block below on the disposeTcs to make sure DisposeAsync is called even with a throwing TryReplenish + idleLimiter.DisposeAsyncCoreImpl = () => + { + disposeTcs.SetResult(null); + return default; + }; + idleLimiter.IdleDurationImpl = () => TimeSpan.FromMinutes(1); + + var ex = await Assert.ThrowsAsync(() => timerLoopMethod()); + Assert.Single(ex.InnerExceptions); + + // Wait for Timer to run again which will see the throwing TryReplenish and an idle limiter it needs to clean-up + await disposeTcs.Task; + } + internal sealed class NotImplementedPartitionedRateLimiter : PartitionedRateLimiter { public override int GetAvailablePermits(T resourceID) => throw new NotImplementedException(); @@ -424,7 +617,7 @@ internal sealed class TrackingRateLimiter : RateLimiter public int DisposeCallCount => _disposeCallCount; public int DisposeAsyncCallCount => _disposeAsyncCallCount; - public override TimeSpan? IdleDuration => throw new NotImplementedException(); + public override TimeSpan? IdleDuration => null; public override int GetAvailablePermits() { @@ -500,5 +693,90 @@ public int GetHashCode([DisallowNull] int obj) return obj.GetHashCode(); } } + + internal sealed class CustomizableLimiter : RateLimiter + { + public Func IdleDurationImpl { get; set; } = () => null; + public override TimeSpan? IdleDuration => IdleDurationImpl(); + + public Func GetAvailablePermitsImpl { get; set; } = () => throw new NotImplementedException(); + public override int GetAvailablePermits() => GetAvailablePermitsImpl(); + + public Func AcquireCoreImpl { get; set; } = _ => new Lease(); + protected override RateLimitLease AcquireCore(int permitCount) => AcquireCoreImpl(permitCount); + + public Func> WaitAsyncCoreImpl { get; set; } = (_, _) => new ValueTask(new Lease()); + protected override ValueTask WaitAsyncCore(int permitCount, CancellationToken cancellationToken) => WaitAsyncCoreImpl(permitCount, cancellationToken); + + public Action DisposeImpl { get; set; } = _ => { }; + protected override void Dispose(bool disposing) => DisposeImpl(disposing); + + public Func DisposeAsyncCoreImpl { get; set; } = () => default; + protected override ValueTask DisposeAsyncCore() => DisposeAsyncCoreImpl(); + + private sealed class Lease : RateLimitLease + { + public override bool IsAcquired => true; + + public override IEnumerable MetadataNames => throw new NotImplementedException(); + + public override bool TryGetMetadata(string metadataName, out object? metadata) => throw new NotImplementedException(); + } + } + + internal sealed class CustomizableReplenishingLimiter : ReplenishingRateLimiter + { + public Func IdleDurationImpl { get; set; } = () => null; + public override TimeSpan? IdleDuration => IdleDurationImpl(); + + public Func GetAvailablePermitsImpl { get; set; } = () => throw new NotImplementedException(); + public override int GetAvailablePermits() => GetAvailablePermitsImpl(); + + public Func AcquireCoreImpl { get; set; } = _ => new Lease(); + protected override RateLimitLease AcquireCore(int permitCount) => AcquireCoreImpl(permitCount); + + public Func> WaitAsyncCoreImpl { get; set; } = (_, _) => new ValueTask(new Lease()); + protected override ValueTask WaitAsyncCore(int permitCount, CancellationToken cancellationToken) => WaitAsyncCoreImpl(permitCount, cancellationToken); + + public Func DisposeAsyncCoreImpl { get; set; } = () => default; + protected override ValueTask DisposeAsyncCore() => DisposeAsyncCoreImpl(); + + public override bool IsAutoReplenishing => false; + + public override TimeSpan ReplenishmentPeriod => throw new NotImplementedException(); + + public Func TryReplenishImpl { get; set; } = () => true; + public override bool TryReplenish() => TryReplenishImpl(); + + private sealed class Lease : RateLimitLease + { + public override bool IsAcquired => true; + + public override IEnumerable MetadataNames => throw new NotImplementedException(); + + public override bool TryGetMetadata(string metadataName, out object? metadata) => throw new NotImplementedException(); + } + } + + Func StopTimerAndGetTimerFunc(PartitionedRateLimiter limiter) + { + var innerTimer = limiter.GetType().GetField("_timer", Reflection.BindingFlags.NonPublic | Reflection.BindingFlags.Instance); + Assert.NotNull(innerTimer); + var timerStopMethod = innerTimer.FieldType.GetMethod("Stop"); + Assert.NotNull(timerStopMethod); + // Stop the current Timer so it doesn't fire unexpectedly + timerStopMethod.Invoke(innerTimer.GetValue(limiter), Array.Empty()); + + // Create a new Timer object so that disposing the PartitionedRateLimiter doesn't fail with an ODE, but this new Timer wont actually do anything + var timerCtor = innerTimer.FieldType.GetConstructor(new Type[] { typeof(TimeSpan), typeof(TimeSpan) }); + Assert.NotNull(timerCtor); + var newTimer = timerCtor.Invoke(new object[] { TimeSpan.FromMinutes(10), TimeSpan.FromMinutes(10) }); + Assert.NotNull(newTimer); + innerTimer.SetValue(limiter, newTimer); + + var timerLoopMethod = limiter.GetType().GetMethod("Heartbeat", Reflection.BindingFlags.NonPublic | Reflection.BindingFlags.Instance); + Assert.NotNull(timerLoopMethod); + return () => (Task)timerLoopMethod.Invoke(limiter, Array.Empty()); + } } } From 55ed5e80a36fb79a7af5f5e22967be935c1710a5 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Fri, 10 Jun 2022 19:09:20 -0700 Subject: [PATCH 053/337] Windows/Arm64: Set flag for Atomics/Dp feature (#70600) --- src/coreclr/vm/codeman.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/coreclr/vm/codeman.cpp b/src/coreclr/vm/codeman.cpp index c3341522d4972c..1b7caaef542018 100644 --- a/src/coreclr/vm/codeman.cpp +++ b/src/coreclr/vm/codeman.cpp @@ -1552,6 +1552,28 @@ void EEJitManager::SetCpuInfo() { CPUCompileFlags.Set(InstructionSet_Crc32); } + +// Older version of SDK would return false for these intrinsics +// but make sure we pass the right values to the APIs +#ifndef PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE +#define PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE 34 +#endif +#ifndef PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE +# define PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE 43 +#endif + + // PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE (34) + if (IsProcessorFeaturePresent(PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE)) + { + CPUCompileFlags.Set(InstructionSet_Atomics); + } + + // PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE (43) + if (IsProcessorFeaturePresent(PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE)) + { + CPUCompileFlags.Set(InstructionSet_Dp); + } + #endif // HOST_64BIT if (GetDataCacheZeroIDReg() == 4) { From 35717a3ea60a9a0d8c7012df884a563305f1f019 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Fri, 10 Jun 2022 23:15:10 -0400 Subject: [PATCH 054/337] Use u8 in a few more places (#70568) --- .../System/Net/Managed/HttpResponseStream.Managed.cs | 2 +- .../System/Net/WebSockets/WebSocketHandle.Managed.cs | 9 +-------- .../System.Private.CoreLib/src/System/IO/Path.cs | 6 +----- .../System/Reflection/Metadata/MetadataReader.WinMD.cs | 10 +--------- 4 files changed, 4 insertions(+), 23 deletions(-) diff --git a/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpResponseStream.Managed.cs b/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpResponseStream.Managed.cs index 5aa170f8b74037..9ea2f404f014c0 100644 --- a/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpResponseStream.Managed.cs +++ b/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpResponseStream.Managed.cs @@ -128,7 +128,7 @@ internal async Task WriteWebSocketHandshakeHeadersAsync() } } - private static byte[] s_crlf = new byte[] { 13, 10 }; + private static readonly byte[] s_crlf = "\r\n"u8.ToArray(); private static byte[] GetChunkSizeBytes(int size, bool final) => Encoding.ASCII.GetBytes($"{size:x}\r\n{(final ? "\r\n" : "")}"); diff --git a/src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/WebSocketHandle.Managed.cs b/src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/WebSocketHandle.Managed.cs index f19f9a572772f0..9f5beb3874e657 100644 --- a/src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/WebSocketHandle.Managed.cs +++ b/src/libraries/System.Net.WebSockets.Client/src/System/Net/WebSockets/WebSocketHandle.Managed.cs @@ -376,14 +376,7 @@ static string GetDeflateOptions(WebSocketDeflateOptions options) private static KeyValuePair CreateSecKeyAndSecWebSocketAccept() { // GUID appended by the server as part of the security key response. Defined in the RFC. - ReadOnlySpan wsServerGuidBytes = new byte[] - { - (byte)'2', (byte)'5', (byte)'8', (byte)'E', (byte)'A', (byte)'F', (byte)'A', (byte)'5', (byte)'-', - (byte)'E', (byte)'9', (byte)'1', (byte)'4', (byte)'-', - (byte)'4', (byte)'7', (byte)'D', (byte)'A', (byte)'-', - (byte)'9', (byte)'5', (byte)'C', (byte)'A', (byte)'-', - (byte)'C', (byte)'5', (byte)'A', (byte)'B', (byte)'0', (byte)'D', (byte)'C', (byte)'8', (byte)'5', (byte)'B', (byte)'1', (byte)'1' - }; + ReadOnlySpan wsServerGuidBytes = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"u8; Span bytes = stackalloc byte[24 /* Base64 guid length */ + wsServerGuidBytes.Length]; diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Path.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Path.cs index e7ed97c683a8b4..b6edb311eac4cf 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Path.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Path.cs @@ -816,11 +816,7 @@ private static unsafe string JoinInternal(ReadOnlySpan first, ReadOnlySpan } } - private static ReadOnlySpan Base32Char => new byte[32] { // uses C# compiler's optimization for static byte[] data - (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', (byte)'h', - (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', (byte)'o', (byte)'p', - (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', (byte)'v', (byte)'w', (byte)'x', - (byte)'y', (byte)'z', (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5' }; + private static ReadOnlySpan Base32Char => "abcdefghijklmnopqrstuvwxyz012345"u8; private static unsafe void Populate83FileNameFromRandomBytes(byte* bytes, int byteCount, Span chars) { diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataReader.WinMD.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataReader.WinMD.cs index de4c80edffac8c..eedf307fe0b8df 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataReader.WinMD.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/MetadataReader.WinMD.cs @@ -11,15 +11,7 @@ public partial class MetadataReader { internal const string ClrPrefix = ""; - internal static readonly byte[] WinRTPrefix = new[] { - (byte)'<', - (byte)'W', - (byte)'i', - (byte)'n', - (byte)'R', - (byte)'T', - (byte)'>' - }; + internal static readonly byte[] WinRTPrefix = ""u8.ToArray(); #region Projection Tables From b1c2854d3bd078460a8094b4481795443e87c9c3 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Sat, 11 Jun 2022 06:32:32 +0200 Subject: [PATCH 055/337] Propagate c++ unhandled exception to previous handler (#70556) * Propagate c++ unhandled exception to previous handler Currently runtime doesn't propagate c++ unhandled exceptions to a handler registered by the std::set_terminate. That is problematic for custom hosts that want e.g. to log such exceptions. This change adds chaining unhandled C++ exception to the previously registered handler. Co-authored-by: Jan Kotas --- src/coreclr/vm/ceemain.cpp | 5 --- src/coreclr/vm/excep.cpp | 90 +++----------------------------------- src/coreclr/vm/excep.h | 1 - 3 files changed, 6 insertions(+), 90 deletions(-) diff --git a/src/coreclr/vm/ceemain.cpp b/src/coreclr/vm/ceemain.cpp index aa100b26058224..36d63aa9e771dc 100644 --- a/src/coreclr/vm/ceemain.cpp +++ b/src/coreclr/vm/ceemain.cpp @@ -1335,11 +1335,6 @@ void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading) // No longer process exceptions g_fNoExceptions = true; - // - // Remove our global exception filter. If it was NULL before, we want it to be null now. - // - UninstallUnhandledExceptionFilter(); - // @TODO: This does things which shouldn't occur in part 2. Namely, // calling managed dll main callbacks (AppDomain::SignalProcessDetach), and // RemoveAppDomainFromIPC. diff --git a/src/coreclr/vm/excep.cpp b/src/coreclr/vm/excep.cpp index 86a4945eeb4d9e..ae9e2fa714c226 100644 --- a/src/coreclr/vm/excep.cpp +++ b/src/coreclr/vm/excep.cpp @@ -4455,18 +4455,10 @@ LONG DefaultCatchNoSwallowFilter(EXCEPTION_POINTERS *ep, PVOID pv) return EXCEPTION_CONTINUE_SEARCH; } // LONG DefaultCatchNoSwallowFilter() -// Note: This is used only for CoreCLR on WLC. -// // We keep a pointer to the previous unhandled exception filter. After we install, we use -// this to call the previous guy. When we un-install, we put them back. Putting them back -// is a bug -- we have no guarantee that the DLL unload order matches the DLL load order -- we -// may in fact be putting back a pointer to a DLL that has been unloaded. -// +// this to call the previous guy. -// initialize to -1 because NULL won't detect difference between us not having installed our handler -// yet and having installed it but the original handler was NULL. -static LPTOP_LEVEL_EXCEPTION_FILTER g_pOriginalUnhandledExceptionFilter = (LPTOP_LEVEL_EXCEPTION_FILTER)-1; -#define FILTER_NOT_INSTALLED (LPTOP_LEVEL_EXCEPTION_FILTER) -1 +static LPTOP_LEVEL_EXCEPTION_FILTER g_pOriginalUnhandledExceptionFilter = NULL; BOOL InstallUnhandledExceptionFilter() { @@ -4476,46 +4468,15 @@ BOOL InstallUnhandledExceptionFilter() { STATIC_CONTRACT_FORBID_FAULT; #ifndef TARGET_UNIX - // We will be here only for CoreCLR on WLC since we dont - // register UEF for SL. - if (g_pOriginalUnhandledExceptionFilter == FILTER_NOT_INSTALLED) { + g_pOriginalUnhandledExceptionFilter = SetUnhandledExceptionFilter(COMUnhandledExceptionFilter); - #pragma prefast(push) - #pragma prefast(suppress:28725, "Calling to SetUnhandledExceptionFilter is intentional in this case.") - g_pOriginalUnhandledExceptionFilter = SetUnhandledExceptionFilter(COMUnhandledExceptionFilter); - #pragma prefast(pop) - - // make sure is set (ie. is not our special value to indicate unset) - LOG((LF_EH, LL_INFO10, "InstallUnhandledExceptionFilter registered UEF with OS for CoreCLR!\n")); - } - _ASSERTE(g_pOriginalUnhandledExceptionFilter != FILTER_NOT_INSTALLED); + LOG((LF_EH, LL_INFO10, "InstallUnhandledExceptionFilter registered UEF with OS for CoreCLR!\n")); #endif // !TARGET_UNIX // All done - successfully! return TRUE; } -void UninstallUnhandledExceptionFilter() { - STATIC_CONTRACT_NOTHROW; - STATIC_CONTRACT_GC_NOTRIGGER; - STATIC_CONTRACT_MODE_ANY; - STATIC_CONTRACT_FORBID_FAULT; - -#ifndef TARGET_UNIX - // We will be here only for CoreCLR on WLC or on Mac SL. - if (g_pOriginalUnhandledExceptionFilter != FILTER_NOT_INSTALLED) { - - #pragma prefast(push) - #pragma prefast(suppress:28725, "Calling to SetUnhandledExceptionFilter is intentional in this case.") - SetUnhandledExceptionFilter(g_pOriginalUnhandledExceptionFilter); - #pragma prefast(pop) - - g_pOriginalUnhandledExceptionFilter = FILTER_NOT_INSTALLED; - LOG((LF_EH, LL_INFO10, "UninstallUnhandledExceptionFilter unregistered UEF from OS for CoreCLR!\n")); - } -#endif // !TARGET_UNIX -} - // // Update the current throwable on the thread if necessary. If we're looking at one of our exceptions, and if the // current throwable on the thread is NULL, then we'll set it to something more useful based on the @@ -4969,48 +4930,9 @@ LONG InternalUnhandledExceptionFilter( return retval; } - // Chaining back to previous UEF handler could be a potential security risk. See - // http://uninformed.org/index.cgi?v=4&a=5&p=1 for details. We are not alone in - // stopping the chain - CRT (as of Orcas) is also doing that. - // - // The change below applies to a thread that starts in native mode and transitions to managed. - - // Let us assume the process loaded two CoreCLRs, C1 and C2, in that order. Thus, in the UEF chain - // (assuming no other entity setup their UEF), C2?s UEF will be the topmost. - // - // Now, assume the stack looks like the following (stack grows down): - // - // Native frame - // Managed Frame (C1) - // Managed Frame (C2) - // Managed Frame (C1) - // Managed Frame (C2) - // Managed Frame (C1) - // - // Suppose an exception is thrown in C1 instance in the last managed frame and it goes unhandled. Eventually - // it will reach the OS which will invoke the UEF. Note that the topmost UEF belongs to C2 instance and it - // will start processing the exception. C2?s UEF could return EXCEPTION_CONTINUE_SEARCH to indicate - // that we should handoff the processing to the last installed UEF. In the example above, we would handoff - // the control to the UEF of the CoreCLR instance that actually threw the exception today. In reality, it - // could be some unknown code too. - // - // Not chaining back to the last UEF, in the case of this example, would imply that certain notifications - // (e.g. Unhandled Exception Notification to the AppDomain) specific to the instance that raised the exception - // will not get fired. However, similar behavior can happen today if another UEF sits between - // C1 and C2 and that may not callback to C1 or perhaps just terminate process. - // - // For CoreCLR, this will not be an issue. See - // http://sharepoint/sites/clros/Shared%20Documents/Design%20Documents/EH/Chaining%20in%20%20UEF%20-%20One%20Pager.docx - // for details. - // - // Note: Also see the conditional UEF registration with the OS in EEStartupHelper. - - // We would be here only on CoreCLR for WLC since we dont register - // the UEF with the OS for SL. - if (g_pOriginalUnhandledExceptionFilter != FILTER_NOT_INSTALLED - && g_pOriginalUnhandledExceptionFilter != NULL) + if (g_pOriginalUnhandledExceptionFilter != NULL) { - STRESS_LOG1(LF_EH, LL_INFO100, "InternalUnhandledExceptionFilter: Not chaining back to previous UEF at address %p on CoreCLR!\n", g_pOriginalUnhandledExceptionFilter); + return g_pOriginalUnhandledExceptionFilter(pExceptionInfo); } return retval; diff --git a/src/coreclr/vm/excep.h b/src/coreclr/vm/excep.h index eea65678cc6a37..dd773bb2434830 100644 --- a/src/coreclr/vm/excep.h +++ b/src/coreclr/vm/excep.h @@ -146,7 +146,6 @@ BOOL IsCOMPlusExceptionHandlerInstalled(); #endif BOOL InstallUnhandledExceptionFilter(); -void UninstallUnhandledExceptionFilter(); #if !defined(TARGET_UNIX) // Section naming is a strategy by itself. Ideally, we could have named the UEF section From 21b5b2e8b7c8c0e66c7a041a61cce8ff4d53ea1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Sat, 11 Jun 2022 10:34:59 +0200 Subject: [PATCH 056/337] [mono] A few more PowerPC cleanups (#70576) Replace `__mono_ppc__` and `__mono_ppc64__` defines with the proper `TARGET_POWERPC` and `TARGET_POWERPC64` ones Use `TARGET_POWERPC64` in a few places where it is more appropriate. --- src/mono/CMakeLists.txt | 5 +- src/mono/cmake/config.h.in | 3 - src/mono/mono/arch/ppc/ppc-codegen.h | 8 +-- src/mono/mono/mini/CMakeLists.txt | 4 +- src/mono/mono/mini/decompose.c | 2 +- src/mono/mono/mini/genmdesc.py | 1 + src/mono/mono/mini/mini-ops.h | 2 +- src/mono/mono/mini/mini-ppc.c | 88 +++++++++++++-------------- src/mono/mono/mini/mini-ppc.h | 20 +++--- src/mono/mono/mini/mini-runtime.c | 2 +- src/mono/mono/mini/tramp-ppc.c | 2 +- src/mono/mono/utils/CMakeLists.txt | 6 +- src/mono/mono/utils/mono-context.h | 6 +- src/mono/mono/utils/mono-sigcontext.h | 4 +- 14 files changed, 74 insertions(+), 79 deletions(-) diff --git a/src/mono/CMakeLists.txt b/src/mono/CMakeLists.txt index fd38892822c719..c0c513df0f95b9 100644 --- a/src/mono/CMakeLists.txt +++ b/src/mono/CMakeLists.txt @@ -376,6 +376,7 @@ elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "s390x") elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "wasm" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "wasm32") set(HOST_WASM 1) elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "ppc64le") + set(HOST_POWERPC 1) set(HOST_POWERPC64 1) else() message(FATAL_ERROR "CMAKE_SYSTEM_PROCESSOR='${CMAKE_SYSTEM_PROCESSOR}' not supported.") @@ -451,12 +452,10 @@ elseif(TARGET_ARCH STREQUAL "wasm" OR TARGET_ARCH STREQUAL "wasm32") set(SIZEOF_REGISTER 4) elseif(TARGET_ARCH STREQUAL "ppc64le") set(TARGET_POWERPC 1) - set(TARGET_POWERPC64 1) + set(TARGET_POWERPC64 1) set(MONO_ARCHITECTURE "\"ppc64le\"") set(TARGET_SIZEOF_VOID_P 8) set(SIZEOF_REGISTER 8) - add_definitions("-D__mono_ppc__") - add_definitions("-D__mono_ppc64__") else() message(FATAL_ERROR "TARGET_ARCH='${TARGET_ARCH}' not supported.") endif() diff --git a/src/mono/cmake/config.h.in b/src/mono/cmake/config.h.in index b13b884f01c634..9245408a013bda 100644 --- a/src/mono/cmake/config.h.in +++ b/src/mono/cmake/config.h.in @@ -706,9 +706,6 @@ /* ... */ #cmakedefine TARGET_PS3 1 -/* ... */ -#cmakedefine __mono_ppc64__ 1 - /* ... */ #cmakedefine TARGET_XBOX360 1 diff --git a/src/mono/mono/arch/ppc/ppc-codegen.h b/src/mono/mono/arch/ppc/ppc-codegen.h index ca3c13791ffda9..4a0076c92e37a8 100644 --- a/src/mono/mono/arch/ppc/ppc-codegen.h +++ b/src/mono/mono/arch/ppc/ppc-codegen.h @@ -138,7 +138,7 @@ enum { /* Macros to load/store pointer sized quantities */ -#if defined(__mono_ppc64__) && !defined(MONO_ARCH_ILP32) +#if defined(TARGET_POWERPC64) && !defined(MONO_ARCH_ILP32) #define ppc_ldptr(c,D,d,A) ppc_ld ((c), (D), (d), (A)) #define ppc_ldptr_update(c,D,d,A) ppc_ldu ((c), (D), (d), (A)) @@ -171,7 +171,7 @@ enum { /* Macros to load/store regsize quantities */ -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 #define ppc_ldr(c,D,d,A) ppc_ld ((c), (D), (d), (A)) #define ppc_ldr_indexed(c,D,A,B) ppc_ldx ((c), (D), (A), (B)) #define ppc_str(c,S,d,A) ppc_std ((c), (S), (d), (A)) @@ -192,7 +192,7 @@ enum { /* PPC32 macros */ -#ifndef __mono_ppc64__ +#ifndef TARGET_POWERPC64 #define ppc_load_sequence(c,D,v) ppc_load32 ((c), (D), (guint32)(v)) @@ -801,7 +801,7 @@ my and Ximian's copyright to this code. ;) #define ppc_fctidz(c,D,B) ppc_fctidzx(c,D,B,0) #define ppc_fctidzd(c,D,B) ppc_fctidzx(c,D,B,1) -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 #define ppc_load_sequence(c,D,v) G_STMT_START { \ ppc_lis ((c), (D), ((guint64)(v) >> 48) & 0xffff); \ diff --git a/src/mono/mono/mini/CMakeLists.txt b/src/mono/mono/mini/CMakeLists.txt index 5c85f9d9275b91..85f5f14a210a2b 100644 --- a/src/mono/mono/mini/CMakeLists.txt +++ b/src/mono/mono/mini/CMakeLists.txt @@ -241,7 +241,7 @@ elseif(TARGET_S390X) set(arch_sources ${s390x_sources}) elseif(TARGET_WASM) set(arch_sources ${wasm_sources}) -elseif(TARGET_POWERPC) +elseif(TARGET_POWERPC64) set(arch_sources ${powerpc64_sources}) endif() @@ -491,7 +491,7 @@ add_custom_command( add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cpu-ppc64.h - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_POWERPC ${CMAKE_CURRENT_SOURCE_DIR} cpu-ppc64.h ppc64_cpu_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-ppc64.mdesc + COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_POWERPC64 ${CMAKE_CURRENT_SOURCE_DIR} cpu-ppc64.h ppc64_cpu_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-ppc64.mdesc VERBATIM ) diff --git a/src/mono/mono/mini/decompose.c b/src/mono/mono/mini/decompose.c index 601585b6d02d8b..59c8939f4c2f4b 100644 --- a/src/mono/mono/mini/decompose.c +++ b/src/mono/mono/mini/decompose.c @@ -101,7 +101,7 @@ decompose_long_opcode (MonoCompile *cfg, MonoInst *ins, MonoInst **repl_ins) NULLIFY_INS (ins); break; } -#ifndef __mono_ppc64__ +#ifndef TARGET_POWERPC64 case OP_LSUB_OVF: { guint16 opcode; diff --git a/src/mono/mono/mini/genmdesc.py b/src/mono/mono/mini/genmdesc.py index 7e46204743fff0..e04063d44ce745 100755 --- a/src/mono/mono/mini/genmdesc.py +++ b/src/mono/mono/mini/genmdesc.py @@ -23,6 +23,7 @@ "TARGET_ARM" : 1, "TARGET_ARM64" : 1, "TARGET_POWERPC" : 1, + "TARGET_POWERPC64" : 1, "TARGET_S390X" : 1, "TARGET_RISCV" : 1, "TARGET_RISCV32" : 1, diff --git a/src/mono/mono/mini/mini-ops.h b/src/mono/mono/mini/mini-ops.h index da197b492ee46a..c6219b0735a869 100644 --- a/src/mono/mono/mini/mini-ops.h +++ b/src/mono/mono/mini/mini-ops.h @@ -1382,7 +1382,7 @@ MINI_OP(OP_AMD64_LOADI8_MEMINDEX, "amd64_loadi8_memindex", IREG, IREG, IR MINI_OP(OP_AMD64_SAVE_SP_TO_LMF, "amd64_save_sp_to_lmf", NONE, NONE, NONE) #endif -#if defined(TARGET_POWERPC) +#if defined(TARGET_POWERPC) || defined(TARGET_POWERPC64) MINI_OP(OP_PPC_SUBFIC, "ppc_subfic", IREG, IREG, NONE) MINI_OP(OP_PPC_SUBFZE, "ppc_subfze", IREG, IREG, NONE) MINI_OP(OP_PPC_CHECK_FINITE, "ppc_check_finite", NONE, IREG, NONE) diff --git a/src/mono/mono/mini/mini-ppc.c b/src/mono/mono/mini/mini-ppc.c index 581775a34613c3..b88fe674984295 100644 --- a/src/mono/mono/mini/mini-ppc.c +++ b/src/mono/mono/mini/mini-ppc.c @@ -151,7 +151,7 @@ emit_memcpy (guint8 *code, int size, int dreg, int doffset, int sreg, int soffse doffset = soffset = 0; dreg = ppc_r11; } -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 /* the hardware has multiple load/store units and the move is long enough to use more then one register, then use load/load/store/store to execute 2 instructions per cycle. */ @@ -224,7 +224,7 @@ emit_memcpy (guint8 *code, int size, int dreg, int doffset, int sreg, int soffse int mono_arch_get_argument_info (MonoMethodSignature *csig, int param_count, MonoJitArgumentInfo *arg_info) { -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 NOT_IMPLEMENTED; return -1; #else @@ -274,7 +274,7 @@ mono_arch_get_argument_info (MonoMethodSignature *csig, int param_count, MonoJit #endif } -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 static gboolean is_load_sequence (guint32 *seq) { @@ -296,7 +296,7 @@ is_load_sequence (guint32 *seq) gboolean mono_ppc_is_direct_call_sequence (guint32 *code) { -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 g_assert(*code == 0x4e800021 || *code == 0x4e800020 || *code == 0x4e800420); /* the thunk-less direct call sequence: lis/ori/sldi/oris/ori/mtlr/blrl */ @@ -617,7 +617,7 @@ mono_arch_cpu_optimizations (guint32 *exclude_mask) return opts; } -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 #define CASE_PPC32(c) #define CASE_PPC64(c) case c: #else @@ -806,7 +806,7 @@ mono_arch_flush_register_windows (void) #define ALWAYS_ON_STACK(s) s #define FP_ALSO_IN_REG(s) s #else -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 #define ALWAYS_ON_STACK(s) s #define FP_ALSO_IN_REG(s) s #else @@ -934,7 +934,7 @@ is_struct_returnable_via_regs (MonoClass *klass, gboolean is_pinvoke) static void inline add_general (guint *gr, guint *stack_size, ArgInfo *ainfo, gboolean simple) { -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 g_assert (simple); #endif @@ -970,7 +970,7 @@ add_general (guint *gr, guint *stack_size, ArgInfo *ainfo, gboolean simple) (*gr) ++; } -#if defined(__APPLE__) || (defined(__mono_ppc64__) && !PPC_PASS_SMALL_FLOAT_STRUCTS_IN_FR_REGS) +#if defined(__APPLE__) || (defined(TARGET_POWERPC64) && !PPC_PASS_SMALL_FLOAT_STRUCTS_IN_FR_REGS) static gboolean has_only_a_r48_field (MonoClass *klass) { @@ -1114,7 +1114,7 @@ get_call_info (MonoMethodSignature *sig) else size = mono_class_value_size (klass, NULL); -#if defined(__APPLE__) || (defined(__mono_ppc64__) && !PPC_PASS_SMALL_FLOAT_STRUCTS_IN_FR_REGS) +#if defined(__APPLE__) || (defined(TARGET_POWERPC64) && !PPC_PASS_SMALL_FLOAT_STRUCTS_IN_FR_REGS) if ((size == 4 || size == 8) && has_only_a_r48_field (klass)) { cinfo->args [n].size = size; @@ -1124,7 +1124,7 @@ get_call_info (MonoMethodSignature *sig) cinfo->args [n].reg = fr; fr ++; FP_ALSO_IN_REG (gr ++); -#if !defined(__mono_ppc64__) +#if !defined(TARGET_POWERPC64) if (size == 8) FP_ALSO_IN_REG (gr ++); #endif @@ -1210,7 +1210,7 @@ get_call_info (MonoMethodSignature *sig) } } -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 if (nregs == 1 && is_pinvoke) cinfo->args [n].bytes = size; else @@ -1609,7 +1609,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) in = call->args [i]; if (ainfo->regtype == RegTypeGeneral) { -#ifndef __mono_ppc64__ +#ifndef TARGET_POWERPC64 if (!m_type_is_byref (t) && ((t->type == MONO_TYPE_I8) || (t->type == MONO_TYPE_U8))) { MONO_INST_NEW (cfg, ins, OP_MOVE); ins->dreg = mono_alloc_ireg (cfg); @@ -1837,7 +1837,7 @@ mono_arch_emit_setret (MonoCompile *cfg, MonoMethod *method, MonoInst *val) { MonoType *ret = mini_get_underlying_type (mono_method_signature_internal (method)->ret); if (!m_type_is_byref (ret)) { -#ifndef __mono_ppc64__ +#ifndef TARGET_POWERPC64 if (ret->type == MONO_TYPE_I8 || ret->type == MONO_TYPE_U8) { MonoInst *ins; @@ -2059,7 +2059,7 @@ mono_arch_peephole_pass_2 (MonoCompile *cfg, MonoBasicBlock *bb) ins->sreg1 = last_ins->sreg1; } break; -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 case OP_LOADU4_MEMBASE: case OP_LOADI4_MEMBASE: if (last_ins && (last_ins->opcode == OP_STOREI4_MEMBASE_REG) && @@ -2128,7 +2128,7 @@ mono_arch_decompose_opts (MonoCompile *cfg, MonoInst *ins) ins->opcode = OP_NOP; break; } -#ifndef __mono_ppc64__ +#ifndef TARGET_POWERPC64 case OP_ICONV_TO_R4: case OP_ICONV_TO_R8: { /* If we have a PPC_FEATURE_64 machine we can avoid @@ -2181,7 +2181,7 @@ mono_arch_decompose_opts (MonoCompile *cfg, MonoInst *ins) ins->opcode = OP_NOP; break; } -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 case OP_IADD_OVF: case OP_IADD_OVF_UN: case OP_ISUB_OVF: { @@ -2485,7 +2485,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) case OP_OR_IMM: case OP_XOR_IMM: { gboolean is_imm = ((ins->inst_imm & 0xffff0000) && (ins->inst_imm & 0xffff)); -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 if (ins->inst_imm & 0xffffffff00000000ULL) is_imm = TRUE; #endif @@ -2642,7 +2642,7 @@ emit_float_to_int (MonoCompile *cfg, guchar *code, int dreg, int sreg, int size, long offset = cfg->arch.fp_conv_var_offset; long sub_offset; /* sreg is a float, dreg is an integer reg. ppc_f0 is used a scratch */ -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 if (size == 8) { ppc_fctidz (code, ppc_f0, sreg); sub_offset = 0; @@ -2672,7 +2672,7 @@ emit_float_to_int (MonoCompile *cfg, guchar *code, int dreg, int sreg, int size, ppc_andid (code, dreg, dreg, 0xff); else if (size == 2) ppc_andid (code, dreg, dreg, 0xffff); -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 else if (size == 4) ppc_clrldi (code, dreg, dreg, 32); #endif @@ -2681,7 +2681,7 @@ emit_float_to_int (MonoCompile *cfg, guchar *code, int dreg, int sreg, int size, ppc_extsb (code, dreg, dreg); else if (size == 2) ppc_extsh (code, dreg, dreg); -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 else if (size == 4) ppc_extsw (code, dreg, dreg); #endif @@ -2761,7 +2761,7 @@ handle_thunk (MonoCompile *cfg, guchar *code, const guchar *target) break; } else { /* ppc64 requires 5 instructions, 32bit two instructions */ -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 const int const_load_size = 5; #else const int const_load_size = 2; @@ -2874,7 +2874,7 @@ ppc_patch_full (MonoCompile *cfg, guchar *code, const guchar *target, gboolean i } if (prim == 15 || ins == 0x4e800021 || ins == 0x4e800020 || ins == 0x4e800420) { -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 guint32 *seq = (guint32*)code; guint32 *branch_ins; @@ -3185,7 +3185,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) } break; case OP_LOADI4_MEMBASE: -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 if (ppc_is_imm16 (ins->inst_offset)) { if(ppc_is_dsoffset_valid (ins->inst_offset)) { ppc_lwa (code, ins->dreg, ins->inst_offset, ins->inst_basereg); @@ -3273,7 +3273,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) ppc_ldptr_indexed (code, ins->dreg, ins->inst_basereg, ins->sreg2); break; case OP_LOADI4_MEMINDEX: -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 ppc_lwax (code, ins->dreg, ins->inst_basereg, ins->sreg2); break; #endif @@ -3503,7 +3503,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) divisor_is_m1 = code; ppc_bc (code, PPC_BR_FALSE | PPC_BR_LIKELY, PPC_BR_EQ, 0); ppc_lis (code, ppc_r0, 0x8000); -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 if (ins->opcode == OP_LDIV) ppc_sldi (code, ppc_r0, ppc_r0, 32); #endif @@ -3514,7 +3514,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) */ if (ins->opcode == OP_IDIV) ppc_divwod (code, ins->dreg, ins->sreg1, ins->sreg2); -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 else ppc_divdod (code, ins->dreg, ins->sreg1, ins->sreg2); #endif @@ -3527,7 +3527,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) CASE_PPC64 (OP_LDIV_UN) if (ins->opcode == OP_IDIV_UN) ppc_divwuod (code, ins->dreg, ins->sreg1, ins->sreg2); -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 else ppc_divduod (code, ins->dreg, ins->sreg1, ins->sreg2); #endif @@ -3622,7 +3622,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) */ if (ins->opcode == OP_IMUL_OVF) ppc_mullwo (code, ins->dreg, ins->sreg1, ins->sreg2); -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 else ppc_mulldo (code, ins->dreg, ins->sreg1, ins->sreg2); #endif @@ -3638,7 +3638,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) */ if (ins->opcode == OP_IMUL_OVF_UN) ppc_mulhwu (code, ppc_r0, ins->sreg1, ins->sreg2); -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 else ppc_mulhdu (code, ppc_r0, ins->sreg1, ins->sreg2); #endif @@ -3701,7 +3701,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) ppc_stw (code, ins->sreg1, -4, ppc_r1); ppc_lfs (code, ins->dreg, -4, ppc_r1); break; -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 case OP_MOVE_F_TO_I8: ppc_stfd (code, ins->sreg1, -8, ppc_r1); ppc_ldptr (code, ins->dreg, -8, ppc_r1); @@ -4197,7 +4197,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) break; case OP_LCONV_TO_OVF_I4_2: case OP_LCONV_TO_OVF_I: { -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 NOT_IMPLEMENTED; #else guint8 *negative_branch, *msword_positive_branch, *msword_negative_branch, *ovf_ex_target; @@ -4382,7 +4382,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) break; case OP_JUMP_TABLE: mono_add_patch_info (cfg, offset, (MonoJumpInfoType)ins->inst_c1, ins->inst_p0); -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 ppc_load_sequence (code, ins->dreg, (guint64)0x0f0f0f0f0f0f0f0fLL); #else ppc_load_sequence (code, ins->dreg, (gulong)0x0f0f0f0fL); @@ -4390,7 +4390,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) break; } -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 case OP_ICONV_TO_I4: case OP_SEXT_I4: ppc_extsw (code, ins->dreg, ins->sreg1); @@ -4504,7 +4504,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) ppc_sync (code); if (ins->opcode == OP_ATOMIC_ADD_I4) ppc_lwarx (code, ppc_r0, 0, location); -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 else ppc_ldarx (code, ppc_r0, 0, location); #endif @@ -4513,7 +4513,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) if (ins->opcode == OP_ATOMIC_ADD_I4) ppc_stwcxd (code, ppc_r0, 0, location); -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 else ppc_stdcxd (code, ppc_r0, 0, location); #endif @@ -4537,7 +4537,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) ppc_sync (code); if (ins->opcode == OP_ATOMIC_CAS_I4) ppc_lwarx (code, ppc_r0, 0, location); -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 else ppc_ldarx (code, ppc_r0, 0, location); #endif @@ -4548,7 +4548,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) if (ins->opcode == OP_ATOMIC_CAS_I4) ppc_stwcxd (code, value, 0, location); -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 else ppc_stdcxd (code, value, 0, location); #endif @@ -4604,7 +4604,7 @@ mono_arch_register_lowlevel_calls (void) mono_register_jit_icall (mono_ppc_throw_exception, mono_icall_sig_void, TRUE); } -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 #if G_BYTE_ORDER == G_LITTLE_ENDIAN #define patch_load_sequence(ip,val) do {\ guint16 *__load = (guint16*)(ip); \ @@ -4911,7 +4911,7 @@ mono_arch_emit_prolog (MonoCompile *cfg) } } break; -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 case 4: if (ppc_is_imm16 (inst->inst_offset)) { ppc_stw (code, ainfo->reg, inst->inst_offset, inst->inst_basereg); @@ -4992,7 +4992,7 @@ mono_arch_emit_prolog (MonoCompile *cfg) } } break; -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 case 4: if (ppc_is_imm16 (inst->inst_offset)) { ppc_stw (code, ppc_r0, inst->inst_offset, inst->inst_basereg); @@ -5098,7 +5098,7 @@ mono_arch_emit_prolog (MonoCompile *cfg) else #endif { -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 if (ainfo->bytes) { g_assert (cur_reg == 0); #if G_BYTE_ORDER == G_BIG_ENDIAN @@ -5204,7 +5204,7 @@ mono_arch_emit_prolog (MonoCompile *cfg) ppc_mflr (code, ppc_r0); } else { mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_IP, NULL); -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 ppc_load_sequence (code, ppc_r0, (guint64)0x0101010101010101LL); #else ppc_load_sequence (code, ppc_r0, (gulong)0x01010101L); @@ -5692,7 +5692,7 @@ mono_arch_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMetho opcode = OP_IMIN; if (fsig->params [0]->type == MONO_TYPE_U4) opcode = OP_IMIN_UN; -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 else if (fsig->params [0]->type == MONO_TYPE_I8) opcode = OP_LMIN; else if (fsig->params [0]->type == MONO_TYPE_U8) @@ -5703,7 +5703,7 @@ mono_arch_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMetho opcode = OP_IMAX; if (fsig->params [0]->type == MONO_TYPE_U4) opcode = OP_IMAX_UN; -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 else if (fsig->params [0]->type == MONO_TYPE_I8) opcode = OP_LMAX; else if (fsig->params [0]->type == MONO_TYPE_U8) diff --git a/src/mono/mono/mini/mini-ppc.h b/src/mono/mono/mini/mini-ppc.h index 7c706ad7214dfa..60931e2827b73d 100644 --- a/src/mono/mono/mini/mini-ppc.h +++ b/src/mono/mono/mini/mini-ppc.h @@ -11,7 +11,7 @@ #include #include -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 #define MONO_ARCH_CPU_SPEC mono_ppc64_cpu_desc #else #define MONO_ARCH_CPU_SPEC mono_ppcg4 @@ -32,7 +32,7 @@ * reproduceable results for benchmarks */ #define MONO_ARCH_CODE_ALIGNMENT 32 -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 #define THUNK_SIZE ((2 + 5) * 4) #else #define THUNK_SIZE ((2 + 2) * 4) @@ -80,7 +80,7 @@ typedef struct MonoCompileArch { * quantities. */ -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 #define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS #define MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS @@ -91,7 +91,7 @@ typedef struct MonoCompileArch { #define PPC_USES_FUNCTION_DESCRIPTOR #endif -#else /* must be __mono_ppc__ */ +#else /* must be TARGET_POWERPC */ #if defined(_AIX) /* 32 and 64 bit AIX use function descriptors */ @@ -113,7 +113,7 @@ typedef struct MonoCompileArch { #define MONO_ARCH_CALLEE_REGS ((0xff << ppc_r3) | (1 << ppc_r12) | (1 << ppc_r11)) #define MONO_ARCH_CALLEE_SAVED_REGS (0xfffff << ppc_r13) /* ppc_13 - ppc_31 */ -#if defined(__APPLE__) || defined(__mono_ppc64__) +#if defined(__APPLE__) || defined(TARGET_POWERPC64) #define MONO_ARCH_CALLEE_FREGS (0x1fff << ppc_f1) #else #define MONO_ARCH_CALLEE_FREGS (0xff << ppc_f1) @@ -122,7 +122,7 @@ typedef struct MonoCompileArch { #define MONO_ARCH_USE_FPSTACK FALSE -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 #define MONO_ARCH_INST_FIXED_REG(desc) (((desc) == 'a')? ppc_r3:\ ((desc) == 'g'? ppc_f1:-1)) #define MONO_ARCH_INST_IS_REGPAIR(desc) FALSE @@ -158,7 +158,7 @@ typedef struct MonoCompileArch { #elif defined(_AIX) /* FIXME: are these values valid? on 32-bit? */ #define PPC_RET_ADDR_OFFSET 16 -#if defined(__mono_ppc64__) +#if defined(TARGET_POWERPC64) #define PPC_STACK_PARAM_OFFSET 112 #define PPC_MINIMAL_STACK_SIZE 112 #else @@ -180,7 +180,7 @@ typedef struct MonoCompileArch { #define PPC_FIRST_FPARG_REG ppc_f1 #else /* Linux */ -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 #define PPC_RET_ADDR_OFFSET 16 // Power LE abvi2 #if (_CALL_ELF == 2) @@ -306,7 +306,7 @@ typedef struct { typedef struct { host_mgreg_t sp; -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 host_mgreg_t cr; #endif host_mgreg_t lr; @@ -386,7 +386,7 @@ mono_ppc_patch (guchar *code, const guchar *target); void mono_ppc_throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp, host_mgreg_t *int_regs, gdouble *fp_regs, gboolean rethrow, gboolean preserve_ips); -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 #define MONO_PPC_32_64_CASE(c32,c64) c64 extern void mono_ppc_emitted (guint8 *code, gint64 length, const char *format, ...); #else diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index d972a4f4a842c2..a4f782a980a571 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -4188,7 +4188,7 @@ mini_create_ftnptr (gpointer addr) mono_jit_unlock (); if (desc) return desc; -#if defined(__mono_ppc64__) +#if defined(TARGET_POWERPC64) desc = mono_mem_manager_alloc0 (jit_mm->mem_manager, 3 * sizeof (gpointer)); desc [0] = addr; diff --git a/src/mono/mono/mini/tramp-ppc.c b/src/mono/mono/mini/tramp-ppc.c index 7d3c286a95af75..956cce2413688d 100644 --- a/src/mono/mono/mini/tramp-ppc.c +++ b/src/mono/mono/mini/tramp-ppc.c @@ -496,7 +496,7 @@ mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_ty code = buf = (guint8 *)mono_mem_manager_code_reserve_align (mem_manager, TRAMPOLINE_SIZE, 4); short_branch = branch_for_target_reachable (code + MONO_PPC_32_64_CASE (8, 5*4), tramp); -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 /* FIXME: make shorter if possible */ #else if (short_branch) diff --git a/src/mono/mono/utils/CMakeLists.txt b/src/mono/mono/utils/CMakeLists.txt index 47634e0be3e9fa..4f46a18ffd4397 100644 --- a/src/mono/mono/utils/CMakeLists.txt +++ b/src/mono/mono/utils/CMakeLists.txt @@ -209,9 +209,7 @@ endif() if(MONO_CROSS_COMPILE) set(utils_arch_sources "${utils_arch_sources};mono-hwcap-cross.c") -elseif(TARGET_AMD64) -set(utils_arch_sources "${utils_arch_sources};mono-hwcap-x86.c") -elseif(TARGET_X86) +elseif(TARGET_AMD64 OR TARGET_X86) set(utils_arch_sources "${utils_arch_sources};mono-hwcap-x86.c") elseif(TARGET_ARM64) set(utils_arch_sources "${utils_arch_sources};mono-hwcap-arm64.c") @@ -221,7 +219,7 @@ elseif(TARGET_S390X) set(utils_arch_sources "${utils_arch_sources};mono-hwcap-s390x.c") elseif(TARGET_WASM) set(utils_arch_sources "${utils_arch_sources};mono-hwcap-wasm.c;mono-mmap-wasm.c") -elseif(TARGET_POWERPC) +elseif(TARGET_POWERPC OR TARGET_POWERPC64) set(utils_arch_sources "${utils_arch_sources};mono-hwcap-ppc.c") else() message(FATAL_ERROR "") diff --git a/src/mono/mono/utils/mono-context.h b/src/mono/mono/utils/mono-context.h index 0bc95f31134e8c..a1f0fe6f68e4d1 100644 --- a/src/mono/mono/utils/mono-context.h +++ b/src/mono/mono/utils/mono-context.h @@ -585,7 +585,7 @@ typedef struct { #define MONO_ARCH_HAS_MONO_CONTEXT 1 -#elif defined(__mono_ppc__) /* defined(__arm__) */ +#elif (defined (HOST_POWERPC) && !defined (MONO_CROSS_COMPILE)) || defined (TARGET_POWERPC) /* defined(__arm__) */ /* we define our own structure and we'll copy the data * from sigcontext/ucontext/mach when we need it. @@ -593,7 +593,7 @@ typedef struct { * We might also want to add an additional field to propagate * the original context from the signal handler. */ -#ifdef __mono_ppc64__ +#if (defined (HOST_POWERPC64) && !defined (MONO_CROSS_COMPILE)) || defined (TARGET_POWERPC64) typedef struct { gulong sc_ir; // pc @@ -683,7 +683,7 @@ typedef struct { : "memory" \ ) -#else /* !defined(__mono_ppc64__) */ +#else /* !defined(HOST_POWERPC64) */ typedef struct { host_mgreg_t sc_ir; // pc diff --git a/src/mono/mono/utils/mono-sigcontext.h b/src/mono/mono/utils/mono-sigcontext.h index 477d535aacf57a..e2970e99d4745a 100644 --- a/src/mono/mono/utils/mono-sigcontext.h +++ b/src/mono/mono/utils/mono-sigcontext.h @@ -262,7 +262,7 @@ #define UCONTEXT_REG_XMM15(ctx) (UCONTEXT_FREGS ((ctx)) [AMD64_XMM15]) #endif -#elif defined(__mono_ppc__) +#elif defined(TARGET_POWERPC) #if HAVE_UCONTEXT_H #include @@ -274,7 +274,7 @@ #include typedef ucontext_t os_ucontext; -#ifdef __mono_ppc64__ +#ifdef TARGET_POWERPC64 #define UCONTEXT_REG_Rn(ctx, n) (((os_ucontext*)(ctx))->uc_mcontext.gp_regs [(n)]) #define UCONTEXT_REG_FPRn(ctx, n) (((os_ucontext*)(ctx))->uc_mcontext.fp_regs [(n)]) #define UCONTEXT_REG_NIP(ctx) (((os_ucontext*)(ctx))->uc_mcontext.gp_regs [PT_NIP]) From 7adbc10dfb865fd5ecc37e309caa2d955b6061b0 Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Sat, 11 Jun 2022 12:28:56 +0200 Subject: [PATCH 057/337] make SslStream_UnifiedHello_Ok test conditional (#70472) --- .../tests/FunctionalTests/SslStreamNetworkStreamTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs index cd2b11f093b461..a513963c07fc96 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamNetworkStreamTest.cs @@ -1019,7 +1019,7 @@ public async Task SslStream_RandomSizeWrites_OK(int bufferSize, int readBufferSi } - [Theory] + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.SupportsTls10))] [InlineData(true)] [InlineData(false)] [PlatformSpecific(TestPlatforms.Windows)] From 624be28530c061c05e1d6a651ee04ca04ee6ae6d Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Sat, 11 Jun 2022 11:29:22 -0400 Subject: [PATCH 058/337] Remove some more unnecessary pragma warning disables (#70583) --- .../System.Drawing.Common/src/System/Drawing/Image.cs | 2 -- .../System.IO.Ports/src/System/IO/Ports/SerialPort.cs | 2 -- .../src/System/IO/Ports/SerialStream.Windows.cs | 2 -- .../src/System/Management/ManagementObjectSearcher.cs | 2 -- .../src/System/UnitySerializationHolder.cs | 2 -- .../System/ServiceModel/Syndication/Rss20FeedFormatter.cs | 2 -- .../src/Internal/SourceCore.cs | 7 ++++--- 7 files changed, 4 insertions(+), 15 deletions(-) diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/Image.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/Image.cs index 2493fe701ef978..67650053bfbc77 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/Image.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/Image.cs @@ -85,9 +85,7 @@ public object? Tag private protected Image() { } -#pragma warning disable CA2229 // Implement Serialization constructor private protected Image(SerializationInfo info, StreamingContext context) -#pragma warning restore CA2229 { byte[] dat = (byte[])info.GetValue("Data", typeof(byte[]))!; // Do not rename (binary serialization) diff --git a/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialPort.cs b/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialPort.cs index 9f05c3a14919b2..8f1e6ce4df1105 100644 --- a/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialPort.cs +++ b/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialPort.cs @@ -1181,7 +1181,6 @@ public void WriteLine(string text) Write(text + NewLine); } -#pragma warning disable CA2002 // ----- SECTION: internal utility methods ----------------* // included here just to use the event filter to block unwanted invocations of the Serial Port's events. @@ -1253,7 +1252,6 @@ private void CatchReceivedEvents(object src, SerialDataReceivedEventArgs e) } } } -#pragma warning restore CA2002 private void CompactBuffer() { diff --git a/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Windows.cs b/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Windows.cs index 93ae56a26e9cee..230daee5f67443 100644 --- a/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Windows.cs +++ b/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Windows.cs @@ -765,14 +765,12 @@ protected override void Dispose(bool disposing) // If we are disposing synchronize closing with raising SerialPort events if (disposing) { -#pragma warning disable CA2002 lock (this) { _handle.Close(); _handle = null; _threadPoolBinding.Dispose(); } -#pragma warning restore CA2002 } else { diff --git a/src/libraries/System.Management/src/System/Management/ManagementObjectSearcher.cs b/src/libraries/System.Management/src/System/Management/ManagementObjectSearcher.cs index d7b3a44ad27757..702dbff93e53c8 100644 --- a/src/libraries/System.Management/src/System/Management/ManagementObjectSearcher.cs +++ b/src/libraries/System.Management/src/System/Management/ManagementObjectSearcher.cs @@ -490,9 +490,7 @@ private void Initialize() throw new InvalidOperationException(); //If we're not connected yet, this is the time to do it... -#pragma warning disable CA2002 lock (this) -#pragma warning restore CA2002 { if (null == scope) scope = ManagementScope._Clone(null); diff --git a/src/libraries/System.Private.CoreLib/src/System/UnitySerializationHolder.cs b/src/libraries/System.Private.CoreLib/src/System/UnitySerializationHolder.cs index 792cfe4e74f60c..eedcebf37a7086 100644 --- a/src/libraries/System.Private.CoreLib/src/System/UnitySerializationHolder.cs +++ b/src/libraries/System.Private.CoreLib/src/System/UnitySerializationHolder.cs @@ -30,9 +30,7 @@ internal static void GetUnitySerializationInfo(SerializationInfo info, int unity info.AddValue("AssemblyName", string.Empty); } -#pragma warning disable CA2229 // public for compat public UnitySerializationHolder(SerializationInfo info, StreamingContext context) -#pragma warning restore CA2229 { ArgumentNullException.ThrowIfNull(info); diff --git a/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/Rss20FeedFormatter.cs b/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/Rss20FeedFormatter.cs index 97e5aef050da02..9fe755dfbc3011 100644 --- a/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/Rss20FeedFormatter.cs +++ b/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/Rss20FeedFormatter.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#pragma warning disable 1634, 1691 - using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Globalization; diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/SourceCore.cs b/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/SourceCore.cs index 1399110f8c37ea..8d1d6250e5c24d 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/SourceCore.cs +++ b/src/libraries/System.Threading.Tasks.Dataflow/src/Internal/SourceCore.cs @@ -367,11 +367,12 @@ internal bool TryReceiveAll([NotNullWhen(true)] out IList? items) int count = _itemCountingFunc != null ? _itemCountingFunc(_owningSource, default(TOutput)!, items) : countReceived; _itemsRemovedAction(_owningSource, count); } -#pragma warning disable CS8762 // Parameter may not have a null value when exiting in some condition. + + Debug.Assert(items != null); return true; -#pragma warning restore CS8762 } - else return false; + + return false; } /// Gets the number of items available to be received from this block. From b1c227546ee2ff7f387b1ccc4a3e2f1f1606e4c0 Mon Sep 17 00:00:00 2001 From: Joni Aromaa Date: Sat, 11 Jun 2022 19:06:34 +0300 Subject: [PATCH 059/337] Unpin locals (#70264) Contributes to #40553 --- src/coreclr/jit/compiler.h | 2 + src/coreclr/jit/gentree.h | 5 +++ src/coreclr/jit/lclvars.cpp | 80 +++++++++++++++++++++++-------------- 3 files changed, 57 insertions(+), 30 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index c838b9e9c7268f..909c22906c8921 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -614,6 +614,8 @@ class LclVarDsc unsigned char lvSingleDefDisqualifyReason = 'H'; #endif + unsigned char lvAllDefsAreNoGc : 1; // For pinned locals: true if all defs of this local are no-gc + #if FEATURE_MULTIREG_ARGS regNumber lvRegNumForSlot(unsigned slotNum) { diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index c0de433f8328f5..4f90d3d880df22 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -1109,6 +1109,11 @@ struct GenTree return true; } + bool IsNotGcDef() const + { + return IsIntegralConst(0) || IsLocalAddrExpr(); + } + // LIR flags // These helper methods, along with the flag values they manipulate, are defined in lir.h // diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index cc12c8a3837dad..d51104d1b93e4a 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -4181,49 +4181,57 @@ void Compiler::lvaMarkLclRefs(GenTree* tree, BasicBlock* block, Statement* stmt, /* Is this an assignment to a local variable? */ - if (op1->gtOper == GT_LCL_VAR && op2->gtType != TYP_BOOL) + if (op1->gtOper == GT_LCL_VAR) { - /* Only simple assignments allowed for booleans */ + LclVarDsc* varDsc = lvaGetDesc(op1->AsLclVarCommon()); - if (tree->gtOper != GT_ASG) + if (varDsc->lvPinned && varDsc->lvAllDefsAreNoGc) { - goto NOT_BOOL; + if (!op2->IsNotGcDef()) + { + varDsc->lvAllDefsAreNoGc = false; + } } - /* Is the RHS clearly a boolean value? */ - - switch (op2->gtOper) + if (op2->gtType != TYP_BOOL) { - unsigned lclNum; + /* Only simple assignments allowed for booleans */ - case GT_CNS_INT: + if (tree->gtOper != GT_ASG) + { + goto NOT_BOOL; + } - if (op2->AsIntCon()->gtIconVal == 0) - { - break; - } - if (op2->AsIntCon()->gtIconVal == 1) - { - break; - } + /* Is the RHS clearly a boolean value? */ - // Not 0 or 1, fall through .... - FALLTHROUGH; + switch (op2->gtOper) + { + case GT_CNS_INT: - default: + if (op2->AsIntCon()->gtIconVal == 0) + { + break; + } + if (op2->AsIntCon()->gtIconVal == 1) + { + break; + } - if (op2->OperIsCompare()) - { - break; - } + // Not 0 or 1, fall through .... + FALLTHROUGH; - NOT_BOOL: + default: - lclNum = op1->AsLclVarCommon()->GetLclNum(); - noway_assert(lclNum < lvaCount); + if (op2->OperIsCompare()) + { + break; + } - lvaTable[lclNum].lvIsBoolean = false; - break; + NOT_BOOL: + + varDsc->lvIsBoolean = false; + break; + } } } } @@ -4278,7 +4286,8 @@ void Compiler::lvaMarkLclRefs(GenTree* tree, BasicBlock* block, Statement* stmt, { if (lvaVarAddrExposed(lclNum)) { - varDsc->lvIsBoolean = false; + varDsc->lvIsBoolean = false; + varDsc->lvAllDefsAreNoGc = false; } if (tree->gtOper == GT_LCL_FLD) @@ -4703,6 +4712,8 @@ void Compiler::lvaComputeRefCounts(bool isRecompute, bool setSlotNumbers) varDsc->setLvRefCnt(0); varDsc->setLvRefCntWtd(BB_ZERO_WEIGHT); + varDsc->lvAllDefsAreNoGc = true; + // Special case for some varargs params ... these must // remain unreferenced. const bool isSpecialVarargsParam = varDsc->lvIsParam && raIsVarargsStackArg(lclNum); @@ -4750,6 +4761,8 @@ void Compiler::lvaComputeRefCounts(bool isRecompute, bool setSlotNumbers) { varDsc->lvSingleDef = varDsc->lvIsParam; varDsc->lvSingleDefRegCandidate = varDsc->lvIsParam; + + varDsc->lvAllDefsAreNoGc = true; } } @@ -4868,6 +4881,13 @@ void Compiler::lvaComputeRefCounts(bool isRecompute, bool setSlotNumbers) varDsc->lvImplicitlyReferenced = 1; } } + + if (varDsc->lvPinned && varDsc->lvAllDefsAreNoGc) + { + varDsc->lvPinned = 0; + + JITDUMP("V%02u was unpinned as all def candidates were local.\n", lclNum); + } } } From 7a85d0c8b2fac0b33c5f06f08ac59ebcd88e5dc2 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Sat, 11 Jun 2022 12:18:21 -0400 Subject: [PATCH 060/337] Skip X.509 extension copies where possible --- .../Security/Cryptography/Oids.Shared.cs | 2 ++ .../Security/Cryptography/AsnEncodedData.cs | 21 +++++++++++++++---- ...X509AuthorityInformationAccessExtension.cs | 8 +++---- .../X509BasicConstraintsExtension.cs | 2 +- .../X509EnhancedKeyUsageExtension.cs | 2 +- .../X509Certificates/X509Extension.cs | 12 +++++++++++ .../X509Certificates/X509KeyUsageExtension.cs | 2 +- .../X509SubjectKeyIdentifierExtension.cs | 6 +++--- 8 files changed, 41 insertions(+), 14 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/Oids.Shared.cs b/src/libraries/Common/src/System/Security/Cryptography/Oids.Shared.cs index 2fc4276104754e..46fd8e72b9a004 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/Oids.Shared.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/Oids.Shared.cs @@ -28,6 +28,7 @@ internal static partial class Oids private static volatile Oid? _enhancedKeyUsageOid; private static volatile Oid? _keyUsageOid; private static volatile Oid? _subjectKeyIdentifierOid; + private static volatile Oid? _authorityInformationAccessOid; internal static Oid RsaOid => _rsaOid ??= InitializeOid(Rsa); internal static Oid EcPublicKeyOid => _ecPublicKeyOid ??= InitializeOid(EcPublicKey); @@ -51,6 +52,7 @@ internal static partial class Oids internal static Oid EnhancedKeyUsageOid => _enhancedKeyUsageOid ??= InitializeOid(EnhancedKeyUsage); internal static Oid KeyUsageOid => _keyUsageOid ??= InitializeOid(KeyUsage); internal static Oid SubjectKeyIdentifierOid => _subjectKeyIdentifierOid ??= InitializeOid(SubjectKeyIdentifier); + internal static Oid AuthorityInformationAccessOid => _authorityInformationAccessOid ??= InitializeOid(AuthorityInformationAccess); private static Oid InitializeOid(string oidValue) { diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AsnEncodedData.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AsnEncodedData.cs index fcc93a066fe7ca..0e7c9eb33af02f 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AsnEncodedData.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AsnEncodedData.cs @@ -39,14 +39,12 @@ public AsnEncodedData(AsnEncodedData asnEncodedData) Reset(asnEncodedData._oid, asnEncodedData._rawData); } - public AsnEncodedData(Oid? oid, byte[] rawData) + public AsnEncodedData(Oid? oid, byte[] rawData) : this(oid, rawData, skipCopy: false) { - Reset(oid, rawData); } - public AsnEncodedData(string oid, byte[] rawData) + public AsnEncodedData(string oid, byte[] rawData) : this(new Oid(oid), rawData, skipCopy: false) { - Reset(new Oid(oid), rawData); } /// @@ -79,6 +77,21 @@ public AsnEncodedData(string oid, ReadOnlySpan rawData) Reset(new Oid(oid), rawData); } + internal AsnEncodedData(Oid? oid, byte[] rawData, bool skipCopy) + { + if (skipCopy) + { + ArgumentNullException.ThrowIfNull(rawData); + Oid = oid; + _rawData = rawData; + } + else + { + Reset(oid, rawData); + } + + } + public Oid? Oid { get => _oid; diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509AuthorityInformationAccessExtension.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509AuthorityInformationAccessExtension.cs index a2d597a8cab721..c5e026207a3ce6 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509AuthorityInformationAccessExtension.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509AuthorityInformationAccessExtension.cs @@ -20,7 +20,7 @@ public sealed class X509AuthorityInformationAccessExtension : X509Extension /// class. /// public X509AuthorityInformationAccessExtension() - : base(Oids.AuthorityInformationAccess) + : base(Oids.AuthorityInformationAccessOid) { _decoded = Array.Empty(); } @@ -43,7 +43,7 @@ public X509AuthorityInformationAccessExtension() /// did not decode as an Authority Information Access extension. /// public X509AuthorityInformationAccessExtension(byte[] rawData, bool critical = false) - : base(Oids.AuthorityInformationAccess, rawData, critical) + : base(Oids.AuthorityInformationAccessOid, rawData, critical) { _decoded = Decode(RawData); } @@ -63,7 +63,7 @@ public X509AuthorityInformationAccessExtension(byte[] rawData, bool critical = f /// did not decode as an Authority Information Access extension. /// public X509AuthorityInformationAccessExtension(ReadOnlySpan rawData, bool critical = false) - : base(Oids.AuthorityInformationAccess, rawData, critical) + : base(Oids.AuthorityInformationAccessOid, rawData, critical) { _decoded = Decode(RawData); } @@ -95,7 +95,7 @@ public X509AuthorityInformationAccessExtension( IEnumerable? ocspUris, IEnumerable? caIssuersUris, bool critical = false) - : base(Oids.AuthorityInformationAccess, Encode(ocspUris, caIssuersUris), critical) + : base(Oids.AuthorityInformationAccessOid, Encode(ocspUris, caIssuersUris), critical, skipCopy: true) { _decoded = Decode(RawData); } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509BasicConstraintsExtension.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509BasicConstraintsExtension.cs index fd7d5373af68d1..29b29e4652e197 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509BasicConstraintsExtension.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509BasicConstraintsExtension.cs @@ -12,7 +12,7 @@ public X509BasicConstraintsExtension() } public X509BasicConstraintsExtension(bool certificateAuthority, bool hasPathLengthConstraint, int pathLengthConstraint, bool critical) - : base(Oids.BasicConstraints2Oid, EncodeExtension(certificateAuthority, hasPathLengthConstraint, pathLengthConstraint), critical) + : base(Oids.BasicConstraints2Oid, EncodeExtension(certificateAuthority, hasPathLengthConstraint, pathLengthConstraint), critical, skipCopy: true) { } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509EnhancedKeyUsageExtension.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509EnhancedKeyUsageExtension.cs index f90979705b9052..712e2dfb0d0311 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509EnhancedKeyUsageExtension.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509EnhancedKeyUsageExtension.cs @@ -18,7 +18,7 @@ public X509EnhancedKeyUsageExtension(AsnEncodedData encodedEnhancedKeyUsages, bo } public X509EnhancedKeyUsageExtension(OidCollection enhancedKeyUsages, bool critical) - : base(Oids.EnhancedKeyUsageOid, EncodeExtension(enhancedKeyUsages), critical) + : base(Oids.EnhancedKeyUsageOid, EncodeExtension(enhancedKeyUsages), critical, skipCopy: true) { } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Extension.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Extension.cs index fa6a8f8f1e9f11..a34104e7f14d72 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Extension.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Extension.cs @@ -68,6 +68,18 @@ public X509Extension(string oid, ReadOnlySpan rawData, bool critical) { } + internal X509Extension(Oid oid, byte[] rawData, bool critical, bool skipCopy) + : base(oid, rawData, skipCopy) + { + if (base.Oid?.Value == null) + throw new ArgumentNullException(nameof(oid)); + + if (base.Oid.Value.Length == 0) + throw new ArgumentException(SR.Format(SR.Arg_EmptyOrNullString_Named, "oid.Value"), nameof(oid)); + + Critical = critical; + } + public bool Critical { get; set; } public override void CopyFrom(AsnEncodedData asnEncodedData) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509KeyUsageExtension.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509KeyUsageExtension.cs index 631b55139a561c..cc823e390b780e 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509KeyUsageExtension.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509KeyUsageExtension.cs @@ -17,7 +17,7 @@ public X509KeyUsageExtension(AsnEncodedData encodedKeyUsage, bool critical) } public X509KeyUsageExtension(X509KeyUsageFlags keyUsages, bool critical) - : base(Oids.KeyUsageOid, X509Pal.Instance.EncodeX509KeyUsageExtension(keyUsages), critical) + : base(Oids.KeyUsageOid, X509Pal.Instance.EncodeX509KeyUsageExtension(keyUsages), critical, skipCopy: true) { } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509SubjectKeyIdentifierExtension.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509SubjectKeyIdentifierExtension.cs index fd893ce6d22913..72429338ef1c57 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509SubjectKeyIdentifierExtension.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509SubjectKeyIdentifierExtension.cs @@ -25,7 +25,7 @@ public X509SubjectKeyIdentifierExtension(byte[] subjectKeyIdentifier, bool criti } public X509SubjectKeyIdentifierExtension(ReadOnlySpan subjectKeyIdentifier, bool critical) - : base(Oids.SubjectKeyIdentifierOid, EncodeExtension(subjectKeyIdentifier), critical) + : base(Oids.SubjectKeyIdentifierOid, EncodeExtension(subjectKeyIdentifier), critical, skipCopy: true) { } @@ -35,12 +35,12 @@ public X509SubjectKeyIdentifierExtension(PublicKey key, bool critical) } public X509SubjectKeyIdentifierExtension(PublicKey key, X509SubjectKeyIdentifierHashAlgorithm algorithm, bool critical) - : base(Oids.SubjectKeyIdentifierOid, EncodeExtension(key, algorithm), critical) + : base(Oids.SubjectKeyIdentifierOid, EncodeExtension(key, algorithm), critical, skipCopy: true) { } public X509SubjectKeyIdentifierExtension(string subjectKeyIdentifier, bool critical) - : base(Oids.SubjectKeyIdentifierOid, EncodeExtension(subjectKeyIdentifier), critical) + : base(Oids.SubjectKeyIdentifierOid, EncodeExtension(subjectKeyIdentifier), critical, skipCopy: true) { } From 1f772afc4b84ee03cafe7965826b559a7540e34e Mon Sep 17 00:00:00 2001 From: Theodore Tsirpanis Date: Sat, 11 Jun 2022 20:41:56 +0300 Subject: [PATCH 061/337] Fix nullability annotation of `ILGenerator.BeginCatchBlock`. (#70615) --- .../src/System/Reflection/Emit/DynamicILGenerator.cs | 2 +- .../src/System/Reflection/Emit/ILGenerator.cs | 2 +- .../src/System/Reflection/Emit/ILGenerator.cs | 2 +- .../Linq/Expressions/Compiler/LambdaCompiler.Statements.cs | 2 +- .../ref/System.Reflection.Emit.ILGeneration.cs | 2 +- .../src/System/Reflection/Emit/ILGenerator.Mono.cs | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/DynamicILGenerator.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/DynamicILGenerator.cs index 55625b412f48eb..ace5eb7d1d0987 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/DynamicILGenerator.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/DynamicILGenerator.cs @@ -341,7 +341,7 @@ public override void BeginExceptFilterBlock() current.MarkFilterAddr(ILOffset); } - public override void BeginCatchBlock(Type exceptionType) + public override void BeginCatchBlock(Type? exceptionType) { if (CurrExcStackCount == 0) throw new NotSupportedException(SR.Argument_NotInExceptionBlock); diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs index 26c1ae27f88ad8..dfcc66d6dcb699 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs @@ -992,7 +992,7 @@ public virtual void BeginExceptFilterBlock() current.MarkFilterAddr(m_length); } - public virtual void BeginCatchBlock(Type exceptionType) + public virtual void BeginCatchBlock(Type? exceptionType) { // Begins a catch block. Emits a branch instruction to the end of the current exception block. diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs index b5e8e0dc0230f9..49190e8c371258 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.cs @@ -21,7 +21,7 @@ public virtual int ILOffset } } - public virtual void BeginCatchBlock(Type exceptionType) + public virtual void BeginCatchBlock(Type? exceptionType) { } diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Statements.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Statements.cs index 321a38f8a069eb..f01cff002fc97c 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Statements.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Statements.cs @@ -946,7 +946,7 @@ private void EmitCatchStart(CatchBlock cb) // begin the catch, clear the exception, we've // already saved it _ilg.MarkLabel(endFilter); - _ilg.BeginCatchBlock(exceptionType: null!); + _ilg.BeginCatchBlock(exceptionType: null); _ilg.Emit(OpCodes.Pop); } diff --git a/src/libraries/System.Reflection.Emit.ILGeneration/ref/System.Reflection.Emit.ILGeneration.cs b/src/libraries/System.Reflection.Emit.ILGeneration/ref/System.Reflection.Emit.ILGeneration.cs index 449916fb2a442f..fbcc94202c48b8 100644 --- a/src/libraries/System.Reflection.Emit.ILGeneration/ref/System.Reflection.Emit.ILGeneration.cs +++ b/src/libraries/System.Reflection.Emit.ILGeneration/ref/System.Reflection.Emit.ILGeneration.cs @@ -17,7 +17,7 @@ public partial class ILGenerator { internal ILGenerator() { } public virtual int ILOffset { get { throw null; } } - public virtual void BeginCatchBlock(System.Type exceptionType) { } + public virtual void BeginCatchBlock(System.Type? exceptionType) { } public virtual void BeginExceptFilterBlock() { } public virtual System.Reflection.Emit.Label BeginExceptionBlock() { throw null; } public virtual void BeginFaultBlock() { } diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.Mono.cs index 249e596ef1b2ef..c1f4df1d9fab0e 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/ILGenerator.Mono.cs @@ -343,7 +343,7 @@ private void InternalEndClause() } } - public virtual void BeginCatchBlock(Type exceptionType) + public virtual void BeginCatchBlock(Type? exceptionType) { if (!InExceptionBlock) throw new NotSupportedException("Not in an exception block"); From 13491f9e3e707fd124c1c371f16b3b8973d17701 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Sat, 11 Jun 2022 10:42:26 -0700 Subject: [PATCH 062/337] Update dependencies from https://github.com/dotnet/arcade build 20220610.1 (#70612) Microsoft.DotNet.ApiCompat , Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Build.Tasks.Archives , Microsoft.DotNet.Build.Tasks.Feed , Microsoft.DotNet.Build.Tasks.Installers , Microsoft.DotNet.Build.Tasks.Packaging , Microsoft.DotNet.Build.Tasks.TargetFramework , Microsoft.DotNet.Build.Tasks.Templating , Microsoft.DotNet.Build.Tasks.Workloads , Microsoft.DotNet.CodeAnalysis , Microsoft.DotNet.GenAPI , Microsoft.DotNet.GenFacades , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.PackageTesting , Microsoft.DotNet.RemoteExecutor , Microsoft.DotNet.SharedFramework.Sdk , Microsoft.DotNet.VersionTools.Tasks , Microsoft.DotNet.XUnitConsoleRunner , Microsoft.DotNet.XUnitExtensions From Version 7.0.0-beta.22308.5 -> To Version 7.0.0-beta.22310.1 Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 76 ++++++++++++++++++++--------------------- eng/Versions.props | 32 ++++++++--------- global.json | 6 ++-- 3 files changed, 57 insertions(+), 57 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 5f87f4276cb439..d629df7063f7b4 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -54,77 +54,77 @@ - + https://github.com/dotnet/arcade - d681cd3568168a97aa4cf50a61af9ec74d307eb8 + 64c91380e3a363632470cacc667fe1dc0693b675 - + https://github.com/dotnet/arcade - d681cd3568168a97aa4cf50a61af9ec74d307eb8 + 64c91380e3a363632470cacc667fe1dc0693b675 - + https://github.com/dotnet/arcade - d681cd3568168a97aa4cf50a61af9ec74d307eb8 + 64c91380e3a363632470cacc667fe1dc0693b675 - + https://github.com/dotnet/arcade - d681cd3568168a97aa4cf50a61af9ec74d307eb8 + 64c91380e3a363632470cacc667fe1dc0693b675 - + https://github.com/dotnet/arcade - d681cd3568168a97aa4cf50a61af9ec74d307eb8 + 64c91380e3a363632470cacc667fe1dc0693b675 - + https://github.com/dotnet/arcade - d681cd3568168a97aa4cf50a61af9ec74d307eb8 + 64c91380e3a363632470cacc667fe1dc0693b675 - + https://github.com/dotnet/arcade - d681cd3568168a97aa4cf50a61af9ec74d307eb8 + 64c91380e3a363632470cacc667fe1dc0693b675 - + https://github.com/dotnet/arcade - d681cd3568168a97aa4cf50a61af9ec74d307eb8 + 64c91380e3a363632470cacc667fe1dc0693b675 - + https://github.com/dotnet/arcade - d681cd3568168a97aa4cf50a61af9ec74d307eb8 + 64c91380e3a363632470cacc667fe1dc0693b675 - + https://github.com/dotnet/arcade - d681cd3568168a97aa4cf50a61af9ec74d307eb8 + 64c91380e3a363632470cacc667fe1dc0693b675 - + https://github.com/dotnet/arcade - d681cd3568168a97aa4cf50a61af9ec74d307eb8 + 64c91380e3a363632470cacc667fe1dc0693b675 - + https://github.com/dotnet/arcade - d681cd3568168a97aa4cf50a61af9ec74d307eb8 + 64c91380e3a363632470cacc667fe1dc0693b675 - + https://github.com/dotnet/arcade - d681cd3568168a97aa4cf50a61af9ec74d307eb8 + 64c91380e3a363632470cacc667fe1dc0693b675 - + https://github.com/dotnet/arcade - d681cd3568168a97aa4cf50a61af9ec74d307eb8 + 64c91380e3a363632470cacc667fe1dc0693b675 - + https://github.com/dotnet/arcade - d681cd3568168a97aa4cf50a61af9ec74d307eb8 + 64c91380e3a363632470cacc667fe1dc0693b675 - + https://github.com/dotnet/arcade - d681cd3568168a97aa4cf50a61af9ec74d307eb8 + 64c91380e3a363632470cacc667fe1dc0693b675 - + https://github.com/dotnet/arcade - d681cd3568168a97aa4cf50a61af9ec74d307eb8 + 64c91380e3a363632470cacc667fe1dc0693b675 - + https://github.com/dotnet/arcade - d681cd3568168a97aa4cf50a61af9ec74d307eb8 + 64c91380e3a363632470cacc667fe1dc0693b675 https://github.com/microsoft/vstest @@ -254,9 +254,9 @@ https://github.com/dotnet/xharness 43e9fe312ac5513edf763877ce9ebf5d57ca9f88 - + https://github.com/dotnet/arcade - d681cd3568168a97aa4cf50a61af9ec74d307eb8 + 64c91380e3a363632470cacc667fe1dc0693b675 https://dev.azure.com/dnceng/internal/_git/dotnet-optimization diff --git a/eng/Versions.props b/eng/Versions.props index 32199b5ec1b38b..c9cd5414c496b9 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -53,22 +53,22 @@ 2.0.0-preview.4.22252.4 - 7.0.0-beta.22308.5 - 7.0.0-beta.22308.5 - 7.0.0-beta.22308.5 - 7.0.0-beta.22308.5 - 7.0.0-beta.22308.5 - 7.0.0-beta.22308.5 - 2.5.1-beta.22308.5 - 7.0.0-beta.22308.5 - 7.0.0-beta.22308.5 - 7.0.0-beta.22308.5 - 7.0.0-beta.22308.5 - 7.0.0-beta.22308.5 - 7.0.0-beta.22308.5 - 7.0.0-beta.22308.5 - 7.0.0-beta.22308.5 - 7.0.0-beta.22308.5 + 7.0.0-beta.22310.1 + 7.0.0-beta.22310.1 + 7.0.0-beta.22310.1 + 7.0.0-beta.22310.1 + 7.0.0-beta.22310.1 + 7.0.0-beta.22310.1 + 2.5.1-beta.22310.1 + 7.0.0-beta.22310.1 + 7.0.0-beta.22310.1 + 7.0.0-beta.22310.1 + 7.0.0-beta.22310.1 + 7.0.0-beta.22310.1 + 7.0.0-beta.22310.1 + 7.0.0-beta.22310.1 + 7.0.0-beta.22310.1 + 7.0.0-beta.22310.1 6.0.0-preview.1.102 diff --git a/global.json b/global.json index 2ae7c6b778d6e2..1447baf49983bd 100644 --- a/global.json +++ b/global.json @@ -8,9 +8,9 @@ "dotnet": "7.0.100-preview.3.22179.4" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.22308.5", - "Microsoft.DotNet.Helix.Sdk": "7.0.0-beta.22308.5", - "Microsoft.DotNet.SharedFramework.Sdk": "7.0.0-beta.22308.5", + "Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.22310.1", + "Microsoft.DotNet.Helix.Sdk": "7.0.0-beta.22310.1", + "Microsoft.DotNet.SharedFramework.Sdk": "7.0.0-beta.22310.1", "Microsoft.Build.NoTargets": "3.5.0", "Microsoft.Build.Traversal": "3.1.6", "Microsoft.NET.Sdk.IL": "7.0.0-preview.6.22305.4" From bfa0ac0f372ef83ecbaff756db2d41bb14cfb03a Mon Sep 17 00:00:00 2001 From: Will Smith Date: Sat, 11 Jun 2022 12:57:04 -0700 Subject: [PATCH 063/337] ARM64 - Always morph GT_MOD (#68885) --- src/coreclr/jit/lower.cpp | 3 +- src/coreclr/jit/lower.h | 2 +- src/coreclr/jit/lowerarmarch.cpp | 30 +++------ src/coreclr/jit/morph.cpp | 5 +- src/coreclr/jit/rationalize.cpp | 63 +++++++++++++++++++ src/coreclr/jit/rationalize.h | 4 ++ .../JitBlue/Runtime_68136/Runtime_68136.cs | 37 +++++++++++ .../Runtime_68136/Runtime_68136.csproj | 11 ++++ 8 files changed, 128 insertions(+), 27 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_68136/Runtime_68136.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_68136/Runtime_68136.csproj diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index 98bd11f0fd2d38..49dde8acd1fd41 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -5838,7 +5838,8 @@ GenTree* Lowering::LowerConstIntDivOrMod(GenTree* node) #if defined(TARGET_ARM64) if (divMod->OperIs(GT_MOD) && divisor->IsIntegralConstPow2()) { - return LowerModPow2(node); + LowerModPow2(node); + return node->gtNext; } assert(node->OperGet() != GT_MOD); #endif // TARGET_ARM64 diff --git a/src/coreclr/jit/lower.h b/src/coreclr/jit/lower.h index 7e6acf6f03009b..d54cc70347971c 100644 --- a/src/coreclr/jit/lower.h +++ b/src/coreclr/jit/lower.h @@ -355,7 +355,7 @@ class Lowering final : public Phase #elif defined(TARGET_ARM64) bool IsValidConstForMovImm(GenTreeHWIntrinsic* node); void LowerHWIntrinsicFusedMultiplyAddScalar(GenTreeHWIntrinsic* node); - GenTree* LowerModPow2(GenTree* node); + void LowerModPow2(GenTree* node); GenTree* LowerAddForPossibleContainment(GenTreeOp* node); #endif // !TARGET_XARCH && !TARGET_ARM64 #endif // FEATURE_HW_INTRINSICS diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp index 5ee0c27767ee1c..5b50f178e7c6ca 100644 --- a/src/coreclr/jit/lowerarmarch.cpp +++ b/src/coreclr/jit/lowerarmarch.cpp @@ -677,24 +677,18 @@ void Lowering::LowerRotate(GenTree* tree) // TODO: We could do this optimization in morph but we do not have // a conditional select op in HIR. At some point, we may // introduce such an op. -GenTree* Lowering::LowerModPow2(GenTree* node) +void Lowering::LowerModPow2(GenTree* node) { assert(node->OperIs(GT_MOD)); - GenTree* mod = node; - GenTree* dividend = mod->gtGetOp1(); - GenTree* divisor = mod->gtGetOp2(); + GenTreeOp* mod = node->AsOp(); + GenTree* dividend = mod->gtGetOp1(); + GenTree* divisor = mod->gtGetOp2(); assert(divisor->IsIntegralConstPow2()); const var_types type = mod->TypeGet(); assert((type == TYP_INT) || (type == TYP_LONG)); - LIR::Use use; - if (!BlockRange().TryGetUse(node, &use)) - { - return nullptr; - } - ssize_t cnsValue = static_cast(divisor->AsIntConCommon()->IntegralValue()) - 1; BlockRange().Remove(divisor); @@ -725,21 +719,15 @@ GenTree* Lowering::LowerModPow2(GenTree* node) BlockRange().InsertAfter(cns2, falseExpr); LowerNode(falseExpr); - GenTree* const cc = comp->gtNewOperNode(GT_CSNEG_MI, type, trueExpr, falseExpr); - cc->gtFlags |= GTF_USE_FLAGS; + mod->ChangeOper(GT_CSNEG_MI); + mod->gtOp1 = trueExpr; + mod->gtOp2 = falseExpr; + mod->gtFlags |= GTF_USE_FLAGS; JITDUMP("Lower: optimize X MOD POW2"); DISPNODE(mod); - JITDUMP("to:\n"); - DISPNODE(cc); - - BlockRange().InsertBefore(mod, cc); - ContainCheckNode(cc); - BlockRange().Remove(mod); - - use.ReplaceWith(cc); - return cc->gtNext; + ContainCheckNode(mod); } //------------------------------------------------------------------------ diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 29f10051e79f04..29ea92a874092a 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -10544,10 +10544,7 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac) #ifdef TARGET_ARM64 // ARM64 architecture manual suggests this transformation // for the mod operator. - // However, we do skip this optimization for ARM64 if the second operand - // is an integral constant power of 2 because there is an even better - // optimization in lowering that is specific for ARM64. - else if (!(tree->OperIs(GT_MOD) && op2->IsIntegralConstPow2())) + else #else // XARCH only applies this transformation if we know // that magic division will be used - which is determined diff --git a/src/coreclr/jit/rationalize.cpp b/src/coreclr/jit/rationalize.cpp index faa90cc61ad8ba..260cb1a98f4cdc 100644 --- a/src/coreclr/jit/rationalize.cpp +++ b/src/coreclr/jit/rationalize.cpp @@ -265,6 +265,62 @@ void Rationalizer::RewriteIntrinsicAsUserCall(GenTree** use, ArrayStack a % cns +// where cns is a signed integer constant that is a power of 2. +// We do this transformation because Lowering has a specific optimization +// for 'a % cns' that is not easily reduced by other means. +// +void Rationalizer::RewriteSubLshDiv(GenTree** use) +{ + if (!comp->opts.OptimizationEnabled()) + return; + + GenTree* const node = *use; + + if (!node->OperIs(GT_SUB)) + return; + + GenTree* op1 = node->gtGetOp1(); + GenTree* op2 = node->gtGetOp2(); + + if (!(node->TypeIs(TYP_INT, TYP_LONG) && op1->OperIs(GT_LCL_VAR))) + return; + + if (!op2->OperIs(GT_LSH)) + return; + + GenTree* lsh = op2; + GenTree* div = lsh->gtGetOp1(); + GenTree* shift = lsh->gtGetOp2(); + if (div->OperIs(GT_DIV) && shift->IsIntegralConst()) + { + GenTree* a = div->gtGetOp1(); + GenTree* cns = div->gtGetOp2(); + if (a->OperIs(GT_LCL_VAR) && cns->IsIntegralConstPow2() && + op1->AsLclVar()->GetLclNum() == a->AsLclVar()->GetLclNum()) + { + size_t shiftValue = shift->AsIntConCommon()->IntegralValue(); + size_t cnsValue = cns->AsIntConCommon()->IntegralValue(); + if ((cnsValue >> shiftValue) == 1) + { + node->ChangeOper(GT_MOD); + node->AsOp()->gtOp2 = cns; + BlockRange().Remove(lsh); + BlockRange().Remove(div); + BlockRange().Remove(a); + BlockRange().Remove(shift); + } + } + } +} +#endif + #ifdef DEBUG void Rationalizer::ValidateStatement(Statement* stmt, BasicBlock* block) @@ -775,6 +831,13 @@ PhaseStatus Rationalizer::DoPhase() m_rationalizer.RewriteIntrinsicAsUserCall(use, this->m_ancestors); } +#ifdef TARGET_ARM64 + if (node->OperIs(GT_SUB)) + { + m_rationalizer.RewriteSubLshDiv(use); + } +#endif + return Compiler::WALK_CONTINUE; } diff --git a/src/coreclr/jit/rationalize.h b/src/coreclr/jit/rationalize.h index 47d355cbbd38f4..329fbcbd1ac248 100644 --- a/src/coreclr/jit/rationalize.h +++ b/src/coreclr/jit/rationalize.h @@ -58,6 +58,10 @@ class Rationalizer final : public Phase void RewriteAssignment(LIR::Use& use); void RewriteAddress(LIR::Use& use); +#ifdef TARGET_ARM64 + void RewriteSubLshDiv(GenTree** use); +#endif + // Root visitor Compiler::fgWalkResult RewriteNode(GenTree** useEdge, Compiler::GenTreeStack& parents); }; diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_68136/Runtime_68136.cs b/src/tests/JIT/Regression/JitBlue/Runtime_68136/Runtime_68136.cs new file mode 100644 index 00000000000000..92a3f87e8b441d --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_68136/Runtime_68136.cs @@ -0,0 +1,37 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +public class Program +{ + public static IRuntime s_rt; + public static ulong s_1; + public static int Main() + { + try + { + var vr1 = (uint)((int)M2(ref s_1, 0) % (long)1); + M2(ref s_1, vr1); + } + catch (System.Exception) + { + } + + return 100; + } + + public static byte M2(ref ulong arg0, uint arg1) + { + s_rt.WriteLine(arg0); + return 0; + } +} + +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_68136/Runtime_68136.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_68136/Runtime_68136.csproj new file mode 100644 index 00000000000000..0365eac2ffab70 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_68136/Runtime_68136.csproj @@ -0,0 +1,11 @@ + + + Exe + + + True + + + + + \ No newline at end of file From 949b7230d7ce2b2eb0cd553a1699fe6cdd9f0149 Mon Sep 17 00:00:00 2001 From: Vladimir Sadov Date: Sat, 11 Jun 2022 13:21:49 -0700 Subject: [PATCH 064/337] [NativeAOT] Better fix for nativeaot lock/typesystem reentrancy (#70605) * Better fix for nativeaot lock/typesystem reentrancy * Turn list into a ring Co-authored-by: Jan Kotas * Update a comment * CR feedback Co-authored-by: Jan Kotas --- .../Threading/ThreadInt64PersistentCounter.cs | 51 ++++++++++++------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadInt64PersistentCounter.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadInt64PersistentCounter.cs index 2c39a5dd7cab30..c2d950e9677219 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadInt64PersistentCounter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadInt64PersistentCounter.cs @@ -9,16 +9,20 @@ namespace System.Threading { internal sealed class ThreadInt64PersistentCounter { - private static readonly LowLevelLock s_lock = new LowLevelLock(); + private readonly LowLevelLock _lock = new LowLevelLock(); [ThreadStatic] private static List? t_nodeFinalizationHelpers; private long _overflowCount; - // we pass comparer explicitly so that in NativeAOT case we would not end up - // calling into the type system when lock contention increments its counter - private HashSet _nodes = new HashSet(ObjectEqualityComparer.Default); + // dummy node serving as a start and end of the ring list + private ThreadLocalNode _nodes; + + public ThreadInt64PersistentCounter() + { + _nodes = new ThreadLocalNode(this); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Increment(object threadLocalCountObject) @@ -41,14 +45,17 @@ public object CreateThreadLocalCountObject() List? nodeFinalizationHelpers = t_nodeFinalizationHelpers ??= new List(1); nodeFinalizationHelpers.Add(new ThreadLocalNodeFinalizationHelper(node)); - s_lock.Acquire(); + _lock.Acquire(); try { - _nodes.Add(node); + node._next = _nodes._next; + node._prev = _nodes; + _nodes._next._prev = node; + _nodes._next = node; } finally { - s_lock.Release(); + _lock.Release(); } return node; @@ -58,22 +65,21 @@ public long Count { get { - s_lock.Acquire(); + _lock.Acquire(); long count = _overflowCount; try { - foreach (ThreadLocalNode node in _nodes) + ThreadLocalNode first = _nodes; + ThreadLocalNode node = first._next; + while (node != first) { count += node.Count; + node = node._next; } } - catch (OutOfMemoryException) - { - // Some allocation occurs above and it may be a bit awkward to get an OOM from this property getter - } finally { - s_lock.Release(); + _lock.Release(); } return count; @@ -85,24 +91,31 @@ private sealed class ThreadLocalNode private uint _count; private readonly ThreadInt64PersistentCounter _counter; + internal ThreadLocalNode _prev; + internal ThreadLocalNode _next; + public ThreadLocalNode(ThreadInt64PersistentCounter counter) { Debug.Assert(counter != null); _counter = counter; + _prev = this; + _next = this; } public void Dispose() { ThreadInt64PersistentCounter counter = _counter; - s_lock.Acquire(); + counter._lock.Acquire(); try { counter._overflowCount += _count; - counter._nodes.Remove(this); + + _prev._next = _next; + _next._prev = _prev; } finally { - s_lock.Release(); + counter._lock.Release(); } } @@ -145,7 +158,7 @@ private void OnAddOverflow(uint count) // The lock, in coordination with other places that read these values, ensures that both changes below become // visible together ThreadInt64PersistentCounter counter = _counter; - s_lock.Acquire(); + counter._lock.Acquire(); try { counter._overflowCount += (long)_count + count; @@ -153,7 +166,7 @@ private void OnAddOverflow(uint count) } finally { - s_lock.Release(); + counter._lock.Release(); } } } From 27195f670937c7e21ab68a806396f9d17c57231a Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Sun, 12 Jun 2022 05:26:28 +0800 Subject: [PATCH 065/337] Use ClrSafeInt everywhere and cleanup other same math declarations (#70197) * Replace safe math in util.hpp with ClrSafeInt * Remove unused definitions in safeint.h * Replace BSTR usage with ClrSafeInt * Delete intsafe.h --- src/coreclr/pal/inc/rt/intsafe.h | 1401 ---------------------------- src/coreclr/vm/classlayoutinfo.cpp | 10 +- src/coreclr/vm/ilmarshalers.cpp | 10 +- src/coreclr/vm/util.hpp | 92 -- 4 files changed, 10 insertions(+), 1503 deletions(-) delete mode 100644 src/coreclr/pal/inc/rt/intsafe.h diff --git a/src/coreclr/pal/inc/rt/intsafe.h b/src/coreclr/pal/inc/rt/intsafe.h deleted file mode 100644 index d793d357a3ba3b..00000000000000 --- a/src/coreclr/pal/inc/rt/intsafe.h +++ /dev/null @@ -1,1401 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/****************************************************************** -* * -* intsafe.h -- This module defines helper functions to prevent * -* integer overflow issues. * -* * -* * -******************************************************************/ -#ifndef _INTSAFE_H_INCLUDED_ -#define _INTSAFE_H_INCLUDED_ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#include // for IN, etc. - -#define INTSAFE_E_ARITHMETIC_OVERFLOW ((HRESULT)0x80070216L) // 0x216 = 534 = ERROR_ARITHMETIC_OVERFLOW - -#ifndef LOWORD -#define LOWORD(l) ((WORD)(((DWORD_PTR)(l)) & 0xffff)) -#endif - -#ifndef HIWORD -#define HIWORD(l) ((WORD)(((DWORD_PTR)(l)) >> 16)) -#endif - -#define HIDWORD(_qw) ((ULONG)((_qw) >> 32)) -#define LODWORD(_qw) ((ULONG)(_qw)) - -#if defined(MIDL_PASS) || defined(RC_INVOKED) || defined(_M_CEE_PURE) \ - || defined(_M_AMD64) || defined(__ARM_ARCH) || defined(_M_S390X) || defined(_M_LOONGARCH64) - -#ifndef UInt32x32To64 -#define UInt32x32To64(a, b) ((unsigned __int64)((ULONG)(a)) * (unsigned __int64)((ULONG)(b))) -#endif - -#elif defined(_M_IX86) - -#ifndef UInt32x32To64 -#define UInt32x32To64(a, b) (unsigned __int64)((unsigned __int64)(ULONG)(a) * (ULONG)(b)) -#endif - -#else - -#error Must define a target architecture. - -#endif - -// -// It is common for -1 to be used as an error value for various types -// -#define USHORT_ERROR (0xffff) -#define INT_ERROR (-1) -#define LONG_ERROR (-1L) -#define UINT_ERROR (0xffffffff) -#define ULONG_ERROR (0xffffffffUL) -#ifdef _MSC_VER -#define ULONGLONG_ERROR (0xffffffffffffffffui64) -#define HIDWORD_MASK (0xffffffff00000000ui64) -#else // _MSC_VER -#define ULONGLONG_ERROR (0xffffffffffffffffULL) -#define HIDWORD_MASK (0xffffffff00000000ULL) -#endif // _MSC_VER -#ifdef HOST_64BIT -#define SIZET_ERROR ULONGLONG_ERROR -#else -#define SIZET_ERROR ULONG_ERROR -#endif - -// -// We make some assumptions about the sizes of various types. Let's be -// explicit about those assumptions and check them. -// -C_ASSERT(sizeof(unsigned short) == 2); -C_ASSERT(sizeof(unsigned int) == 4); -C_ASSERT(sizeof(ULONG) == 4); - -// -// INT -> signed char conversion -// -__inline -HRESULT -IntToSignedChar( - IN INT iOperand, - OUT signed char* pch) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *pch = 0; - - if ((iOperand >= -128) && (iOperand <= 127)) - { - *pch = (signed char)iOperand; - hr = S_OK; - } - - return hr; -} - -// -// INT -> UCHAR conversion -// -__inline -HRESULT -IntToUChar( - IN INT iOperand, - OUT UCHAR* pch) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *pch = 0; - - if ((iOperand >= 0) && (iOperand <= 255)) - { - *pch = (UCHAR)iOperand; - hr = S_OK; - } - - return hr; -} - -// -// LONG -> UCHAR conversion -// -__inline -HRESULT -LongToUChar( - IN LONG lOperand, - OUT UCHAR* pch) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *pch = 0; - - if ((lOperand >= 0) && (lOperand <= 255)) - { - *pch = (UCHAR)lOperand; - hr = S_OK; - } - - return hr; -} - -// -// __inline is not sufficient. __forceinline is necessary. -// If the function is not inlined and you link .objs compiled with different compiler switches, -// you get one or the other function arbitrarily chosen. -// -// INT -> CHAR conversion -// -__forceinline -HRESULT -IntToChar( - IN INT iOperand, - OUT CHAR* pch) -{ -#ifdef _CHAR_UNSIGNED - return IntToUChar(iOperand, (UCHAR*)pch); -#else - return IntToSignedChar(iOperand, (signed char*)pch); -#endif -} - -// -// INT -> USHORT conversion -// -__inline -HRESULT -IntToUShort( - IN INT iOperand, - OUT USHORT* pusResult) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *pusResult = USHORT_ERROR; - - if ((iOperand >= 0) && (iOperand <= USHRT_MAX)) - { - *pusResult = (USHORT)iOperand; - hr = S_OK; - } - - return hr; -} - -// -// INT -> UINT conversion -// -__inline -HRESULT -IntToUInt( - IN INT iOperand, - OUT UINT* puResult) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *puResult = UINT_ERROR; - - if (iOperand >= 0) - { - *puResult = (UINT)iOperand; - hr = S_OK; - } - - return hr; -} - -// -// INT -> ULONG conversion -// -__inline -HRESULT -IntToULong( - IN INT iOperand, - OUT ULONG* pulResult) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *pulResult = ULONG_ERROR; - - if (iOperand >= 0) - { - *pulResult = (ULONG)iOperand; - hr = S_OK; - } - - return hr; -} - -// -// INT -> ULONGLONG conversion -// -__inline -HRESULT -IntToULongLong( - IN INT iOperand, - OUT ULONGLONG* pullResult) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *pullResult = ULONG_ERROR; - - if (iOperand >= 0) - { - *pullResult = (ULONGLONG)iOperand; - hr = S_OK; - } - - return hr; -} - -// -// UINT -> signed char conversion -// -__inline -HRESULT -UIntToSignedChar( - IN UINT uOperand, - OUT signed char* pch) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *pch = 0; - - if (uOperand <= 127) - { - *pch = (signed char)uOperand; - hr = S_OK; - } - - return hr; -} - -// -// UINT -> UCHAR conversion -// -__inline -HRESULT -UIntToUChar( - IN UINT uOperand, - OUT UCHAR* pch) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *pch = 0; - - if (uOperand <= 255) - { - *pch = (UCHAR)uOperand; - hr = S_OK; - } - - return hr; -} - -// -// UINT -> BYTE conversion -// -#define UIntToByte UIntToUChar - -// -// __inline is not sufficient. __forceinline is necessary. -// If the function is not inlined and you link .objs compiled with different compiler switches, -// you get one or the other function arbitrarily chosen. -// -// UINT -> CHAR conversion -// -__forceinline -HRESULT -UIntToChar( - IN UINT uOperand, - OUT CHAR* pch) -{ -#ifdef _CHAR_UNSIGNED - return UIntToUChar(uOperand, (UCHAR*)pch); -#else - return UIntToSignedChar(uOperand, (signed char*)pch); -#endif // _CHAR_UNSIGNED -} - -// -// UINT -> INT conversion -// -__inline -HRESULT -UIntToInt( - IN UINT uOperand, - OUT INT* piResult) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *piResult = INT_ERROR; - - if (uOperand <= INT_MAX) - { - *piResult = (INT)uOperand; - hr = S_OK; - } - - return hr; -} - -// -// UINT -> LONG conversion -// -__inline -HRESULT -UIntToLong( - IN UINT Operand, - OUT LONG* Result) -{ - if (Operand <= _I32_MAX) - { - *Result = (LONG)Operand; - return S_OK; - } - else - { - *Result = LONG_ERROR; - return INTSAFE_E_ARITHMETIC_OVERFLOW; - } -} - -// -// UINT -> ULONG conversion -// -__inline -HRESULT -UIntToULong( - IN UINT uOperand, - OUT ULONG* pulResult) -{ - *pulResult = (ULONG)uOperand; - - return S_OK; -} - -// -// ULONG -> UCHAR conversion -// -__inline -HRESULT -ULongToSignedChar( - IN ULONG ulOperand, - OUT signed char* pch) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *pch = 0; - - if (ulOperand <= 127) - { - *pch = (signed char)ulOperand; - hr = S_OK; - } - - return hr; -} - -// -// ULONG -> UCHAR conversion -// -__inline -HRESULT -ULongToUChar( - IN ULONG ulOperand, - OUT unsigned char* pch) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *pch = 0; - - if (ulOperand <= 255) - { - *pch = (unsigned char)ulOperand; - hr = S_OK; - } - - return hr; -} - -// -// __inline is not sufficient. __forceinline is necessary. -// If the function is not inlined and you link .objs compiled with different compiler switches, -// you get one or the other function arbitrarily chosen. -// -// ULONG -> CHAR conversion -// -__forceinline -HRESULT -ULongToChar( - IN ULONG ulOperand, - OUT CHAR* pch) -{ -#ifdef _CHAR_UNSIGNED - return ULongToUChar(ulOperand, (unsigned char*)pch); -#else - return ULongToSignedChar(ulOperand, (signed char*)pch); -#endif // _CHAR_UNSIGNED -} - -// -// ULONG -> USHORT conversion -// -__inline -HRESULT -ULongToUShort( - IN ULONG ulOperand, - OUT USHORT* pusResult) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *pusResult = USHORT_ERROR; - - if (ulOperand <= USHRT_MAX) - { - *pusResult = (USHORT)ulOperand; - hr = S_OK; - } - - return hr; -} - -// -// ULONG -> INT conversion -// -__inline -HRESULT -ULongToInt( - IN ULONG ulOperand, - OUT INT* piResult) -{ - if (ulOperand <= INT_MAX) - { - *piResult = (INT)ulOperand; - return S_OK; - } - else - { - *piResult = INT_ERROR; - return INTSAFE_E_ARITHMETIC_OVERFLOW; - } -} - -// -// ULONG -> UINT conversion -// -__inline -HRESULT -ULongToUInt( - IN ULONG ulOperand, - OUT UINT* puResult) -{ - *puResult = (UINT)ulOperand; - - return S_OK; -} - -// -// ULONG -> LONG conversion -// -__inline -HRESULT -ULongToLong( - IN ULONG Operand, - OUT LONG* Result) -{ - if (Operand <= _I32_MAX) - { - *Result = (LONG)Operand; - return S_OK; - } - else - { - *Result = LONG_ERROR; - return INTSAFE_E_ARITHMETIC_OVERFLOW; - } -} - -// -// ULONGLONG -> INT conversion -// -__inline -HRESULT -ULongLongToInt( - IN ULONGLONG ullOperand, - OUT INT* piResult) -{ - if (ullOperand <= INT_MAX) - { - *piResult = (INT)ullOperand; - return S_OK; - } - else - { - *piResult = INT_ERROR; - return INTSAFE_E_ARITHMETIC_OVERFLOW; - } -} - -// -// ULONGLONG -> LONG conversion -// -__inline -HRESULT -ULongLongToLong( - IN ULONGLONG Operand, - OUT LONG* Result) -{ - if (Operand <= _I32_MAX) - { - *Result = (LONG)Operand; - return S_OK; - } - else - { - *Result = LONG_ERROR; - return INTSAFE_E_ARITHMETIC_OVERFLOW; - } -} - -// -// UINT -> USHORT conversion -// -__inline -HRESULT -UIntToUShort( - IN UINT uOperand, - OUT USHORT* pusResult) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *pusResult = USHORT_ERROR; - - if (uOperand <= USHRT_MAX) - { - *pusResult = (USHORT)uOperand; - hr = S_OK; - } - - return hr; -} - -// -// ULONGLONG -> USHORT conversion -// -__inline -HRESULT -ULongLongToUShort( - IN ULONGLONG ullOperand, - OUT USHORT* pusResult) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - USHORT usResult = USHORT_ERROR; - - if (ullOperand <= USHRT_MAX) - { - usResult = (USHORT)ullOperand; - hr = S_OK; - } - *pusResult = usResult; - - return hr; -} - -// -// ULONGLONG -> ULONG conversion -// -__inline -HRESULT -ULongLongToULong( - IN ULONGLONG ullOperand, - OUT ULONG* pulResult) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *pulResult = ULONG_ERROR; - - if (ullOperand <= _UI32_MAX) - { - *pulResult = (ULONG)ullOperand; - hr = S_OK; - } - - return hr; -} - -// -// UINT_PTR -> ULONG conversion -// ULONG_PTR -> ULONG conversion -// -#ifdef HOST_64BIT - -#define UIntPtrToULong ULongLongToULong -#define ULongPtrToULong ULongLongToULong - -#else - -__inline -HRESULT -UIntPtrToULong( - IN UINT_PTR Operand, - OUT ULONG* pResult) -{ - *pResult = (ULONG)Operand; - return S_OK; -} - -__inline -HRESULT -ULongPtrToULong( - IN ULONG_PTR Operand, - OUT ULONG* pResult) -{ - *pResult = (ULONG)Operand; - return S_OK; -} - -#endif - -// -// ULONGLONG -> UINT conversion -// -__inline -HRESULT -ULongLongToUInt( - IN ULONGLONG ullOperand, - OUT UINT* puResult) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *puResult = UINT_ERROR; - - if (ullOperand <= UINT_MAX) - { - *puResult = (UINT)ullOperand; - hr = S_OK; - } - - return hr; -} - -// -// UINT_PTR -> UINT conversion -// ULONG_PTR -> UINT conversion -// -#ifdef HOST_64BIT - -#define UIntPtrToUInt ULongLongToUInt -#define ULongPtrToUInt ULongLongToUInt - -#else - -__inline -HRESULT -UIntPtrToUInt( - IN UINT_PTR Operand, - OUT UINT* pResult) -{ - *pResult = (UINT)Operand; - return S_OK; -} - -__inline -HRESULT -ULongPtrToUInt( - IN ULONG_PTR Operand, - OUT UINT* pResult) -{ - *pResult = (UINT)Operand; - return S_OK; -} - -#endif - -// -// * -> BYTE conversion (BYTE is always unsigned char) -// -#define IntToByte IntToUChar -#define UIntToByte UIntToUChar -#define LongToByte LongToUChar -#define ULongToByte ULongToUChar - -// -// * -> WORD conversion (WORD is always unsigned short) -// -#define IntToWord IntToUShort -#define LongToWord LongToUShort -#define LongLongToWord LongLongToUShort -#define UIntToWord UIntToUShort -#define ULongToWord ULongToUShort -#define ULongLongToWord ULongLongToUShort -#define UIntPtrToWord UIntPtrToUShort -#define ULongPtrToWord ULongPtrToUShort -#define SizeTToWord SizeTToUShort -#define SIZETToWord SIZETToUShort - -// -// WORD -> * conversion (WORD is always unsigned short) -// -#define WordToUChar UShortToUChar -#define WordToByte UShortToByte -#define WordToChar UShortToChar -#define WordToSignedChar UShortToSignedChar -#define WordToInt UShortToInt -#define WordToLong UShortToLong -#define WordToLongLong UShortToLongLong -#define WordToIntPtr UShortToIntPtr -#define WordToLongPtr UShortToLongPtr - -// -// * -> DWORD conversion (DWORD is always ULONG) -// -#define CharToDWord CharToULong -#define SignedCharToDWord SignedCharToULong -#define ShortToDWord ShortToULong -#define IntToDWord IntToULong -#define LongToDWord LongToULong -#define LongLongToDWord LongLongToULong -#define UIntToDWord UIntToULong -#define ULongLongToDWord ULongLongToULong -#define IntPtrToDWord IntPtrToULong -#define LongPtrToDWord LongPtrToULong -#define UIntPtrToDWord UIntPtrToULong -#define ULongPtrToDWord ULongPtrToULong -#define SizeTToDWord SizeTToULong -#define SIZETToDWord SIZETToULong - -// -// DWORD -> * conversion (DWORD is always ULONG) -// -#define DWordToChar ULongToChar -#define DWordToUChar ULongToUChar -#define DWordToByte ULongToByte -#define DWordToSignedChar ULongToSignedChar -#define DWordToUShort ULongToUShort -#define DWordToUInt ULongToUInt -#define DWordToInt ULongToInt -#define DWordToLong ULongToLong -#define DWordToLongLong ULongToLongLong -#define DWordToIntPtr ULongToIntPtr -#define DWordToLongPtr ULongToLongPtr - - -// -// * -> UINT_PTR conversion (UINT_PTR is UINT on Win32, ULONGLONG on Win64) -// -#ifdef HOST_64BIT -#define CharToUIntPtr CharToULongLong -#define SignedCharToUIntPtr SignedCharToULongLong -#define ShortToUIntPtr ShortToULongLong -#define IntToUIntPtr IntToULongLong -#define LongToUIntPtr LongToULongLong -#define LongLongToUIntPtr LongLongToULongLong -#define IntPtrToUIntPtr IntPtrToULongLong -#define LongPtrToUIntPtr LongPtrToULongLong -#else -#define CharToUIntPtr CharToUInt -#define SignedCharToUIntPtr SignedCharToUInt -#define ShortToUIntPtr ShortToUInt - -__inline -HRESULT -IntToUIntPtr( - IN INT iOperand, - OUT UINT_PTR* puResult) -{ - return IntToUInt(iOperand, (UINT*)puResult); -} - -#define LongToUIntPtr LongToUInt -#define LongLongToUIntPtr LongLongToUInt - -#define IntPtrToUIntPtr IntPtrToUInt -#define LongPtrToUIntPtr LongPtrToUInt -#endif - -__inline -HRESULT -ULongLongToUIntPtr( - IN ULONGLONG ullOperand, - OUT UINT_PTR* puResult) -{ -#ifdef HOST_64BIT - *puResult = ullOperand; - return S_OK; -#else - return ULongLongToUInt(ullOperand, (UINT*)puResult); -#endif -} - - -// -// UINT_PTR -> * conversion (UINT_PTR is UINT on Win32, ULONGLONG on Win64) -// -#ifdef HOST_64BIT -#define UIntPtrToUShort ULongLongToUShort -#define UIntPtrToInt ULongLongToInt -#define UIntPtrToLong ULongLongToLong -#define UIntPtrToLongLong ULongLongToLongLong -#define UIntPtrToIntPtr ULongLongToIntPtr -#define UIntPtrToLongPtr ULongLongToLongPtr -#else - -__inline -HRESULT -UIntPtrToUShort( - IN UINT_PTR uOperand, - OUT USHORT* pusResult) -{ - return UIntToUShort((UINT)uOperand, pusResult); -} - -__inline -HRESULT -UIntPtrToInt( - IN UINT_PTR uOperand, - OUT INT* piResult) -{ - return UIntToInt((UINT)uOperand, piResult); -} - -__inline -HRESULT -UIntPtrToLong( - IN UINT_PTR Operand, - OUT LONG* Result) -{ - return UIntToLong((UINT)Operand, Result); -} - -#define UIntPtrToLongLong UIntToLongLong -#define UIntPtrToIntPtr UIntToIntPtr -#define UIntPtrToLongPtr UIntToLongPtr -#endif - - -// -// * -> ULONG_PTR conversion (ULONG_PTR is ULONG on Win32, ULONGLONG on Win64) -// -#ifdef HOST_64BIT -#define CharToULongPtr CharToULongLong -#define SignedCharToULongPtr SignedCharToULongLong -#define ShortToULongPtr ShortToULongLong -#define IntToULongPtr IntToULongLong -#define LongToULongPtr LongToULongLong -#define LongLongToULongPtr LongLongToULongLong -#define IntPtrToULongPtr IntPtrToULongLong -#define LongPtrToULongPtr LongPtrToULongLong -#else -#define CharToULongPtr CharToULong -#define SignedCharToULongPtr SignedCharToULong -#define ShortToULongPtr ShortToULong - -__inline -HRESULT -IntToULongPtr( - IN INT iOperand, - OUT ULONG_PTR* pulResult) -{ - return IntToULong(iOperand, (ULONG*)pulResult); -} - -#define LongToULongPtr LongToULong -#define LongLongToULongPtr LongLongToULong - -#define IntPtrToULongPtr IntPtrToULong -#define LongPtrToULongPtr LongPtrToULong -#endif - -__inline -HRESULT -ULongLongToULongPtr( - IN ULONGLONG ullOperand, - OUT ULONG_PTR* pulResult) -{ -#ifdef HOST_64BIT - *pulResult = ullOperand; - return S_OK; -#else - return ULongLongToULong(ullOperand, (ULONG*)pulResult); -#endif -} - - -// -// ULONG_PTR -> * conversion (ULONG_PTR is ULONG on Win32, ULONGLONG on Win64) -// -#ifdef HOST_64BIT -#define ULongPtrToUShort ULongLongToUShort -#define ULongPtrToInt ULongLongToInt -#define ULongPtrToLong ULongLongToLong -#define ULongPtrToLongLong ULongLongToLongLong -#define ULongPtrToIntPtr ULongLongToIntPtr -#define ULongPtrToLongPtr ULongLongToLongPtr -#else - -__inline -HRESULT -ULongPtrToUShort( - IN ULONG_PTR ulOperand, - OUT USHORT* pusResult) -{ - return ULongToUShort((ULONG)ulOperand, pusResult); -} - -__inline -HRESULT -ULongPtrToInt( - IN ULONG_PTR ulOperand, - OUT INT* piResult) -{ - return ULongToInt((ULONG)ulOperand, piResult); -} - -__inline -HRESULT -ULongPtrToLong( - IN ULONG_PTR Operand, - OUT LONG* Result) -{ - return ULongToLong((ULONG)Operand, Result); -} - -#define ULongPtrToLongLong ULongToLongLong -#define ULongPtrToIntPtr ULongToIntPtr -#define ULongPtrToLongPtr ULongToLongPtr -#endif - -// -// * -> size_t conversion (size_t is always UINT_PTR) -// -#define CharToSizeT CharToUIntPtr -#define SignedCharToSizeT SignedCharToUIntPtr -#define ShortToSizeT ShortToUIntPtr -#define IntToSizeT IntToUIntPtr -#define LongToSizeT LongToUIntPtr -#define LongLongToSizeT LongLongToUIntPtr -#define ULongLongToSizeT ULongLongToUIntPtr -#define IntPtrToSizeT IntPtrToUIntPtr -#define LongPtrToSizeT LongPtrToUIntPtr - -// -// size_t -> * conversion (size_t is always UINT_PTR) -// -#define SizeTToUShort UIntPtrToUShort -#define SizeTToUInt UIntPtrToUInt -#define SizeTToULong UIntPtrToULong -#define SizeTToInt UIntPtrToInt -#define SizeTToLong UIntPtrToLong -#define SizeTToLongLong UIntPtrToLongLong -#define SizeTToIntPtr UIntPtrToIntPtr -#define SizeTToLongPtr UIntPtrToLongPtr - -// -// * -> SIZE_T conversion (SIZE_T is always ULONG_PTR) -// -#define CharToSIZET CharToULongPtr -#define SignedCharToSIZET SignedCharToULongPtr -#define ShortToSIZET ShortToULongPtr -#define IntToSIZET IntToULongPtr -#define LongToSIZET LongToULongPtr -#define LongLongToSIZET LongLongToULongPtr -#define IntPtrToSIZET IntPtrToULongPtr -#define LongPtrToSIZET LongPtrToULongPtr -#define ULongLongToSIZET ULongLongToULongPtr - -// -// SIZE_T -> * conversion (SIZE_T is always ULONG_PTR) -// -#define SIZETToUShort ULongPtrToUShort -#define SIZETToUInt ULongPtrToUInt -#define SIZETToULong ULongPtrToULong -#define SIZETToUIntPtr ULongPtrToUIntPtr -#define SIZETToULongPtr ULongPtrToULongPtr -#define SIZETToInt ULongPtrToInt -#define SIZETToLong ULongPtrToLong -#define SIZETToLongLong ULongPtrToLongLong -#define SIZETToIntPtr ULongPtrToIntPtr -#define SIZETToLongPtr ULongPtrToLongPtr - -// -// * -> DWORD_PTR conversion (DWORD_PTR is always ULONG_PTR) -// -#define CharToDWordPtr CharToULongPtr -#define SignedCharToDWordPtr SignedCharToULongPtr -#define ShortToDWordPtr ShortToULongPtr -#define IntToDWordPtr IntToULongPtr -#define LongToDWordPtr LongToULongPtr -#define LongLongToDWordPtr LongLongToULongPtr -#define ULongLongToDWordPtr ULongLongToULongPtr -#define IntPtrToDWordPtr IntPtrToULongPtr -#define LongPtrToDWordPtr LongPtrToULongPtr - -// -// DWORD_PTR -> * conversion (DWORD_PTR is always ULONG_PTR) -// -#define DWordPtrToUShort ULongPtrToUShort -#define DWordPtrToUInt ULongPtrToUInt -#define DWordPtrToULong ULongPtrToULong -#define DWordPtrToDWord ULongPtrToDWord -#define DWordPtrToInt ULongPtrToInt -#define DWordPtrToLong ULongPtrToLong -#define DWordPtrToLongLong ULongPtrToLongLong -#define DWordPtrToIntPtr ULongPtrToIntPtr -#define DWordPtrToLongPtr ULongPtrToLongPtr - -// -// USHORT addition -// -__inline -HRESULT -UShortAdd( - IN USHORT usAugend, - IN USHORT usAddend, - OUT USHORT* pusResult) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *pusResult = USHORT_ERROR; - - if (((USHORT)(usAugend + usAddend)) >= usAugend) - { - *pusResult = (usAugend + usAddend); - hr = S_OK; - } - - return hr; -} - -// -// WORD addtition -// -#define WordAdd UShortAdd - -// -// UINT addition -// -__inline -HRESULT -UIntAdd( - IN UINT uAugend, - IN UINT uAddend, - OUT UINT* puResult) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *puResult = UINT_ERROR; - - if ((uAugend + uAddend) >= uAugend) - { - *puResult = (uAugend + uAddend); - hr = S_OK; - } - - return hr; -} - -// -// UINT_PTR addition -// -#define UIntPtrAdd SizeTAdd - -// -// ULONG addition -// -__inline -HRESULT -ULongAdd( - IN ULONG ulAugend, - IN ULONG ulAddend, - OUT ULONG* pulResult) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *pulResult = ULONG_ERROR; - - if ((ulAugend + ulAddend) >= ulAugend) - { - *pulResult = (ulAugend + ulAddend); - hr = S_OK; - } - - return hr; -} - -// -// ULONG_PTR addition -// -#ifdef HOST_64BIT -#define ULongPtrAdd ULongLongAdd -#else -__inline -HRESULT -ULongPtrAdd( - IN ULONG_PTR ulAugend, - IN ULONG_PTR ulAddend, - OUT ULONG_PTR* pulResult) -{ - return ULongAdd((ULONG)ulAugend, (ULONG)ulAddend, (ULONG*)pulResult); -} -#endif // HOST_64BIT - -// -// DWORD addition -// -#define DWordAdd ULongAdd - -// -// DWORD_PTR addition -// -#define DWordPtrAdd ULongPtrAdd - -// -// size_t addition -// -__inline -HRESULT -SizeTAdd( - IN size_t Augend, - IN size_t Addend, - OUT size_t* pResult) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *pResult = SIZET_ERROR; - - if ((Augend + Addend) >= Augend) - { - *pResult = (Augend + Addend); - hr = S_OK; - } - - return hr; -} - -// -// SIZE_T addition -// -#define SIZETAdd ULongPtrAdd - -// -// ULONGLONG addition -// -__inline -HRESULT -ULongLongAdd( - IN ULONGLONG ullAugend, - IN ULONGLONG ullAddend, - OUT ULONGLONG* pullResult) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *pullResult = ULONGLONG_ERROR; - - if ((ullAugend + ullAddend) >= ullAugend) - { - *pullResult = (ullAugend + ullAddend); - hr = S_OK; - } - - return hr; -} - -// -// USHORT subtraction -// -__inline -HRESULT -UShortSub( - IN USHORT usMinuend, - IN USHORT usSubtrahend, - OUT USHORT* pusResult) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *pusResult = USHORT_ERROR; - - if (usMinuend >= usSubtrahend) - { - *pusResult = (usMinuend - usSubtrahend); - hr = S_OK; - } - - return hr; -} - -// -// WORD subtraction -// -#define WordSub UShortSub - - -// -// UINT subtraction -// -__inline -HRESULT -UIntSub( - IN UINT uMinuend, - IN UINT uSubtrahend, - OUT UINT* puResult) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *puResult = UINT_ERROR; - - if (uMinuend >= uSubtrahend) - { - *puResult = (uMinuend - uSubtrahend); - hr = S_OK; - } - - return hr; -} - -// -// UINT_PTR subtraction -// -#define UIntPtrSub SizeTSub - -// -// ULONG subtraction -// -__inline -HRESULT -ULongSub( - IN ULONG ulMinuend, - IN ULONG ulSubtrahend, - OUT ULONG* pulResult) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *pulResult = ULONG_ERROR; - - if (ulMinuend >= ulSubtrahend) - { - *pulResult = (ulMinuend - ulSubtrahend); - hr = S_OK; - } - - return hr; -} - -// -// ULONG_PTR subtraction -// -#ifdef HOST_64BIT -#define ULongPtrSub ULongLongSub -#else -__inline -HRESULT -ULongPtrSub( - IN ULONG_PTR ulMinuend, - IN ULONG_PTR ulSubtrahend, - OUT ULONG_PTR* pulResult) -{ - return ULongSub((ULONG)ulMinuend, (ULONG)ulSubtrahend, (ULONG*)pulResult); -} -#endif // HOST_64BIT - - -// -// DWORD subtraction -// -#define DWordSub ULongSub - -// -// DWORD_PTR subtraction -// -#define DWordPtrSub ULongPtrSub - -// -// size_t subtraction -// -__inline -HRESULT -SizeTSub( - IN size_t Minuend, - IN size_t Subtrahend, - OUT size_t* pResult) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *pResult = SIZET_ERROR; - - if (Minuend >= Subtrahend) - { - *pResult = (Minuend - Subtrahend); - hr = S_OK; - } - - return hr; -} - -// -// SIZE_T subtraction -// -#define SIZETSub ULongPtrSub - -// -// ULONGLONG subtraction -// -__inline -HRESULT -ULongLongSub( - IN ULONGLONG ullMinuend, - IN ULONGLONG ullSubtrahend, - OUT ULONGLONG* pullResult) -{ - HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW; - *pullResult = ULONGLONG_ERROR; - - if (ullMinuend >= ullSubtrahend) - { - *pullResult = (ullMinuend - ullSubtrahend); - hr = S_OK; - } - - return hr; -} - -// -// USHORT multiplication -// -__inline -HRESULT -UShortMult( - IN USHORT usMultiplicand, - IN USHORT usMultiplier, - OUT USHORT* pusResult) -{ - ULONG ulResult = ((ULONG)usMultiplicand) * (ULONG)usMultiplier; - - return ULongToUShort(ulResult, pusResult); -} - -// -// WORD multiplication -// -#define WordMult UShortMult - -// -// UINT multiplication -// -__inline -HRESULT -UIntMult( - IN UINT uMultiplicand, - IN UINT uMultiplier, - OUT UINT* puResult) -{ - ULONGLONG ull64Result = UInt32x32To64(uMultiplicand, uMultiplier); - - return ULongLongToUInt(ull64Result, puResult); -} - -// -// ULONG multiplication -// -__inline -HRESULT -ULongMult( - IN ULONG ulMultiplicand, - IN ULONG ulMultiplier, - OUT ULONG* pulResult) -{ - ULONGLONG ull64Result = UInt32x32To64(ulMultiplicand, ulMultiplier); - - return ULongLongToULong(ull64Result, pulResult); -} - -// -// DWORD multiplication -// -#define DWordMult ULongMult - -// -// DWORD_PTR multiplication -// -#define DWordPtrMult ULongPtrMult - -#endif // _INTSAFE_H_INCLUDED_ diff --git a/src/coreclr/vm/classlayoutinfo.cpp b/src/coreclr/vm/classlayoutinfo.cpp index c89488a2427f15..14e75f52e3f58f 100644 --- a/src/coreclr/vm/classlayoutinfo.cpp +++ b/src/coreclr/vm/classlayoutinfo.cpp @@ -56,7 +56,7 @@ namespace pfwalk->m_sequence = (ULONG)-1; // Treat base class as an initial member. - if (!SafeAddUINT32(&(pfwalk->m_placement.m_offset), cbAdjustedParentLayoutNativeSize)) + if (!ClrSafeInt::addition(pfwalk->m_placement.m_offset, cbAdjustedParentLayoutNativeSize, pfwalk->m_placement.m_offset)) COMPlusThrowOM(); } } @@ -172,7 +172,7 @@ namespace // Insert enough padding to align the current data member. while (cbCurOffset % alignmentRequirement) { - if (!SafeAddUINT32(&cbCurOffset, 1)) + if (!ClrSafeInt::addition(cbCurOffset, 1, cbCurOffset)) COMPlusThrowOM(); } @@ -192,8 +192,8 @@ namespace if (classSizeInMetadata != 0) { - ULONG classSize = classSizeInMetadata; - if (!SafeAddULONG(&classSize, (ULONG)parentSize)) + ULONG classSize; + if (!ClrSafeInt::addition(classSizeInMetadata, (ULONG)parentSize, classSize)) COMPlusThrowOM(); // size must be large enough to accomodate layout. If not, we use the layout size instead. @@ -207,7 +207,7 @@ namespace if (calcTotalSize % LargestAlignmentRequirement != 0) { - if (!SafeAddUINT32(&calcTotalSize, LargestAlignmentRequirement - (calcTotalSize % LargestAlignmentRequirement))) + if (!ClrSafeInt::addition(calcTotalSize, LargestAlignmentRequirement - (calcTotalSize % LargestAlignmentRequirement), calcTotalSize)) COMPlusThrowOM(); } } diff --git a/src/coreclr/vm/ilmarshalers.cpp b/src/coreclr/vm/ilmarshalers.cpp index 1a4f265999f13e..182a434c1e6b97 100644 --- a/src/coreclr/vm/ilmarshalers.cpp +++ b/src/coreclr/vm/ilmarshalers.cpp @@ -4344,8 +4344,8 @@ FCIMPL3(void, MngdNativeArrayMarshaler::ConvertSpaceToNative, MngdNativeArrayMar if (cbElement == 0) COMPlusThrow(kArgumentException, IDS_EE_COM_UNSUPPORTED_SIG); - SIZE_T cbArray = cElements; - if ( (!SafeMulSIZE_T(&cbArray, cbElement)) || cbArray > MAX_SIZE_FOR_INTEROP) + SIZE_T cbArray; + if ( (!ClrSafeInt::multiply(cElements, cbElement, cbArray)) || cbArray > MAX_SIZE_FOR_INTEROP) COMPlusThrow(kArgumentException, IDS_EE_STRUCTARRAYTOOLARGE); *pNativeHome = CoTaskMemAlloc(cbArray); @@ -4374,7 +4374,7 @@ FCIMPL3(void, MngdNativeArrayMarshaler::ConvertContentsToNative, MngdNativeArray SIZE_T cElements = (*pArrayRef)->GetNumComponents(); if (pMarshaler == NULL || pMarshaler->ComToOleArray == NULL) { - if ( (!SafeMulSIZE_T(&cElements, OleVariant::GetElementSizeForVarType(pThis->m_vt, pThis->m_pElementMT))) || cElements > MAX_SIZE_FOR_INTEROP) + if ( (!ClrSafeInt::multiply(cElements, OleVariant::GetElementSizeForVarType(pThis->m_vt, pThis->m_pElementMT), cElements)) || cElements > MAX_SIZE_FOR_INTEROP) COMPlusThrow(kArgumentException, IDS_EE_STRUCTARRAYTOOLARGE); _ASSERTE(!GetTypeHandleForCVType(OleVariant::GetCVTypeForVarType(pThis->m_vt)).GetMethodTable()->ContainsPointers()); @@ -4434,8 +4434,8 @@ FCIMPL3(void, MngdNativeArrayMarshaler::ConvertContentsToManaged, MngdNativeArra if (pMarshaler == NULL || pMarshaler->OleToComArray == NULL) { - SIZE_T cElements = (*pArrayRef)->GetNumComponents(); - if ( (!SafeMulSIZE_T(&cElements, OleVariant::GetElementSizeForVarType(pThis->m_vt, pThis->m_pElementMT))) || cElements > MAX_SIZE_FOR_INTEROP) + SIZE_T cElements; + if ( (!ClrSafeInt::multiply((*pArrayRef)->GetNumComponents(), OleVariant::GetElementSizeForVarType(pThis->m_vt, pThis->m_pElementMT), cElements)) || cElements > MAX_SIZE_FOR_INTEROP) COMPlusThrow(kArgumentException, IDS_EE_STRUCTARRAYTOOLARGE); // If we are copying variants, strings, etc, we need to use write barrier diff --git a/src/coreclr/vm/util.hpp b/src/coreclr/vm/util.hpp index 920e29bdc3dd18..949f9bd6559d3f 100644 --- a/src/coreclr/vm/util.hpp +++ b/src/coreclr/vm/util.hpp @@ -122,98 +122,6 @@ BOOL inline FitsInU4(unsigned __int64 val) return val == (unsigned __int64)(unsigned __int32)val; } -// returns FALSE if overflows 15 bits: otherwise, (*pa) is incremented by b -BOOL inline SafeAddUINT15(UINT16 *pa, ULONG b) -{ - LIMITED_METHOD_CONTRACT; - - UINT16 a = *pa; - // first check if overflows 16 bits - if ( ((UINT16)b) != b ) - { - return FALSE; - } - // now make sure that doesn't overflow 15 bits - if (((ULONG)a + b) > 0x00007FFF) - { - return FALSE; - } - (*pa) += (UINT16)b; - return TRUE; -} - - -// returns FALSE if overflows 16 bits: otherwise, (*pa) is incremented by b -BOOL inline SafeAddUINT16(UINT16 *pa, ULONG b) -{ - UINT16 a = *pa; - if ( ((UINT16)b) != b ) - { - return FALSE; - } - // now make sure that doesn't overflow 16 bits - if (((ULONG)a + b) > 0x0000FFFF) - { - return FALSE; - } - (*pa) += (UINT16)b; - return TRUE; -} - - -// returns FALSE if overflow: otherwise, (*pa) is incremented by b -BOOL inline SafeAddUINT32(UINT32 *pa, UINT32 b) -{ - LIMITED_METHOD_CONTRACT; - - UINT32 a = *pa; - if ( ((UINT32)(a + b)) < a) - { - return FALSE; - } - (*pa) += b; - return TRUE; -} - -// returns FALSE if overflow: otherwise, (*pa) is incremented by b -BOOL inline SafeAddULONG(ULONG *pa, ULONG b) -{ - LIMITED_METHOD_CONTRACT; - - ULONG a = *pa; - if ( ((ULONG)(a + b)) < a) - { - return FALSE; - } - (*pa) += b; - return TRUE; -} - -// returns FALSE if overflow: otherwise, (*pa) is multiplied by b -BOOL inline SafeMulSIZE_T(SIZE_T *pa, SIZE_T b) -{ - LIMITED_METHOD_CONTRACT; - -#ifdef _DEBUG_IMPL - { - //Make sure SIZE_T is unsigned - SIZE_T m = ((SIZE_T)(-1)); - SIZE_T z = 0; - _ASSERTE(m > z); - } -#endif - - - SIZE_T a = *pa; - const SIZE_T m = ((SIZE_T)(-1)); - if ( (m / b) < a ) - { - return FALSE; - } - (*pa) *= b; - return TRUE; -} - //************************************************************************ From 5c5e66e6c067f8a82d514598575011cd21655ffb Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Sun, 12 Jun 2022 00:25:20 -0700 Subject: [PATCH 066/337] Investigate helix error return (#70238) --- eng/testing/xunit/xunit.console.targets | 5 +++++ .../SingleFileTestRunner/SingleFileTestRunner.cs | 15 ++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/eng/testing/xunit/xunit.console.targets b/eng/testing/xunit/xunit.console.targets index 77d7363a22f4ee..75d73d1037442d 100644 --- a/eng/testing/xunit/xunit.console.targets +++ b/eng/testing/xunit/xunit.console.targets @@ -36,6 +36,11 @@ $(_withoutCategories.Replace(';', '%0dcategory=')) + + + $(RunScriptCommand) -xml $(TestResultsName) + + > noTraits = new Dictionary>(); for (int i = 0; i < args.Length; i++) { @@ -72,6 +75,10 @@ public static int Main(string[] args) } values.Add(traitKeyValue[1]); } + if (args[i].Equals("-xml", StringComparison.OrdinalIgnoreCase)) + { + xmlResultFileName=args[i + 1].Trim(); + } } foreach (KeyValuePair> kvp in noTraits) @@ -85,6 +92,12 @@ public static int Main(string[] args) resultsSink.Finished.WaitOne(); + // Helix need to see results file in the drive to detect if the test has failed or not + if(xmlResultFileName != null) + { + resultsXmlAssembly.Save(xmlResultFileName); + } + var failed = resultsSink.ExecutionSummary.Failed > 0 || resultsSink.ExecutionSummary.Errors > 0; return failed ? 1 : 0; } From b15ffe57b9a1c4e8aaa2f49125efeace697fa9fb Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Sun, 12 Jun 2022 09:03:56 -0700 Subject: [PATCH 067/337] Fold System.Private.Reflection.Core into CoreLib (#70545) --- src/coreclr/dlls/mscorrc/mscorrc.rc | 1 - src/coreclr/dlls/mscorrc/resource.h | 1 - .../Microsoft.NETCore.Native.targets | 6 +- .../DeveloperExperienceModeOnlyAttribute.cs | 46 --- .../DeveloperExperienceState.cs | 1 - .../src/ILLink/ILLink.Substitutions.xml | 3 + .../Reflection/Core/AssemblyBinder.cs | 5 + .../Core/Execution/ExecutionDomain.cs | 17 +- .../Core/Execution/ExecutionEnvironment.cs | 3 + .../Core/Execution/FieldAccessor.cs | 3 + .../Core/Execution/MethodInvoker.cs | 8 +- .../Core/Execution/ReflectionCoreExecution.cs | 3 + .../Reflection/Core/ReflectionDomainSetup.cs | 7 +- .../Runtime/Augments/TypeLoaderCallbacks.cs | 5 + .../src/System.Private.CoreLib.csproj | 149 ++++++- .../src/System/ActivatorImplementation.cs | 10 +- .../src/System/Helpers.cs | 27 -- ...imeAssembly.GetTypeCore.CaseInsensitive.cs | 0 ...ntimeAssembly.GetTypeCore.CaseSensitive.cs | 0 .../NativeFormatRuntimeAssembly.cs | 4 +- .../Runtime/Assemblies/RuntimeAssemblyInfo.cs | 12 +- .../BindingFlagSupport/ConstructorPolicies.cs | 4 +- .../BindingFlagSupport/EventPolicies.cs | 28 +- .../BindingFlagSupport/FieldPolicies.cs | 2 +- .../BindingFlagSupport/MemberPolicies.cs | 2 +- .../BindingFlagSupport/MemberTypeIndex.cs | 0 .../BindingFlagSupport/MethodPolicies.cs | 6 +- .../NameFilter.NativeFormat.cs | 0 .../Runtime/BindingFlagSupport/NameFilter.cs | 0 .../BindingFlagSupport/NestedTypePolicies.cs | 2 +- .../BindingFlagSupport/PropertyPolicies.cs | 18 +- .../BindingFlagSupport/QueriedMemberList.cs | 2 +- .../QueryResult.Enumerator.cs | 0 .../Runtime/BindingFlagSupport/QueryResult.cs | 4 +- .../Runtime/BindingFlagSupport/Shared.cs | 4 +- .../NativeFormatCustomAttributeData.cs | 18 +- .../RuntimeCustomAttributeData.cs | 10 +- .../RuntimePseudoCustomAttributeData.cs | 0 .../Dispensers/DefaultDispenserPolicy.cs | 0 .../Runtime/Dispensers/Dispenser.cs | 0 .../Runtime/Dispensers/DispenserAlgorithm.cs | 0 .../Runtime/Dispensers/DispenserFactory.cs | 0 .../Runtime/Dispensers/DispenserPolicy.cs | 0 .../Runtime/Dispensers/DispenserScenario.cs | 0 .../Dispensers/DispenserThatAlwaysCreates.cs | 0 .../Dispensers/DispenserThatAlwaysReuses.cs | 0 .../DispenserThatReusesAsLongAsKeyIsAlive.cs | 0 ...nserThatReusesAsLongAsKeyedValueIsAlive.cs | 0 ...DispenserThatReusesAsLongAsValueIsAlive.cs | 0 .../NativeFormatRuntimeEventInfo.cs | 0 .../Runtime/EventInfos/RuntimeEventInfo.cs | 0 .../NativeFormatRuntimeFieldInfo.cs | 6 +- .../Runtime/FieldInfos/RuntimeFieldInfo.cs | 0 .../Runtime/General/Assignability.cs | 18 +- .../BlockedRuntimeTypeNameGenerator.cs | 0 .../General/Dispensers.NativeFormat.cs | 2 +- .../Reflection/Runtime/General/Dispensers.cs | 6 +- .../Runtime/General/Helpers.NativeFormat.cs | 0 .../Reflection/Runtime/General/Helpers.cs | 12 +- ...ntimeMemberInfoWithNoMetadataDefinition.cs | 0 .../General/LegacyCustomAttributeApis.cs | 0 .../Reflection/Runtime/General/ListBuilder.cs | 0 .../MetadataReaderExtensions.NativeFormat.cs | 33 +- .../General}/MetadataReaderExtensions.cs | 11 +- .../Runtime/General/NamespaceChain.cs | 2 +- .../NativeFormat/DefaultValueParser.cs | 2 +- .../Runtime/General/QHandles.NativeFormat.cs | 1 - .../Reflection/Runtime/General/QHandles.cs | 13 + .../QSignatureTypeHandle.NativeFormat.cs | 0 .../Runtime/General/QSignatureTypeHandle.cs | 15 +- .../ReflectionCoreCallbacksImplementation.cs | 4 +- .../Runtime/General/RuntimeTypeHandleKey.cs | 0 .../Reflection/Runtime/General/ThunkedApis.cs | 9 +- .../Runtime/General/ToStringUtils.cs | 2 +- .../Reflection/Runtime/General/TypeContext.cs | 0 .../Runtime/General/TypeForwardInfo.cs | 0 .../General/TypeResolver.NativeFormat.cs | 30 +- .../Runtime/General/TypeResolver.cs | 6 +- .../General/TypeUnifier.NativeFormat.cs | 0 .../Reflection/Runtime/General/TypeUnifier.cs | 2 +- .../MethodInfos/CustomMethodInvoker.cs | 2 +- .../MethodInfos/CustomMethodInvokerAction.cs | 0 .../CustomMethodMapper.Nullable.cs | 3 +- .../MethodInfos/CustomMethodMapper.String.cs | 0 .../Runtime/MethodInfos/CustomMethodMapper.cs | 6 +- .../MethodInfos/IRuntimeMethodCommon.cs | 0 .../Runtime/MethodInfos/InvokerOptions.cs | 0 .../NativeFormat/NativeFormatMethodCommon.cs | 8 +- .../Runtime/MethodInfos/OpenMethodInvoker.cs | 2 +- .../RuntimeClsIdNullaryConstructorInfo.cs | 4 +- .../RuntimeConstructedGenericMethodInfo.cs | 2 +- .../MethodInfos/RuntimeConstructorInfo.cs | 8 +- .../MethodInfos/RuntimeDummyMethodInfo.cs | 2 +- .../MethodInfos/RuntimeMethodHelpers.cs | 2 +- .../Runtime/MethodInfos/RuntimeMethodInfo.cs | 6 +- .../MethodInfos/RuntimeNamedMethodInfo.cs | 6 +- .../RuntimePlainConstructorInfo.cs | 4 +- .../RuntimeSyntheticConstructorInfo.cs | 6 +- .../MethodInfos/RuntimeSyntheticMethodInfo.cs | 4 +- .../Runtime/MethodInfos/SyntheticMethodId.cs | 0 .../VirtualRuntimeParameterInfoArray.cs | 0 .../NativeFormat/NativeFormatRuntimeModule.cs | 0 .../Runtime/Modules/RuntimeModule.cs | 2 - .../NativeFormatMethodParameterInfo.cs | 2 +- .../RuntimeFatMethodParameterInfo.cs | 0 .../RuntimeMethodParameterInfo.cs | 0 .../ParameterInfos/RuntimeParameterInfo.cs | 0 .../RuntimePropertyIndexParameterInfo.cs | 0 .../RuntimeSyntheticParameterInfo.cs | 2 +- .../RuntimeThinMethodParameterInfo.cs | 2 +- .../EcmaFormatRuntimePropertyInfo.cs | 0 .../NativeFormatRuntimePropertyInfo.cs | 2 +- .../PropertyInfos/RuntimePropertyInfo.cs | 8 +- ...veFormatRuntimeGenericParameterTypeInfo.cs | 2 +- ...ameterTypeInfoForMethods.UnificationKey.cs | 0 ...ntimeGenericParameterTypeInfoForMethods.cs | 0 ...arameterTypeInfoForTypes.UnificationKey.cs | 0 ...RuntimeGenericParameterTypeInfoForTypes.cs | 0 ...rmatRuntimeNamedTypeInfo.UnificationKey.cs | 0 .../NativeFormatRuntimeNamedTypeInfo.cs | 10 +- ...veFormatRuntimeTypeInfo.CoreGetDeclared.cs | 0 .../Runtime/TypeInfos/RuntimeArrayTypeInfo.cs | 0 .../TypeInfos/RuntimeBlockedTypeInfo.cs | 4 +- .../Runtime/TypeInfos/RuntimeByRefTypeInfo.cs | 0 .../RuntimeClsIdTypeInfo.UnificationKey.cs | 0 .../Runtime/TypeInfos/RuntimeClsIdTypeInfo.cs | 4 +- ...nstructedGenericTypeInfo.UnificationKey.cs | 0 .../RuntimeConstructedGenericTypeInfo.cs | 4 +- .../RuntimeGenericParameterTypeInfo.cs | 0 ...untimeHasElementTypeInfo.UnificationKey.cs | 0 .../TypeInfos/RuntimeHasElementTypeInfo.cs | 6 +- .../Runtime/TypeInfos/RuntimeNamedTypeInfo.cs | 10 +- .../RuntimeNoMetadataNamedTypeInfo.cs | 2 +- .../TypeInfos/RuntimePointerTypeInfo.cs | 0 .../RuntimeTypeDefinitionTypeInfo.cs | 0 .../TypeInfos/RuntimeTypeInfo.BindingFlags.cs | 0 .../RuntimeTypeInfo.CoreGetDeclared.cs | 10 +- .../TypeInfos/RuntimeTypeInfo.GetMember.cs | 19 +- .../TypeInfos/RuntimeTypeInfo.InvokeMember.cs | 49 ++- .../RuntimeTypeInfo.TypeComponentsCache.cs | 0 .../Runtime/TypeInfos/RuntimeTypeInfo.cs | 30 +- .../Runtime/TypeParsing/GetTypeOptions.cs | 0 .../Runtime/TypeParsing/TypeLexer.cs | 0 .../Runtime/TypeParsing/TypeName.cs | 2 +- .../Runtime/TypeParsing/TypeParser.cs | 2 +- .../src/System/Type.Internal.cs | 24 +- .../src/ILLink/ILLink.Substitutions.xml | 5 - .../src/Resources/Strings.resx | 369 ------------------ .../src/System.Private.Reflection.Core.csproj | 200 ---------- .../Runtime/General/NonOverriddenApis.cs | 217 ---------- .../MissingMetadataExceptionCreator.cs | 12 +- ...System.Private.Reflection.Execution.csproj | 1 - .../TypeLoader/TypeLoaderEnvironment.cs | 15 + .../src/System.Private.TypeLoader.csproj | 4 - src/coreclr/nativeaot/nativeaot.sln | 2 - src/coreclr/vm/typeparse.cpp | 2 +- .../src/Resources/Strings.resx | 38 +- .../src/System/DefaultBinder.cs | 7 +- .../src/System/Empty.cs | 7 +- .../System/Reflection/MethodInfo.Internal.cs | 7 +- .../Reflection/SignatureTypeExtensions.cs | 8 +- 161 files changed, 546 insertions(+), 1194 deletions(-) delete mode 100644 src/coreclr/nativeaot/Common/src/System/Runtime/CompilerServices/DeveloperExperienceModeOnlyAttribute.cs rename src/coreclr/nativeaot/{System.Private.TypeLoader => System.Private.CoreLib}/src/Internal/Reflection/Core/AssemblyBinder.cs (92%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/Internal/Reflection/Core/Execution/ExecutionDomain.cs (97%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/Internal/Reflection/Core/Execution/ExecutionEnvironment.cs (99%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/Internal/Reflection/Core/Execution/FieldAccessor.cs (92%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/Internal/Reflection/Core/Execution/MethodInvoker.cs (81%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/Internal/Reflection/Core/Execution/ReflectionCoreExecution.cs (95%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/Internal/Reflection/Core/ReflectionDomainSetup.cs (88%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/ActivatorImplementation.cs (94%) delete mode 100644 src/coreclr/nativeaot/System.Private.CoreLib/src/System/Helpers.cs rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.GetTypeCore.CaseInsensitive.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.GetTypeCore.CaseSensitive.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.cs (98%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/Assemblies/RuntimeAssemblyInfo.cs (97%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/BindingFlagSupport/ConstructorPolicies.cs (94%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/BindingFlagSupport/EventPolicies.cs (68%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/BindingFlagSupport/FieldPolicies.cs (95%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/BindingFlagSupport/MemberPolicies.cs (99%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/BindingFlagSupport/MemberTypeIndex.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/BindingFlagSupport/MethodPolicies.cs (93%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/BindingFlagSupport/NameFilter.NativeFormat.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/BindingFlagSupport/NameFilter.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/BindingFlagSupport/NestedTypePolicies.cs (97%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/BindingFlagSupport/PropertyPolicies.cs (86%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/BindingFlagSupport/QueriedMemberList.cs (99%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/BindingFlagSupport/QueryResult.Enumerator.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/BindingFlagSupport/QueryResult.cs (98%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/BindingFlagSupport/Shared.cs (98%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/CustomAttributes/NativeFormat/NativeFormatCustomAttributeData.cs (94%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/CustomAttributes/RuntimeCustomAttributeData.cs (97%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/CustomAttributes/RuntimePseudoCustomAttributeData.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/Dispensers/DefaultDispenserPolicy.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/Dispensers/Dispenser.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/Dispensers/DispenserAlgorithm.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/Dispensers/DispenserFactory.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/Dispensers/DispenserPolicy.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/Dispensers/DispenserScenario.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/Dispensers/DispenserThatAlwaysCreates.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/Dispensers/DispenserThatAlwaysReuses.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/Dispensers/DispenserThatReusesAsLongAsKeyIsAlive.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/Dispensers/DispenserThatReusesAsLongAsKeyedValueIsAlive.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/Dispensers/DispenserThatReusesAsLongAsValueIsAlive.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/EventInfos/NativeFormat/NativeFormatRuntimeEventInfo.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/EventInfos/RuntimeEventInfo.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/FieldInfos/NativeFormat/NativeFormatRuntimeFieldInfo.cs (97%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/FieldInfos/RuntimeFieldInfo.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/General/Assignability.cs (98%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/General/BlockedRuntimeTypeNameGenerator.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/General/Dispensers.NativeFormat.cs (99%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/General/Dispensers.cs (98%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/General/Helpers.NativeFormat.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/General/Helpers.cs (94%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/General/IRuntimeMemberInfoWithNoMetadataDefinition.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/General/LegacyCustomAttributeApis.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/General/ListBuilder.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/General/MetadataReaderExtensions.NativeFormat.cs (97%) rename src/coreclr/nativeaot/{System.Private.TypeLoader/src/Internal/Runtime/TypeLoader => System.Private.CoreLib/src/System/Reflection/Runtime/General}/MetadataReaderExtensions.cs (96%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/General/NamespaceChain.cs (97%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/General/NativeFormat/DefaultValueParser.cs (93%) rename src/coreclr/nativeaot/{System.Private.TypeLoader => System.Private.CoreLib}/src/System/Reflection/Runtime/General/QHandles.NativeFormat.cs (99%) rename src/coreclr/nativeaot/{System.Private.TypeLoader => System.Private.CoreLib}/src/System/Reflection/Runtime/General/QHandles.cs (93%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/General/QSignatureTypeHandle.NativeFormat.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/General/QSignatureTypeHandle.cs (87%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/General/ReflectionCoreCallbacksImplementation.cs (99%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/General/RuntimeTypeHandleKey.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/General/ThunkedApis.cs (95%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/General/ToStringUtils.cs (97%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/General/TypeContext.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/General/TypeForwardInfo.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/General/TypeResolver.NativeFormat.cs (85%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/General/TypeResolver.cs (95%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/General/TypeUnifier.NativeFormat.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/General/TypeUnifier.cs (99%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/MethodInfos/CustomMethodInvoker.cs (95%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/MethodInfos/CustomMethodInvokerAction.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/MethodInfos/CustomMethodMapper.Nullable.cs (94%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/MethodInfos/CustomMethodMapper.String.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/MethodInfos/CustomMethodMapper.cs (93%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/MethodInfos/IRuntimeMethodCommon.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/MethodInfos/InvokerOptions.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/MethodInfos/NativeFormat/NativeFormatMethodCommon.cs (97%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/MethodInfos/OpenMethodInvoker.cs (86%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/MethodInfos/RuntimeClsIdNullaryConstructorInfo.cs (97%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructedGenericMethodInfo.cs (98%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructorInfo.cs (94%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/MethodInfos/RuntimeDummyMethodInfo.cs (97%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/MethodInfos/RuntimeMethodHelpers.cs (98%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/MethodInfos/RuntimeMethodInfo.cs (98%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/MethodInfos/RuntimeNamedMethodInfo.cs (97%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/MethodInfos/RuntimePlainConstructorInfo.cs (98%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/MethodInfos/RuntimeSyntheticConstructorInfo.cs (97%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/MethodInfos/RuntimeSyntheticMethodInfo.cs (98%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/MethodInfos/SyntheticMethodId.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/MethodInfos/VirtualRuntimeParameterInfoArray.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/Modules/NativeFormat/NativeFormatRuntimeModule.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/Modules/RuntimeModule.cs (97%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/ParameterInfos/NativeFormat/NativeFormatMethodParameterInfo.cs (98%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/ParameterInfos/RuntimeFatMethodParameterInfo.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/ParameterInfos/RuntimeMethodParameterInfo.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/ParameterInfos/RuntimeParameterInfo.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/ParameterInfos/RuntimePropertyIndexParameterInfo.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/ParameterInfos/RuntimeSyntheticParameterInfo.cs (97%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/ParameterInfos/RuntimeThinMethodParameterInfo.cs (97%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/PropertyInfos/EcmaFormat/EcmaFormatRuntimePropertyInfo.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/PropertyInfos/NativeFormat/NativeFormatRuntimePropertyInfo.cs (99%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/PropertyInfos/RuntimePropertyInfo.cs (96%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfo.cs (96%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfoForMethods.UnificationKey.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfoForMethods.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfoForTypes.UnificationKey.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfoForTypes.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeNamedTypeInfo.UnificationKey.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeNamedTypeInfo.cs (97%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeTypeInfo.CoreGetDeclared.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/RuntimeArrayTypeInfo.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/RuntimeBlockedTypeInfo.cs (98%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/RuntimeByRefTypeInfo.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/RuntimeClsIdTypeInfo.UnificationKey.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/RuntimeClsIdTypeInfo.cs (95%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/RuntimeConstructedGenericTypeInfo.UnificationKey.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/RuntimeConstructedGenericTypeInfo.cs (98%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/RuntimeGenericParameterTypeInfo.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/RuntimeHasElementTypeInfo.UnificationKey.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/RuntimeHasElementTypeInfo.cs (95%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/RuntimeNamedTypeInfo.cs (96%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/RuntimeNoMetadataNamedTypeInfo.cs (98%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/RuntimePointerTypeInfo.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeDefinitionTypeInfo.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.BindingFlags.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.CoreGetDeclared.cs (96%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.GetMember.cs (84%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.InvokeMember.cs (90%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.TypeComponentsCache.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.cs (97%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeParsing/GetTypeOptions.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeParsing/TypeLexer.cs (100%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeParsing/TypeName.cs (99%) rename src/coreclr/nativeaot/{System.Private.Reflection.Core => System.Private.CoreLib}/src/System/Reflection/Runtime/TypeParsing/TypeParser.cs (99%) delete mode 100644 src/coreclr/nativeaot/System.Private.Reflection.Core/src/ILLink/ILLink.Substitutions.xml delete mode 100644 src/coreclr/nativeaot/System.Private.Reflection.Core/src/Resources/Strings.resx delete mode 100644 src/coreclr/nativeaot/System.Private.Reflection.Core/src/System.Private.Reflection.Core.csproj delete mode 100644 src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/NonOverriddenApis.cs diff --git a/src/coreclr/dlls/mscorrc/mscorrc.rc b/src/coreclr/dlls/mscorrc/mscorrc.rc index f6dc44d8b06ee3..6a96d6c03e0ea1 100644 --- a/src/coreclr/dlls/mscorrc/mscorrc.rc +++ b/src/coreclr/dlls/mscorrc/mscorrc.rc @@ -415,7 +415,6 @@ BEGIN IDS_EE_SIZECONTROLBADTYPE "Array size control parameter type not supported." IDS_EE_SAFEARRAYSZARRAYMISMATCH "SafeArray cannot be marshaled to this array type because it has either nonzero lower bounds or more than one dimension." - IDS_EE_ASSEMBLY_GETTYPE_CANNONT_HAVE_ASSEMBLY_SPEC "Type names passed to Assembly.GetType() must not specify an assembly." IDS_EE_NEEDS_ASSEMBLY_SPEC "Typename needs an assembly qualifier." IDS_EE_FILELOAD_ERROR_GENERIC "Could not load file or assembly '%1'. %2" diff --git a/src/coreclr/dlls/mscorrc/resource.h b/src/coreclr/dlls/mscorrc/resource.h index ed503b4875ad60..351ff690aaca65 100644 --- a/src/coreclr/dlls/mscorrc/resource.h +++ b/src/coreclr/dlls/mscorrc/resource.h @@ -305,7 +305,6 @@ #define IDS_CLASSLOAD_OVERLAPPING_INTERFACES 0x1a80 #define IDS_CLASSLOAD_32BITCLRLOADING64BITASSEMBLY 0x1a81 -#define IDS_EE_ASSEMBLY_GETTYPE_CANNONT_HAVE_ASSEMBLY_SPEC 0x1a84 #define IDS_EE_NEEDS_ASSEMBLY_SPEC 0x1a87 diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets index d5c08a768d970e..a6b599cd1bdca6 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets @@ -109,8 +109,7 @@ The .NET Foundation licenses this file to you under the MIT license. - <_ExcludedPrivateSdkAssemblies Include="$(IlcSdkPath)System.Private.Reflection.Core.dll" Condition="$(IlcDisableReflection) == 'true'" /> - + @@ -150,8 +149,7 @@ The .NET Foundation licenses this file to you under the MIT license. - <_ExcludedPrivateSdkAssemblies Include="$(IlcSdkPath)System.Private.Reflection.Core.dll" Condition="$(IlcDisableReflection) == 'true'" /> - + diff --git a/src/coreclr/nativeaot/Common/src/System/Runtime/CompilerServices/DeveloperExperienceModeOnlyAttribute.cs b/src/coreclr/nativeaot/Common/src/System/Runtime/CompilerServices/DeveloperExperienceModeOnlyAttribute.cs deleted file mode 100644 index f7d6a1d315f848..00000000000000 --- a/src/coreclr/nativeaot/Common/src/System/Runtime/CompilerServices/DeveloperExperienceModeOnlyAttribute.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; - -namespace System.Runtime.CompilerServices -{ - // - // Attach to classes that contain code only used in ILC /BuildType:chk builds. - // - // Any class attributed with this must have the following properties: - // - // - Class must be declared "static" - // - // - All public/internal methods must have a return type of: - // - // void - // bool - // any non-value type - // - // - All fields must be private. - // - // - Class constructor must not have externally visible side effects. - // - // - // On /BuildType:ret builds, ILC will run a special transform that - // turns all of the public and internal method bodies into - // the equivalent of: - // - // [MethodImpl(MethodImplOptions.AggressiveInlining)] - // T Foo() - // { - // return default(T); - // } - // - // It also removes all fields and private methods (including the class constructor.) - // - // The method semantics must be defined so that ret builds have - // the desired behavior with these implementations. - // - // - [AttributeUsage(AttributeTargets.Class)] - internal sealed class DeveloperExperienceModeOnlyAttribute : Attribute - { - } -} diff --git a/src/coreclr/nativeaot/Common/src/System/Runtime/CompilerServices/DeveloperExperienceState.cs b/src/coreclr/nativeaot/Common/src/System/Runtime/CompilerServices/DeveloperExperienceState.cs index f2e0d260b5d12a..78a8de127e59fc 100644 --- a/src/coreclr/nativeaot/Common/src/System/Runtime/CompilerServices/DeveloperExperienceState.cs +++ b/src/coreclr/nativeaot/Common/src/System/Runtime/CompilerServices/DeveloperExperienceState.cs @@ -5,7 +5,6 @@ namespace System.Runtime.CompilerServices { - [DeveloperExperienceModeOnly] internal static class DeveloperExperienceState { public static bool DeveloperExperienceModeEnabled diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.xml b/src/coreclr/nativeaot/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.xml index 3aeeaf70faefd9..48edfc4f2540c2 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.xml +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/ILLink/ILLink.Substitutions.xml @@ -17,4 +17,7 @@ + + + diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Reflection/Core/AssemblyBinder.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Core/AssemblyBinder.cs similarity index 92% rename from src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Reflection/Core/AssemblyBinder.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Core/AssemblyBinder.cs index 0a7bab62ea3620..f68d8407b2781b 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Reflection/Core/AssemblyBinder.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Core/AssemblyBinder.cs @@ -6,12 +6,15 @@ using System.Reflection; using Internal.Metadata.NativeFormat; using System.Reflection.Runtime.General; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace Internal.Reflection.Core { // Auto StructLayout used to suppress warning that order of fields is not guaranteed in partial structs [StructLayout(LayoutKind.Auto)] + [ReflectionBlocked] + [CLSCompliant(false)] public partial struct AssemblyBindResult { public MetadataReader Reader; @@ -25,6 +28,8 @@ public partial struct AssemblyBindResult // // If the binder cannot locate an assembly, it must return null and set "exception" to an exception object. // + [ReflectionBlocked] + [CLSCompliant(false)] public abstract class AssemblyBinder { public const string DefaultAssemblyNameForGetType = "System.Private.CoreLib"; diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/Internal/Reflection/Core/Execution/ExecutionDomain.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Core/Execution/ExecutionDomain.cs similarity index 97% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/Internal/Reflection/Core/Execution/ExecutionDomain.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Core/Execution/ExecutionDomain.cs index f2065074d78b3f..02f6a206015db2 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/Internal/Reflection/Core/Execution/ExecutionDomain.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Reflection/Core/Execution/ExecutionDomain.cs @@ -16,6 +16,7 @@ #endif using System.Reflection.Runtime.TypeParsing; using System.Reflection.Runtime.CustomAttributes; +using System.Runtime.CompilerServices; using Internal.Metadata.NativeFormat; using Internal.Runtime.Augments; @@ -24,6 +25,8 @@ namespace Internal.Reflection.Core.Execution // // This singleton class acts as an entrypoint from System.Private.Reflection.Execution to System.Private.Reflection.Core. // + [ReflectionBlocked] + [CLSCompliant(false)] public sealed class ExecutionDomain { internal ExecutionDomain(ReflectionDomainSetup executionDomainSetup, ExecutionEnvironment executionEnvironment) @@ -124,7 +127,7 @@ private static CoreTypeResolver CreateCoreTypeResolver(Func - @@ -344,9 +343,15 @@ + + ArrayBuilder.cs + Utilities\LockFreeReaderHashtable.cs + + System\Collections\Generic\EnumerableExtensions.cs + System\Collections\Generic\LowLevelList.cs @@ -374,6 +379,9 @@ System\Runtime\CompilerServices\__BlockReflectionAttribute.cs + + System\Runtime\CompilerServices\DeveloperExperienceState.cs + Internal\Runtime\CanonTypeKind.cs @@ -398,6 +406,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/ActivatorImplementation.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/ActivatorImplementation.cs similarity index 94% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/ActivatorImplementation.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/ActivatorImplementation.cs index 4370581bd7c6e2..8e3aef57b8ca5c 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/ActivatorImplementation.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/ActivatorImplementation.cs @@ -28,7 +28,7 @@ public static object CreateInstance( BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance; if (nonPublic) bindingFlags |= BindingFlags.NonPublic; - ConstructorInfo constructor = type.GetConstructor(bindingFlags, null, CallingConventions.Any, Array.Empty(), null); + ConstructorInfo? constructor = type.GetConstructor(bindingFlags, null, CallingConventions.Any, Array.Empty(), null); if (constructor == null) { if (type.IsValueType) @@ -44,7 +44,7 @@ public static object CreateInstance( [DebuggerGuidedStepThrough] public static object CreateInstance( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] - Type type, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes) + Type type, BindingFlags bindingAttr, Binder binder, object?[]? args, CultureInfo? culture, object?[]? activationAttributes) { if (type == null) throw new ArgumentNullException(nameof(type)); @@ -64,7 +64,7 @@ public static object CreateInstance( args = Array.Empty(); int numArgs = args.Length; - Type[] argTypes = new Type[numArgs]; + Type?[] argTypes = new Type[numArgs]; for (int i = 0; i < numArgs; i++) { argTypes[i] = args[i]?.GetType(); @@ -88,7 +88,7 @@ public static object CreateInstance( if (binder == null) binder = Type.DefaultBinder; - MethodBase invokeMethod = binder.BindToMethod(bindingAttr, matches.ToArray(), ref args, null, culture, null, out object state); + MethodBase invokeMethod = binder.BindToMethod(bindingAttr, matches.ToArray(), ref args, null, culture, null, out object? state); if (invokeMethod.GetParametersNoCopy().Length == 0) { if (args.Length != 0) @@ -132,7 +132,7 @@ private static void CreateInstanceCheckType(Type type) Type elementType = type; while (elementType.HasElementType) - elementType = elementType.GetElementType(); + elementType = elementType.GetElementType()!; if (elementType == typeof(void)) throw new NotSupportedException(SR.Acc_CreateVoid); } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Helpers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Helpers.cs deleted file mode 100644 index 23a17a0e6702c5..00000000000000 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Helpers.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// Implements System.Type -// - -using System; -using Internal.Runtime.Augments; - -namespace System -{ - internal static class Helpers - { - public static bool TryGetEEType(this Type type, out EETypePtr eeType) - { - RuntimeTypeHandle typeHandle = RuntimeAugments.Callbacks.GetTypeHandleIfAvailable(type); - if (typeHandle.IsNull) - { - eeType = default(EETypePtr); - return false; - } - eeType = typeHandle.ToEETypePtr(); - return true; - } - } -} diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.GetTypeCore.CaseInsensitive.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.GetTypeCore.CaseInsensitive.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.GetTypeCore.CaseInsensitive.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.GetTypeCore.CaseInsensitive.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.GetTypeCore.CaseSensitive.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.GetTypeCore.CaseSensitive.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.GetTypeCore.CaseSensitive.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.GetTypeCore.CaseSensitive.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.cs similarity index 98% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.cs index 81cf4e7a4c27ed..93fd3bfca537b5 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.cs @@ -120,7 +120,7 @@ protected sealed override IEnumerable TypeForwardInfos IEnumerable allNamespaceHandles = reader.GetTransitiveNamespaces(topLevelNamespaceHandles); foreach (NamespaceDefinitionHandle namespaceHandle in allNamespaceHandles) { - string namespaceName = null; + string? namespaceName = null; foreach (TypeForwarderHandle typeForwarderHandle in namespaceHandle.GetNamespaceDefinition(reader).TypeForwarders) { if (namespaceName == null) @@ -182,7 +182,7 @@ internal sealed override RuntimeAssemblyName RuntimeAssemblyName public sealed override bool Equals(object obj) { - NativeFormatRuntimeAssembly other = obj as NativeFormatRuntimeAssembly; + NativeFormatRuntimeAssembly? other = obj as NativeFormatRuntimeAssembly; return Equals(other); } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Assemblies/RuntimeAssemblyInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Assemblies/RuntimeAssemblyInfo.cs similarity index 97% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Assemblies/RuntimeAssemblyInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Assemblies/RuntimeAssemblyInfo.cs index 0234c88357b260..491acf920ec10e 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Assemblies/RuntimeAssemblyInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Assemblies/RuntimeAssemblyInfo.cs @@ -29,7 +29,7 @@ namespace System.Reflection.Runtime.Assemblies // internal abstract partial class RuntimeAssemblyInfo : RuntimeAssembly, IEquatable { - public bool Equals(RuntimeAssemblyInfo other) + public bool Equals(RuntimeAssemblyInfo? other) { if (other == null) return false; @@ -102,7 +102,7 @@ public sealed override Type GetType(string name, bool throwOnError, bool ignoreC } #pragma warning disable 0067 // Silence warning about ModuleResolve not being used. - public sealed override event ModuleResolveEventHandler ModuleResolve; + public sealed override event ModuleResolveEventHandler? ModuleResolve; #pragma warning restore 0067 public sealed override bool ReflectionOnly => false; // ReflectionOnly loading not supported. @@ -120,14 +120,14 @@ public sealed override AssemblyName GetName() public sealed override Type[] GetForwardedTypes() { List types = new List(); - List exceptions = null; + List? exceptions = null; foreach (TypeForwardInfo typeForwardInfo in TypeForwardInfos) { string fullTypeName = typeForwardInfo.NamespaceName.Length == 0 ? typeForwardInfo.TypeName : typeForwardInfo.NamespaceName + "." + typeForwardInfo.TypeName; RuntimeAssemblyName redirectedAssemblyName = typeForwardInfo.RedirectedAssemblyName; - Type type = null; + Type? type = null; RuntimeAssemblyInfo redirectedAssembly; Exception exception = TryGetRuntimeAssembly(redirectedAssemblyName, out redirectedAssembly); if (exception == null) @@ -252,6 +252,7 @@ private CaseSensitiveTypeCache CaseSensitiveTypeTable } } +#pragma warning disable 0672 // GlobalAssemblyCache is Obsolete. public sealed override bool GlobalAssemblyCache { get @@ -259,6 +260,7 @@ public sealed override bool GlobalAssemblyCache return false; } } +#pragma warning restore 0672 public sealed override long HostContext { @@ -274,8 +276,6 @@ public sealed override Module LoadModule(string moduleName, byte[] rawModule, by throw new PlatformNotSupportedException(); } - internal const string ThrowingMessageInRAF = "This member throws an exception for assemblies embedded in a single-file app"; - [RequiresAssemblyFiles(ThrowingMessageInRAF)] public sealed override FileStream GetFile(string name) { diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/ConstructorPolicies.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/ConstructorPolicies.cs similarity index 94% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/ConstructorPolicies.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/ConstructorPolicies.cs index 368105aa0de8a9..ee55cf1087d2be 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/ConstructorPolicies.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/ConstructorPolicies.cs @@ -20,7 +20,7 @@ public sealed override IEnumerable GetDeclaredMembers(TypeInfo return typeInfo.DeclaredConstructors; } - public sealed override IEnumerable CoreGetDeclaredMembers(RuntimeTypeInfo type, NameFilter optionalNameFilter, RuntimeTypeInfo reflectedType) + public sealed override IEnumerable CoreGetDeclaredMembers(RuntimeTypeInfo type, NameFilter? optionalNameFilter, RuntimeTypeInfo reflectedType) { Debug.Assert(reflectedType.Equals(type)); // Constructor queries are always performed as if BindingFlags.DeclaredOnly are set so the reflectedType should always be the declaring type. return type.CoreGetDeclaredConstructors(optionalNameFilter); @@ -43,7 +43,7 @@ public sealed override void GetMemberAttributes(ConstructorInfo member, out Meth isNewSlot = false; } - public sealed override bool ImplicitlyOverrides(ConstructorInfo baseMember, ConstructorInfo derivedMember) => false; + public sealed override bool ImplicitlyOverrides(ConstructorInfo? baseMember, ConstructorInfo? derivedMember) => false; public sealed override bool IsSuppressedByMoreDerivedMember(ConstructorInfo member, ConstructorInfo[] priorMembers, int startIndex, int endIndex) { diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/EventPolicies.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/EventPolicies.cs similarity index 68% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/EventPolicies.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/EventPolicies.cs index 59262a33155522..e8ba0e22ea9ae0 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/EventPolicies.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/EventPolicies.cs @@ -20,7 +20,7 @@ public sealed override IEnumerable GetDeclaredMembers(TypeInfo typeIn return typeInfo.DeclaredEvents; } - public sealed override IEnumerable CoreGetDeclaredMembers(RuntimeTypeInfo type, NameFilter optionalNameFilter, RuntimeTypeInfo reflectedType) + public sealed override IEnumerable CoreGetDeclaredMembers(RuntimeTypeInfo type, NameFilter? optionalNameFilter, RuntimeTypeInfo reflectedType) { return type.CoreGetDeclaredEvents(optionalNameFilter, reflectedType); } @@ -29,7 +29,20 @@ public sealed override IEnumerable CoreGetDeclaredMembers(RuntimeType public sealed override void GetMemberAttributes(EventInfo member, out MethodAttributes visibility, out bool isStatic, out bool isVirtual, out bool isNewSlot) { - MethodInfo accessorMethod = GetAccessorMethod(member); + MethodInfo? accessorMethod = GetAccessorMethod(member); + if (accessorMethod == null) + { + // If we got here, this is a inherited EventInfo that only had private accessors and is now refusing to give them out + // because that's what the rules of inherited EventInfo's are. Such a EventInfo is also considered private and will never be + // given out of a Type.GetProperty() call. So all we have to do is set its visibility to Private and it will get filtered out. + // Other values need to be set to satisfy C# but they are meaningless. + visibility = MethodAttributes.Private; + isStatic = false; + isVirtual = false; + isNewSlot = true; + return; + } + MethodAttributes methodAttributes = accessorMethod.Attributes; visibility = methodAttributes & MethodAttributes.MemberAccessMask; isStatic = (0 != (methodAttributes & MethodAttributes.Static)); @@ -50,10 +63,10 @@ public sealed override bool IsSuppressedByMoreDerivedMember(EventInfo member, Ev return false; } - public sealed override bool ImplicitlyOverrides(EventInfo baseMember, EventInfo derivedMember) + public sealed override bool ImplicitlyOverrides(EventInfo? baseMember, EventInfo? derivedMember) { - MethodInfo baseAccessor = GetAccessorMethod(baseMember); - MethodInfo derivedAccessor = GetAccessorMethod(derivedMember); + MethodInfo? baseAccessor = GetAccessorMethod(baseMember!); + MethodInfo? derivedAccessor = GetAccessorMethod(derivedMember!); return MemberPolicies.Default.ImplicitlyOverrides(baseAccessor, derivedAccessor); } @@ -62,10 +75,9 @@ public sealed override bool OkToIgnoreAmbiguity(EventInfo m1, EventInfo m2) return false; } - private static MethodInfo GetAccessorMethod(EventInfo e) + private static MethodInfo? GetAccessorMethod(EventInfo e) { - MethodInfo accessor = e.AddMethod; - return accessor; + return e.AddMethod; } } } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/FieldPolicies.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/FieldPolicies.cs similarity index 95% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/FieldPolicies.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/FieldPolicies.cs index d17a43ce09252f..a1fe8f0c069e7e 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/FieldPolicies.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/FieldPolicies.cs @@ -20,7 +20,7 @@ public sealed override IEnumerable GetDeclaredMembers(TypeInfo typeIn return typeInfo.DeclaredFields; } - public sealed override IEnumerable CoreGetDeclaredMembers(RuntimeTypeInfo type, NameFilter optionalNameFilter, RuntimeTypeInfo reflectedType) + public sealed override IEnumerable CoreGetDeclaredMembers(RuntimeTypeInfo type, NameFilter? optionalNameFilter, RuntimeTypeInfo reflectedType) { return type.CoreGetDeclaredFields(optionalNameFilter, reflectedType); } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/MemberPolicies.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/MemberPolicies.cs similarity index 99% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/MemberPolicies.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/MemberPolicies.cs index cbb620e5be3c39..50a665e5aea3ae 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/MemberPolicies.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/MemberPolicies.cs @@ -28,7 +28,7 @@ internal abstract class MemberPolicies where M : MemberInfo // Returns all of the directly declared members on the given TypeInfo whose name matches optionalNameFilter. If optionalNameFilter is null, // returns all directly declared members. // - public abstract IEnumerable CoreGetDeclaredMembers(RuntimeTypeInfo type, NameFilter optionalNameFilter, RuntimeTypeInfo reflectedType); + public abstract IEnumerable CoreGetDeclaredMembers(RuntimeTypeInfo type, NameFilter? optionalNameFilter, RuntimeTypeInfo reflectedType); // // Policy to decide whether a member is considered "virtual", "virtual new" and what its member visibility is. diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/MemberTypeIndex.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/MemberTypeIndex.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/MemberTypeIndex.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/MemberTypeIndex.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/MethodPolicies.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/MethodPolicies.cs similarity index 93% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/MethodPolicies.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/MethodPolicies.cs index a88d9b76b1cee8..040034cb4e5e3d 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/MethodPolicies.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/MethodPolicies.cs @@ -20,7 +20,7 @@ public sealed override IEnumerable GetDeclaredMembers(TypeInfo typeI return typeInfo.DeclaredMethods; } - public sealed override IEnumerable CoreGetDeclaredMembers(RuntimeTypeInfo type, NameFilter optionalNameFilter, RuntimeTypeInfo reflectedType) + public sealed override IEnumerable CoreGetDeclaredMembers(RuntimeTypeInfo type, NameFilter? optionalNameFilter, RuntimeTypeInfo reflectedType) { return type.CoreGetDeclaredMethods(optionalNameFilter, reflectedType); } @@ -36,10 +36,10 @@ public sealed override void GetMemberAttributes(MethodInfo member, out MethodAtt isNewSlot = (0 != (methodAttributes & MethodAttributes.NewSlot)); } - public sealed override bool ImplicitlyOverrides(MethodInfo baseMember, MethodInfo derivedMember) + public sealed override bool ImplicitlyOverrides(MethodInfo? baseMember, MethodInfo? derivedMember) { // TODO (https://github.com/dotnet/corert/issues/1896) Comparing signatures is fragile. The runtime and/or toolchain should have a way of sharing this info. - return AreNamesAndSignaturesEqual(baseMember, derivedMember); + return AreNamesAndSignaturesEqual(baseMember!, derivedMember!); } // diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/NameFilter.NativeFormat.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/NameFilter.NativeFormat.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/NameFilter.NativeFormat.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/NameFilter.NativeFormat.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/NameFilter.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/NameFilter.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/NameFilter.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/NameFilter.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/NestedTypePolicies.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/NestedTypePolicies.cs similarity index 97% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/NestedTypePolicies.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/NestedTypePolicies.cs index d22d42ac12e309..9fd791d0d655bc 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/NestedTypePolicies.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/NestedTypePolicies.cs @@ -30,7 +30,7 @@ public sealed override IEnumerable GetDeclaredMembers(TypeInfo typeInfo) return typeInfo.DeclaredNestedTypes; } - public sealed override IEnumerable CoreGetDeclaredMembers(RuntimeTypeInfo type, NameFilter optionalNameFilter, RuntimeTypeInfo reflectedType) + public sealed override IEnumerable CoreGetDeclaredMembers(RuntimeTypeInfo type, NameFilter? optionalNameFilter, RuntimeTypeInfo reflectedType) { Debug.Assert(reflectedType.Equals(type)); // NestedType queries are always performed as if BindingFlags.DeclaredOnly are set so the reflectedType should always be the declaring type. return type.CoreGetDeclaredNestedTypes(optionalNameFilter); diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/PropertyPolicies.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/PropertyPolicies.cs similarity index 86% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/PropertyPolicies.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/PropertyPolicies.cs index ee162bdfe98984..c7752043c63b97 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/PropertyPolicies.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/PropertyPolicies.cs @@ -20,7 +20,7 @@ public sealed override IEnumerable GetDeclaredMembers(TypeInfo typ return typeInfo.DeclaredProperties; } - public sealed override IEnumerable CoreGetDeclaredMembers(RuntimeTypeInfo type, NameFilter optionalNameFilter, RuntimeTypeInfo reflectedType) + public sealed override IEnumerable CoreGetDeclaredMembers(RuntimeTypeInfo type, NameFilter? optionalNameFilter, RuntimeTypeInfo reflectedType) { return type.CoreGetDeclaredProperties(optionalNameFilter, reflectedType); } @@ -29,7 +29,7 @@ public sealed override IEnumerable CoreGetDeclaredMembers(RuntimeT public sealed override void GetMemberAttributes(PropertyInfo member, out MethodAttributes visibility, out bool isStatic, out bool isVirtual, out bool isNewSlot) { - MethodInfo accessorMethod = GetAccessorMethod(member); + MethodInfo? accessorMethod = GetAccessorMethod(member); if (accessorMethod == null) { // If we got here, this is a inherited PropertyInfo that only had private accessors and is now refusing to give them out @@ -50,10 +50,10 @@ public sealed override void GetMemberAttributes(PropertyInfo member, out MethodA isNewSlot = (0 != (methodAttributes & MethodAttributes.NewSlot)); } - public sealed override bool ImplicitlyOverrides(PropertyInfo baseMember, PropertyInfo derivedMember) + public sealed override bool ImplicitlyOverrides(PropertyInfo? baseMember, PropertyInfo? derivedMember) { - MethodInfo baseAccessor = GetAccessorMethod(baseMember); - MethodInfo derivedAccessor = GetAccessorMethod(derivedMember); + MethodInfo? baseAccessor = GetAccessorMethod(baseMember!); + MethodInfo? derivedAccessor = GetAccessorMethod(derivedMember!); return MemberPolicies.Default.ImplicitlyOverrides(baseAccessor, derivedAccessor); } @@ -63,11 +63,11 @@ public sealed override bool ImplicitlyOverrides(PropertyInfo baseMember, Propert // public sealed override bool IsSuppressedByMoreDerivedMember(PropertyInfo member, PropertyInfo[] priorMembers, int startIndex, int endIndex) { - MethodInfo baseAccessor = GetAccessorMethod(member); + MethodInfo? baseAccessor = GetAccessorMethod(member); for (int i = startIndex; i < endIndex; i++) { PropertyInfo prior = priorMembers[i]; - MethodInfo derivedAccessor = GetAccessorMethod(prior); + MethodInfo? derivedAccessor = GetAccessorMethod(prior); if (!AreNamesAndSignaturesEqual(baseAccessor, derivedAccessor)) continue; if (derivedAccessor.IsStatic != baseAccessor.IsStatic) @@ -85,9 +85,9 @@ public sealed override bool OkToIgnoreAmbiguity(PropertyInfo m1, PropertyInfo m2 return false; } - private static MethodInfo GetAccessorMethod(PropertyInfo property) + private static MethodInfo? GetAccessorMethod(PropertyInfo property) { - MethodInfo accessor = property.GetMethod; + MethodInfo? accessor = property.GetMethod; if (accessor == null) { accessor = property.SetMethod; diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/QueriedMemberList.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/QueriedMemberList.cs similarity index 99% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/QueriedMemberList.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/QueriedMemberList.cs index d1ce2475ea8fd5..427d00b8d506b8 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/QueriedMemberList.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/QueriedMemberList.cs @@ -105,7 +105,7 @@ public static QueriedMemberList Create(RuntimeTypeInfo type, string optionalN MemberPolicies policies = MemberPolicies.Default; - NameFilter nameFilter; + NameFilter? nameFilter; if (optionalNameFilter == null) nameFilter = null; else if (ignoreCase) diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/QueryResult.Enumerator.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/QueryResult.Enumerator.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/QueryResult.Enumerator.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/QueryResult.Enumerator.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/QueryResult.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/QueryResult.cs similarity index 98% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/QueryResult.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/QueryResult.cs index 1674efe1ea57ad..4aadb1864c2002 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/QueryResult.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/QueryResult.cs @@ -92,14 +92,14 @@ public void CopyTo(MemberInfo[] array, int startIndex) /// /// Returns a single member, null or throws AmbigousMatchException, for the Type.Get*(string name,...) family of apis. /// - public M Disambiguate() + public M? Disambiguate() { if (_queriedMembers == null) return null; // This is an uninitialized QueryResult, which is supported and represents a 0-length list of matches. int unfilteredCount = UnfilteredCount; - M match = null; + M? match = null; for (int i = 0; i < unfilteredCount; i++) { if (_queriedMembers.Matches(i, _bindingAttr)) diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/Shared.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/Shared.cs similarity index 98% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/Shared.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/Shared.cs index 4f20819d1d210a..8d68023a816535 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/BindingFlagSupport/Shared.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/BindingFlagSupport/Shared.cs @@ -20,7 +20,7 @@ internal static class Shared // // Candidates must pass this screen before we involve the binder. // - public static bool QualifiesBasedOnParameterCount(this MethodBase methodBase, BindingFlags bindingFlags, CallingConventions callConv, Type[] argumentTypes) + public static bool QualifiesBasedOnParameterCount(this MethodBase methodBase, BindingFlags bindingFlags, CallingConventions callConv, Type?[] argumentTypes) { Debug.Assert(methodBase is not null); Debug.Assert(argumentTypes is not null); @@ -160,7 +160,7 @@ public static M GetImplicitlyOverriddenBaseClassMember(this M member) where M TypeInfo typeInfo = member.DeclaringType.GetTypeInfo(); for (;;) { - Type baseType = typeInfo.BaseType; + Type? baseType = typeInfo.BaseType; if (baseType == null) { return null; diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/CustomAttributes/NativeFormat/NativeFormatCustomAttributeData.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/CustomAttributes/NativeFormat/NativeFormatCustomAttributeData.cs similarity index 94% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/CustomAttributes/NativeFormat/NativeFormatCustomAttributeData.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/CustomAttributes/NativeFormat/NativeFormatCustomAttributeData.cs index 20a2d5ff1e3d45..f564f311cc7454 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/CustomAttributes/NativeFormat/NativeFormatCustomAttributeData.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/CustomAttributes/NativeFormat/NativeFormatCustomAttributeData.cs @@ -127,16 +127,16 @@ internal sealed override IList GetConstructorArgum foreach (Handle fixedArgumentHandle in _customAttribute.FixedArguments) { Handle typeHandle = ctorTypeHandles[index]; - Exception exception = null; - RuntimeTypeInfo argumentType = typeHandle.TryResolve(_reader, new TypeContext(null, null), ref exception); + Exception? exception = null; + RuntimeTypeInfo? argumentType = typeHandle.TryResolve(_reader, new TypeContext(null, null), ref exception); if (argumentType == null) { if (throwIfMissingMetadata) - throw exception; + throw exception!; return null; } - Exception e = fixedArgumentHandle.TryParseConstantValue(_reader, out object value); + Exception e = fixedArgumentHandle.TryParseConstantValue(_reader, out object? value); CustomAttributeTypedArgument customAttributeTypedArgument; if (e != null) { @@ -169,17 +169,17 @@ internal sealed override IList GetNamedArguments(b string memberName = namedArgument.Name.GetString(_reader); bool isField = (namedArgument.Flags == NamedArgumentMemberKind.Field); - Exception exception = null; - RuntimeTypeInfo argumentType = namedArgument.Type.TryResolve(_reader, new TypeContext(null, null), ref exception); + Exception? exception = null; + RuntimeTypeInfo? argumentType = namedArgument.Type.TryResolve(_reader, new TypeContext(null, null), ref exception); if (argumentType == null) { if (throwIfMissingMetadata) - throw exception; + throw exception!; else return null; } - object value; + object? value; Exception e = namedArgument.Value.TryParseConstantValue(_reader, out value); if (e != null) { @@ -199,7 +199,7 @@ internal sealed override IList GetNamedArguments(b Justification = "Metadata generation ensures fields/properties referenced from attributes are preserved.")] private static CustomAttributeNamedArgument CreateCustomAttributeNamedArgument(Type attributeType, string memberName, bool isField, CustomAttributeTypedArgument typedValue) { - MemberInfo memberInfo; + MemberInfo? memberInfo; if (isField) memberInfo = attributeType.GetField(memberName, BindingFlags.Public | BindingFlags.Instance); diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/CustomAttributes/RuntimeCustomAttributeData.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/CustomAttributes/RuntimeCustomAttributeData.cs similarity index 97% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/CustomAttributes/RuntimeCustomAttributeData.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/CustomAttributes/RuntimeCustomAttributeData.cs index 867a447c8c049a..2b964c6b0b5605 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/CustomAttributes/RuntimeCustomAttributeData.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/CustomAttributes/RuntimeCustomAttributeData.cs @@ -116,7 +116,7 @@ private static string ComputeTypedArgumentString(CustomAttributeTypedArgument ca if (argumentType == null) return cat.ToString(); - object value = cat.Value; + object? value = cat.Value; if (argumentType.IsEnum) return string.Format(typed ? "{0}" : "({1}){0}", value, argumentType.FullName); @@ -134,9 +134,9 @@ private static string ComputeTypedArgumentString(CustomAttributeTypedArgument ca else if (argumentType.IsArray) { - IList array = value as IList; + IList array = (IList)value; - Type elementType = argumentType.GetElementType(); + Type elementType = argumentType.GetElementType()!; string result = string.Format(@"new {0}[{1}] {{ ", elementType.IsEnum ? elementType.FullName : elementType.Name, array.Count); for (int i = 0; i < array.Count; i++) @@ -161,7 +161,7 @@ private string LastResortToString // Wrap a custom attribute argument (or an element of an array-typed custom attribute argument) in a CustomAttributeTypeArgument structure // for insertion into a CustomAttributeData value. // - protected CustomAttributeTypedArgument WrapInCustomAttributeTypedArgument(object value, Type argumentType) + protected CustomAttributeTypedArgument WrapInCustomAttributeTypedArgument(object? value, Type argumentType) { if (argumentType == typeof(object)) { @@ -179,7 +179,7 @@ protected CustomAttributeTypedArgument WrapInCustomAttributeTypedArgument(object { if (!argumentType.IsArray) throw new BadImageFormatException(); - Type reportedElementType = argumentType.GetElementType(); + Type reportedElementType = argumentType.GetElementType()!; LowLevelListWithIList elementTypedArguments = new LowLevelListWithIList(); foreach (object elementValue in enumerableValue) { diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/CustomAttributes/RuntimePseudoCustomAttributeData.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/CustomAttributes/RuntimePseudoCustomAttributeData.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/CustomAttributes/RuntimePseudoCustomAttributeData.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/CustomAttributes/RuntimePseudoCustomAttributeData.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/DefaultDispenserPolicy.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Dispensers/DefaultDispenserPolicy.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/DefaultDispenserPolicy.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Dispensers/DefaultDispenserPolicy.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/Dispenser.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Dispensers/Dispenser.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/Dispenser.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Dispensers/Dispenser.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/DispenserAlgorithm.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Dispensers/DispenserAlgorithm.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/DispenserAlgorithm.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Dispensers/DispenserAlgorithm.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/DispenserFactory.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Dispensers/DispenserFactory.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/DispenserFactory.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Dispensers/DispenserFactory.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/DispenserPolicy.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Dispensers/DispenserPolicy.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/DispenserPolicy.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Dispensers/DispenserPolicy.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/DispenserScenario.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Dispensers/DispenserScenario.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/DispenserScenario.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Dispensers/DispenserScenario.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/DispenserThatAlwaysCreates.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Dispensers/DispenserThatAlwaysCreates.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/DispenserThatAlwaysCreates.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Dispensers/DispenserThatAlwaysCreates.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/DispenserThatAlwaysReuses.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Dispensers/DispenserThatAlwaysReuses.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/DispenserThatAlwaysReuses.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Dispensers/DispenserThatAlwaysReuses.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/DispenserThatReusesAsLongAsKeyIsAlive.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Dispensers/DispenserThatReusesAsLongAsKeyIsAlive.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/DispenserThatReusesAsLongAsKeyIsAlive.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Dispensers/DispenserThatReusesAsLongAsKeyIsAlive.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/DispenserThatReusesAsLongAsKeyedValueIsAlive.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Dispensers/DispenserThatReusesAsLongAsKeyedValueIsAlive.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/DispenserThatReusesAsLongAsKeyedValueIsAlive.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Dispensers/DispenserThatReusesAsLongAsKeyedValueIsAlive.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/DispenserThatReusesAsLongAsValueIsAlive.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Dispensers/DispenserThatReusesAsLongAsValueIsAlive.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Dispensers/DispenserThatReusesAsLongAsValueIsAlive.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Dispensers/DispenserThatReusesAsLongAsValueIsAlive.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/EventInfos/NativeFormat/NativeFormatRuntimeEventInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/EventInfos/NativeFormat/NativeFormatRuntimeEventInfo.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/EventInfos/NativeFormat/NativeFormatRuntimeEventInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/EventInfos/NativeFormat/NativeFormatRuntimeEventInfo.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/EventInfos/RuntimeEventInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/EventInfos/RuntimeEventInfo.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/EventInfos/RuntimeEventInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/EventInfos/RuntimeEventInfo.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/FieldInfos/NativeFormat/NativeFormatRuntimeFieldInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/FieldInfos/NativeFormat/NativeFormatRuntimeFieldInfo.cs similarity index 97% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/FieldInfos/NativeFormat/NativeFormatRuntimeFieldInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/FieldInfos/NativeFormat/NativeFormatRuntimeFieldInfo.cs index 40ad5cc3cf3c66..83835e4ce9e1b2 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/FieldInfos/NativeFormat/NativeFormatRuntimeFieldInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/FieldInfos/NativeFormat/NativeFormatRuntimeFieldInfo.cs @@ -21,7 +21,7 @@ using Internal.Reflection.Core; using Internal.Reflection.Core.Execution; -using Internal.Runtime.TypeLoader; +using Internal.Runtime.Augments; namespace System.Reflection.Runtime.FieldInfos.NativeFormat { @@ -134,13 +134,13 @@ public sealed override RuntimeFieldHandle FieldHandle { get { - return TypeLoaderEnvironment.Instance.GetRuntimeFieldHandleForComponents( + return RuntimeAugments.TypeLoaderCallbacks.GetRuntimeFieldHandleForComponents( DeclaringType.TypeHandle, Name); } } - protected sealed override bool GetDefaultValueIfAvailable(bool raw, out object defaultValue) + protected sealed override bool GetDefaultValueIfAvailable(bool raw, out object? defaultValue) { return DefaultValueParser.GetDefaultValueIfAny(_reader, _field.DefaultValue, FieldType, CustomAttributes, raw, out defaultValue); } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/FieldInfos/RuntimeFieldInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/FieldInfos/RuntimeFieldInfo.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/FieldInfos/RuntimeFieldInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/FieldInfos/RuntimeFieldInfo.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/Assignability.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/Assignability.cs similarity index 98% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/Assignability.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/Assignability.cs index 074b49aab2e930..61f1bb5430c533 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/Assignability.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/Assignability.cs @@ -53,7 +53,7 @@ public static bool IsAssignableFrom(Type toTypeInfo, Type fromTypeInfo) // Desktop compat: IsAssignableFrom() considers T as assignable to Nullable (but does not check if T is a generic parameter.) if (!fromTypeInfo.IsGenericParameter) { - Type nullableUnderlyingType = Nullable.GetUnderlyingType(toTypeInfo); + Type? nullableUnderlyingType = Nullable.GetUnderlyingType(toTypeInfo); if (nullableUnderlyingType != null && nullableUnderlyingType.Equals(fromTypeInfo)) return true; } @@ -93,8 +93,8 @@ private static bool CanCastTo(this Type fromTypeInfo, Type toTypeInfo) } } - Type toElementTypeInfo = toTypeInfo.GetElementType(); - Type fromElementTypeInfo = fromTypeInfo.GetElementType(); + Type toElementTypeInfo = toTypeInfo.GetElementType()!; + Type fromElementTypeInfo = fromTypeInfo.GetElementType()!; return fromElementTypeInfo.IsElementTypeCompatibleWith(toElementTypeInfo); } @@ -103,8 +103,8 @@ private static bool CanCastTo(this Type fromTypeInfo, Type toTypeInfo) if (!toTypeInfo.IsByRef) return false; - Type toElementTypeInfo = toTypeInfo.GetElementType(); - Type fromElementTypeInfo = fromTypeInfo.GetElementType(); + Type toElementTypeInfo = toTypeInfo.GetElementType()!; + Type fromElementTypeInfo = fromTypeInfo.GetElementType()!; return fromElementTypeInfo.IsElementTypeCompatibleWith(toElementTypeInfo); } @@ -113,8 +113,8 @@ private static bool CanCastTo(this Type fromTypeInfo, Type toTypeInfo) if (!toTypeInfo.IsPointer) return false; - Type toElementTypeInfo = toTypeInfo.GetElementType(); - Type fromElementTypeInfo = fromTypeInfo.GetElementType(); + Type toElementTypeInfo = toTypeInfo.GetElementType()!; + Type fromElementTypeInfo = fromTypeInfo.GetElementType()!; return fromElementTypeInfo.IsElementTypeCompatibleWith(toElementTypeInfo); } @@ -169,7 +169,7 @@ private static bool CanCastTo(this Type fromTypeInfo, Type toTypeInfo) Type walk = fromTypeInfo; for (;;) { - Type baseType = walk.BaseType; + Type? baseType = walk.BaseType; if (baseType == null) return false; walk = baseType; @@ -358,7 +358,7 @@ private static bool CanCastArrayToInterface(this Type fromTypeInfo, Type toTypeI Type toElementTypeInfo = toTypeGenericTypeArguments[0]; Type toTypeGenericTypeDefinition = toTypeInfo.GetGenericTypeDefinition(); - Type fromElementTypeInfo = fromTypeInfo.GetElementType(); + Type fromElementTypeInfo = fromTypeInfo.GetElementType()!; foreach (Type ifc in fromTypeInfo.GetInterfaces()) { if (ifc.IsConstructedGenericType) diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/BlockedRuntimeTypeNameGenerator.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/BlockedRuntimeTypeNameGenerator.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/BlockedRuntimeTypeNameGenerator.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/BlockedRuntimeTypeNameGenerator.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/Dispensers.NativeFormat.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/Dispensers.NativeFormat.cs similarity index 99% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/Dispensers.NativeFormat.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/Dispensers.NativeFormat.cs index 26d2e4bc6b0900..93233d1c59a564 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/Dispensers.NativeFormat.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/Dispensers.NativeFormat.cs @@ -32,7 +32,7 @@ namespace System.Reflection.Runtime.Assemblies //----------------------------------------------------------------------------------------------------------- internal partial class RuntimeAssemblyInfo { - static partial void GetNativeFormatRuntimeAssembly(AssemblyBindResult bindResult, ref RuntimeAssembly runtimeAssembly) + static partial void GetNativeFormatRuntimeAssembly(AssemblyBindResult bindResult, ref RuntimeAssembly? runtimeAssembly) { if (bindResult.Reader != null) runtimeAssembly = NativeFormatRuntimeAssembly.GetRuntimeAssembly(bindResult.Reader, bindResult.ScopeDefinitionHandle, bindResult.OverflowScopes); diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/Dispensers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/Dispensers.cs similarity index 98% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/Dispensers.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/Dispensers.cs index e524aa3bb8b85f..730215bdbab6a6 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/Dispensers.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/Dispensers.cs @@ -117,7 +117,7 @@ internal static Exception TryGetRuntimeAssembly(RuntimeAssemblyName assemblyRefN private static RuntimeAssembly GetRuntimeAssembly(AssemblyBindResult bindResult, string assemblyPath = null) { - RuntimeAssembly result = null; + RuntimeAssembly? result = null; GetNativeFormatRuntimeAssembly(bindResult, ref result); if (result != null) @@ -131,8 +131,8 @@ private static RuntimeAssembly GetRuntimeAssembly(AssemblyBindResult bindResult, } // Use C# partial method feature to avoid complex #if logic, whichever code files are included will drive behavior - static partial void GetNativeFormatRuntimeAssembly(AssemblyBindResult bindResult, ref RuntimeAssembly runtimeAssembly); - static partial void GetEcmaRuntimeAssembly(AssemblyBindResult bindResult, string assemblyPath, ref RuntimeAssembly runtimeAssembly); + static partial void GetNativeFormatRuntimeAssembly(AssemblyBindResult bindResult, ref RuntimeAssembly? runtimeAssembly); + static partial void GetEcmaRuntimeAssembly(AssemblyBindResult bindResult, string assemblyPath, ref RuntimeAssembly? runtimeAssembly); } } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/Helpers.NativeFormat.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/Helpers.NativeFormat.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/Helpers.NativeFormat.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/Helpers.NativeFormat.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/Helpers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/Helpers.cs similarity index 94% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/Helpers.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/Helpers.cs index 2541bc60506662..51847c8e868c30 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/Helpers.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/Helpers.cs @@ -78,7 +78,7 @@ public static RuntimeNamedTypeInfo CastToRuntimeNamedTypeInfo(this Type type) public static RuntimeTypeInfo CastToRuntimeTypeInfo(this Type type) { Debug.Assert(type == null || type is RuntimeTypeInfo); - return (RuntimeTypeInfo)type; + return (RuntimeTypeInfo)type!; } public static ReadOnlyCollection ToReadOnlyCollection(this IEnumerable enumeration) @@ -161,16 +161,12 @@ public static RuntimeMethodInfo GetInvokeMethod(this RuntimeTypeInfo delegateTyp { Debug.Assert(delegateType.IsDelegate); - MethodInfo invokeMethod = delegateType.GetMethod("Invoke", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); + MethodInfo? invokeMethod = delegateType.GetMethod("Invoke", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly); if (invokeMethod == null) { // No Invoke method found. Since delegate types are compiler constructed, the most likely cause is missing metadata rather than // a missing Invoke method. - - // We're deliberating calling FullName rather than ToString() because if it's the type that's missing metadata, - // the FullName property constructs a more informative MissingMetadataException than we can. - string fullName = delegateType.FullName; - throw new MissingMetadataException(SR.Format(SR.Arg_InvokeMethodMissingMetadata, fullName)); // No invoke method found. + throw ReflectionCoreExecution.ExecutionDomain.CreateMissingMetadataException(delegateType); } return (RuntimeMethodInfo)invokeMethod; } @@ -207,7 +203,7 @@ public static object[] InstantiateAsArray(this IEnumerable return result; } - public static bool GetCustomAttributeDefaultValueIfAny(IEnumerable customAttributes, bool raw, out object defaultValue) + public static bool GetCustomAttributeDefaultValueIfAny(IEnumerable customAttributes, bool raw, out object? defaultValue) { // Legacy: If there are multiple default value attribute, the desktop picks one at random (and so do we...) foreach (CustomAttributeData cad in customAttributes) diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/IRuntimeMemberInfoWithNoMetadataDefinition.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/IRuntimeMemberInfoWithNoMetadataDefinition.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/IRuntimeMemberInfoWithNoMetadataDefinition.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/IRuntimeMemberInfoWithNoMetadataDefinition.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/LegacyCustomAttributeApis.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/LegacyCustomAttributeApis.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/LegacyCustomAttributeApis.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/LegacyCustomAttributeApis.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/ListBuilder.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/ListBuilder.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/ListBuilder.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/ListBuilder.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/MetadataReaderExtensions.NativeFormat.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/MetadataReaderExtensions.NativeFormat.cs similarity index 97% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/MetadataReaderExtensions.NativeFormat.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/MetadataReaderExtensions.NativeFormat.cs index 1c9480246005d4..3a1244dee62333 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/MetadataReaderExtensions.NativeFormat.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/MetadataReaderExtensions.NativeFormat.cs @@ -9,6 +9,7 @@ using System.Collections; using System.Collections.Generic; using System.Reflection.Runtime.Assemblies; +using System.Runtime.CompilerServices; using Internal.LowLevelLinq; using Internal.Reflection.Core; @@ -23,6 +24,8 @@ namespace System.Reflection.Runtime.General // // Collect various metadata reading tasks for better chunking... // + [ReflectionBlocked] + [CLSCompliant(false)] public static class NativeFormatMetadataReaderExtensions { public static bool StringOrNullEquals(this ConstantStringValueHandle handle, string valueOrNull, MetadataReader reader) @@ -221,8 +224,8 @@ private static Exception ParseBoxedEnumConstantValue(this ConstantBoxedEnumValue { ConstantBoxedEnumValue record = handle.GetConstantBoxedEnumValue(reader); - Exception exception = null; - Type enumType = record.Type.TryResolve(reader, new TypeContext(null, null), ref exception); + Exception? exception = null; + Type? enumType = record.Type.TryResolve(reader, new TypeContext(null, null), ref exception); if (enumType == null) { value = null; @@ -317,9 +320,9 @@ private static Exception ParseBoxedEnumConstantValue(this ConstantBoxedEnumValue } } - public static object ParseConstantValue(this Handle handle, MetadataReader reader) + public static object? ParseConstantValue(this Handle handle, MetadataReader reader) { - object value; + object? value; Exception exception = handle.TryParseConstantValue(reader, out value); if (exception != null) throw exception; @@ -359,7 +362,7 @@ public static object ParseConstantNumericValue(this Handle handle, MetadataReade } } - public static Exception TryParseConstantValue(this Handle handle, MetadataReader reader, out object value) + public static Exception TryParseConstantValue(this Handle handle, MetadataReader reader, out object? value) { HandleType handleType = handle.HandleType; switch (handleType) @@ -385,8 +388,8 @@ public static Exception TryParseConstantValue(this Handle handle, MetadataReader case HandleType.TypeReference: case HandleType.TypeSpecification: { - Exception exception = null; - Type type = handle.TryResolve(reader, new TypeContext(null, null), ref exception); + Exception? exception = null; + Type? type = handle.TryResolve(reader, new TypeContext(null, null), ref exception); value = type; return (value == null) ? exception : null; } @@ -399,7 +402,7 @@ public static Exception TryParseConstantValue(this Handle handle, MetadataReader } default: { - Exception exception; + Exception? exception; value = handle.TryParseConstantArray(reader, out exception); if (value == null) return exception; @@ -408,7 +411,7 @@ public static Exception TryParseConstantValue(this Handle handle, MetadataReader } } - private static Array TryParseConstantArray(this Handle handle, MetadataReader reader, out Exception exception) + private static Array TryParseConstantArray(this Handle handle, MetadataReader reader, out Exception? exception) { exception = null; @@ -461,11 +464,11 @@ private static Array TryParseConstantArray(this Handle handle, MetadataReader re int i = 0; foreach (Handle constantHandle in constantHandles) { - object elementValue; + object? elementValue; exception = constantHandle.TryParseConstantValue(reader, out elementValue); if (exception != null) return null; - elements[i] = (string)elementValue; + elements[i] = (string)elementValue!; i++; } return elements; @@ -474,7 +477,7 @@ private static Array TryParseConstantArray(this Handle handle, MetadataReader re case HandleType.ConstantHandleArray: { HandleCollection constantHandles = handle.ToConstantHandleArrayHandle(reader).GetConstantHandleArray(reader).Value; - object[] elements = new object[constantHandles.Count]; + object?[] elements = new object[constantHandles.Count]; int i = 0; foreach (Handle constantHandle in constantHandles) { @@ -490,12 +493,12 @@ private static Array TryParseConstantArray(this Handle handle, MetadataReader re } } - private static Array TryParseConstantEnumArray(this ConstantEnumArrayHandle handle, MetadataReader reader, out Exception exception) + private static Array TryParseConstantEnumArray(this ConstantEnumArrayHandle handle, MetadataReader reader, out Exception? exception) { exception = null; ConstantEnumArray enumArray = handle.GetConstantEnumArray(reader); - Type elementType = enumArray.ElementType.TryResolve(reader, new TypeContext(null, null), ref exception); + Type? elementType = enumArray.ElementType.TryResolve(reader, new TypeContext(null, null), ref exception); if (exception != null) return null; @@ -630,7 +633,7 @@ public static string ToNamespaceName(this NamespaceDefinitionHandle namespaceDef continue; } - throw new BadImageFormatException(SR.Bif_InvalidMetadata); + throw new BadImageFormatException(); } return ns; } diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/MetadataReaderExtensions.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/MetadataReaderExtensions.cs similarity index 96% rename from src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/MetadataReaderExtensions.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/MetadataReaderExtensions.cs index fa4cc683585740..35d240d925b3e2 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/MetadataReaderExtensions.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/MetadataReaderExtensions.cs @@ -2,17 +2,20 @@ // The .NET Foundation licenses this file to you under the MIT license. -using global::System; -using global::System.Reflection; -using global::System.Collections.Generic; +using System; +using System.Reflection; +using System.Collections.Generic; +using System.Runtime.CompilerServices; -using global::Internal.Metadata.NativeFormat; +using Internal.Metadata.NativeFormat; using Debug = System.Diagnostics.Debug; using AssemblyFlags = Internal.Metadata.NativeFormat.AssemblyFlags; namespace System.Reflection.Runtime.General { + [ReflectionBlocked] + [CLSCompliant(false)] public static partial class MetadataReaderExtensions { /// diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/NamespaceChain.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/NamespaceChain.cs similarity index 97% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/NamespaceChain.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/NamespaceChain.cs index 34b97186d7507e..dd52a03e6b5af9 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/NamespaceChain.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/NamespaceChain.cs @@ -39,7 +39,7 @@ internal NamespaceChain(MetadataReader reader, NamespaceDefinitionHandle innerMo continue; } - throw new BadImageFormatException(SR.Bif_InvalidMetadata); + throw new BadImageFormatException(); } DefiningScope = currentNamespaceHandle.ToScopeDefinitionHandle(reader); diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/NativeFormat/DefaultValueParser.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/NativeFormat/DefaultValueParser.cs similarity index 93% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/NativeFormat/DefaultValueParser.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/NativeFormat/DefaultValueParser.cs index 0da7bd27a6fd29..24fd595d5bd09f 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/NativeFormat/DefaultValueParser.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/NativeFormat/DefaultValueParser.cs @@ -8,7 +8,7 @@ namespace System.Reflection.Runtime.General.NativeFormat { internal static class DefaultValueParser { - public static bool GetDefaultValueIfAny(MetadataReader reader, Handle constantHandle, Type declaredType, IEnumerable customAttributes, bool raw, out object defaultValue) + public static bool GetDefaultValueIfAny(MetadataReader reader, Handle constantHandle, Type declaredType, IEnumerable customAttributes, bool raw, out object? defaultValue) { if (!(constantHandle.IsNull(reader))) { diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/System/Reflection/Runtime/General/QHandles.NativeFormat.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/QHandles.NativeFormat.cs similarity index 99% rename from src/coreclr/nativeaot/System.Private.TypeLoader/src/System/Reflection/Runtime/General/QHandles.NativeFormat.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/QHandles.NativeFormat.cs index 08ad466e41a0c5..087f2cfdcf087d 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/System/Reflection/Runtime/General/QHandles.NativeFormat.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/QHandles.NativeFormat.cs @@ -14,7 +14,6 @@ namespace System.Reflection.Runtime.General { - public partial struct QMethodDefinition { public QMethodDefinition(MetadataReader reader, MethodHandle handle) diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/System/Reflection/Runtime/General/QHandles.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/QHandles.cs similarity index 93% rename from src/coreclr/nativeaot/System.Private.TypeLoader/src/System/Reflection/Runtime/General/QHandles.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/QHandles.cs index 2f47be124a0a28..f8c7e014c857e7 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/System/Reflection/Runtime/General/QHandles.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/QHandles.cs @@ -8,12 +8,15 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Runtime.CompilerServices; using Internal.Metadata.NativeFormat; using Internal.Runtime.TypeLoader; namespace Internal.Reflection.Core { + [ReflectionBlocked] + [CLSCompliant(false)] public struct QScopeDefinition : IEquatable { public QScopeDefinition(MetadataReader reader, ScopeDefinitionHandle handle) @@ -60,6 +63,8 @@ public override int GetHashCode() namespace System.Reflection.Runtime.General { + [ReflectionBlocked] + [CLSCompliant(false)] public struct QHandle : IEquatable { public QHandle(MetadataReader reader, Handle handle) @@ -96,6 +101,8 @@ public override int GetHashCode() private readonly Handle _handle; } + [ReflectionBlocked] + [CLSCompliant(false)] public partial struct QMethodDefinition { private QMethodDefinition(object reader, int token) @@ -120,6 +127,8 @@ public static QMethodDefinition FromObjectAndInt(object reader, int token) private readonly int _handle; } + [ReflectionBlocked] + [CLSCompliant(false)] public partial struct QTypeDefinition { public object Reader { get { return _reader; } } @@ -134,6 +143,8 @@ public partial struct QTypeDefinition } + [ReflectionBlocked] + [CLSCompliant(false)] public partial struct QTypeDefRefOrSpec { public object Reader { get { return _reader; } } @@ -147,6 +158,8 @@ public partial struct QTypeDefRefOrSpec private readonly int _handle; } + [ReflectionBlocked] + [CLSCompliant(false)] public struct QGenericParameter : IEquatable { public QGenericParameter(MetadataReader reader, GenericParameterHandle handle) diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/QSignatureTypeHandle.NativeFormat.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/QSignatureTypeHandle.NativeFormat.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/QSignatureTypeHandle.NativeFormat.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/QSignatureTypeHandle.NativeFormat.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/QSignatureTypeHandle.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/QSignatureTypeHandle.cs similarity index 87% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/QSignatureTypeHandle.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/QSignatureTypeHandle.cs index b1307eea2f27a5..59925d98a73fd8 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/QSignatureTypeHandle.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/QSignatureTypeHandle.cs @@ -9,9 +9,12 @@ using System.Collections.Generic; using System.Diagnostics; using System.Reflection.Runtime.TypeInfos; +using System.Runtime.CompilerServices; namespace System.Reflection.Runtime.General { + [ReflectionBlocked] + [CLSCompliant(false)] public partial struct QSignatureTypeHandle { public object Reader { get { return _reader; } } @@ -23,14 +26,14 @@ public partial struct QSignatureTypeHandle internal RuntimeTypeInfo Resolve(TypeContext typeContext) { - Exception exception = null; - RuntimeTypeInfo runtimeType = TryResolve(typeContext, ref exception); + Exception? exception = null; + RuntimeTypeInfo? runtimeType = TryResolve(typeContext, ref exception); if (runtimeType == null) - throw exception; + throw exception!; return runtimeType; } - internal RuntimeTypeInfo TryResolve(TypeContext typeContext, ref Exception exception) + internal RuntimeTypeInfo? TryResolve(TypeContext typeContext, ref Exception? exception) { if (Reader is global::Internal.Metadata.NativeFormat.MetadataReader) { @@ -70,8 +73,8 @@ internal string FormatTypeName(TypeContext typeContext) // Though we wrap this in a try-catch as a failsafe, this code must still strive to avoid triggering MissingMetadata exceptions // (non-error exceptions are very annoying when debugging.) - Exception exception = null; - RuntimeTypeInfo runtimeType = TryResolve(typeContext, ref exception); + Exception? exception = null; + RuntimeTypeInfo? runtimeType = TryResolve(typeContext, ref exception); if (runtimeType == null) return Type.DefaultTypeNameWhenMissingMetadata; diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/ReflectionCoreCallbacksImplementation.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/ReflectionCoreCallbacksImplementation.cs similarity index 99% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/ReflectionCoreCallbacksImplementation.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/ReflectionCoreCallbacksImplementation.cs index 0b211124f26b83..c1321e4a4797df 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/ReflectionCoreCallbacksImplementation.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/ReflectionCoreCallbacksImplementation.cs @@ -183,7 +183,7 @@ public sealed override object ActivatorCreateInstance( [DebuggerStepThrough] public sealed override object ActivatorCreateInstance( [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] - Type type, BindingFlags bindingAttr, Binder? binder, object[]? args, CultureInfo? culture, object[]? activationAttributes) + Type type, BindingFlags bindingAttr, Binder? binder, object?[]? args, CultureInfo? culture, object?[]? activationAttributes) { return ActivatorImplementation.CreateInstance(type, bindingAttr, binder, args, culture, activationAttributes); } @@ -323,7 +323,7 @@ private static RuntimeMethodInfo LookupMethodForCreateDelegate(RuntimeTypeInfo r while (containingType != null) { - MethodInfo methodInfo = containingType.GetMethod(method, 0, bindingFlags, null, parameterTypes, null); + MethodInfo? methodInfo = containingType.GetMethod(method, 0, bindingFlags, null, parameterTypes, null); if (methodInfo != null && methodInfo.ReturnType.Equals(invokeMethod.ReturnType)) return (RuntimeMethodInfo)methodInfo; // This cast is safe since we already verified that containingType is runtime implemented. diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/RuntimeTypeHandleKey.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/RuntimeTypeHandleKey.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/RuntimeTypeHandleKey.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/RuntimeTypeHandleKey.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/ThunkedApis.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/ThunkedApis.cs similarity index 95% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/ThunkedApis.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/ThunkedApis.cs index 295c9f8777aa70..1eb4d3dcd69ab1 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/ThunkedApis.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/ThunkedApis.cs @@ -41,7 +41,7 @@ public sealed override Stream GetManifestResourceStream(Type type, string name) } else { - string nameSpace = type.Namespace; + string? nameSpace = type.Namespace; if (nameSpace != null) { sb.Append(nameSpace); @@ -68,8 +68,9 @@ public override string Location } } + [Obsolete("Assembly.CodeBase and Assembly.EscapedCodeBase are only included for .NET Framework compatibility. Use Assembly.Location.", DiagnosticId = "SYSLIB0012", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")] - public sealed override string CodeBase + public sealed override string? CodeBase { get { @@ -175,7 +176,7 @@ public sealed override Type[] GetGenericArguments() [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2073:UnrecognizedReflectionPattern", Justification = "The returned interface is one of the interfaces implemented by this type and does have DynamicallyAccessedMemberTypes.Interfaces")] - public sealed override Type GetInterface(string name, bool ignoreCase) + public sealed override Type? GetInterface(string name, bool ignoreCase) { if (name == null) throw new ArgumentNullException("fullname" /* Yep, CoreCLR names this different than the ref assembly */); @@ -184,7 +185,7 @@ public sealed override Type GetInterface(string name, bool ignoreCase) string ns; SplitTypeName(name, out simpleName, out ns); - Type match = null; + Type? match = null; foreach (Type ifc in ImplementedInterfaces) { string ifcSimpleName = ifc.Name; diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/ToStringUtils.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/ToStringUtils.cs similarity index 97% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/ToStringUtils.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/ToStringUtils.cs index 9fe84bac777aee..0a9ff9c82f83aa 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/ToStringUtils.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/ToStringUtils.cs @@ -21,7 +21,7 @@ public static string FormatTypeName(this QTypeDefRefOrSpec qualifiedTypeHandle, // Though we wrap this in a try-catch as a failsafe, this code must still strive to avoid triggering MissingMetadata exceptions // (non-error exceptions are very annoying when debugging.) - Exception exception = null; + Exception? exception = null; RuntimeTypeInfo runtimeType = qualifiedTypeHandle.TryResolve(typeContext, ref exception); if (runtimeType == null) return Type.DefaultTypeNameWhenMissingMetadata; diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/TypeContext.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/TypeContext.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/TypeContext.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/TypeContext.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/TypeForwardInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/TypeForwardInfo.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/TypeForwardInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/TypeForwardInfo.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/TypeResolver.NativeFormat.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/TypeResolver.NativeFormat.cs similarity index 85% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/TypeResolver.NativeFormat.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/TypeResolver.NativeFormat.cs index aa2a4ebf61618d..838f6a1f6dfa11 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/TypeResolver.NativeFormat.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/TypeResolver.NativeFormat.cs @@ -27,14 +27,14 @@ internal static partial class TypeResolver // internal static RuntimeTypeInfo Resolve(this Handle typeDefRefOrSpec, MetadataReader reader, TypeContext typeContext) { - Exception exception = null; - RuntimeTypeInfo runtimeType = typeDefRefOrSpec.TryResolve(reader, typeContext, ref exception); + Exception? exception = null; + RuntimeTypeInfo? runtimeType = typeDefRefOrSpec.TryResolve(reader, typeContext, ref exception); if (runtimeType == null) - throw exception; + throw exception!; return runtimeType; } - internal static RuntimeTypeInfo TryResolve(this Handle typeDefRefOrSpec, MetadataReader reader, TypeContext typeContext, ref Exception exception) + internal static RuntimeTypeInfo? TryResolve(this Handle typeDefRefOrSpec, MetadataReader reader, TypeContext typeContext, ref Exception? exception) { HandleType handleType = typeDefRefOrSpec.HandleType; if (handleType == HandleType.TypeDefinition) @@ -64,7 +64,7 @@ internal static RuntimeTypeInfo ResolveTypeDefinition(this TypeDefinitionHandle // // Main routine to parse a metadata type specification signature. // - private static RuntimeTypeInfo TryResolveTypeSignature(this TypeSpecificationHandle typeSpecHandle, MetadataReader reader, TypeContext typeContext, ref Exception exception) + private static RuntimeTypeInfo? TryResolveTypeSignature(this TypeSpecificationHandle typeSpecHandle, MetadataReader reader, TypeContext typeContext, ref Exception? exception) { Handle typeHandle = typeSpecHandle.GetTypeSpecification(reader).Signature; switch (typeHandle.HandleType) @@ -75,7 +75,7 @@ private static RuntimeTypeInfo TryResolveTypeSignature(this TypeSpecificationHan int rank = sig.Rank; if (rank <= 0) throw new BadImageFormatException(); // Bad rank. - RuntimeTypeInfo elementType = sig.ElementType.TryResolve(reader, typeContext, ref exception); + RuntimeTypeInfo? elementType = sig.ElementType.TryResolve(reader, typeContext, ref exception); if (elementType == null) return null; return elementType.GetMultiDimArrayType(rank); @@ -84,7 +84,7 @@ private static RuntimeTypeInfo TryResolveTypeSignature(this TypeSpecificationHan case HandleType.ByReferenceSignature: { ByReferenceSignature sig = typeHandle.ToByReferenceSignatureHandle(reader).GetByReferenceSignature(reader); - RuntimeTypeInfo targetType = sig.Type.TryResolve(reader, typeContext, ref exception); + RuntimeTypeInfo? targetType = sig.Type.TryResolve(reader, typeContext, ref exception); if (targetType == null) return null; return targetType.GetByRefType(); @@ -99,7 +99,7 @@ private static RuntimeTypeInfo TryResolveTypeSignature(this TypeSpecificationHan case HandleType.PointerSignature: { PointerSignature sig = typeHandle.ToPointerSignatureHandle(reader).GetPointerSignature(reader); - RuntimeTypeInfo targetType = sig.Type.TryResolve(reader, typeContext, ref exception); + RuntimeTypeInfo? targetType = sig.Type.TryResolve(reader, typeContext, ref exception); if (targetType == null) return null; return targetType.GetPointerType(); @@ -108,7 +108,7 @@ private static RuntimeTypeInfo TryResolveTypeSignature(this TypeSpecificationHan case HandleType.SZArraySignature: { SZArraySignature sig = typeHandle.ToSZArraySignatureHandle(reader).GetSZArraySignature(reader); - RuntimeTypeInfo elementType = sig.ElementType.TryResolve(reader, typeContext, ref exception); + RuntimeTypeInfo? elementType = sig.ElementType.TryResolve(reader, typeContext, ref exception); if (elementType == null) return null; return elementType.GetArrayType(); @@ -122,13 +122,13 @@ private static RuntimeTypeInfo TryResolveTypeSignature(this TypeSpecificationHan case HandleType.TypeInstantiationSignature: { TypeInstantiationSignature sig = typeHandle.ToTypeInstantiationSignatureHandle(reader).GetTypeInstantiationSignature(reader); - RuntimeTypeInfo genericTypeDefinition = sig.GenericType.TryResolve(reader, typeContext, ref exception); + RuntimeTypeInfo? genericTypeDefinition = sig.GenericType.TryResolve(reader, typeContext, ref exception); if (genericTypeDefinition == null) return null; LowLevelList genericTypeArguments = new LowLevelList(); foreach (Handle genericTypeArgumentHandle in sig.GenericTypeArguments) { - RuntimeTypeInfo genericTypeArgument = genericTypeArgumentHandle.TryResolve(reader, typeContext, ref exception); + RuntimeTypeInfo? genericTypeArgument = genericTypeArgumentHandle.TryResolve(reader, typeContext, ref exception); if (genericTypeArgument == null) return null; genericTypeArguments.Add(genericTypeArgument); @@ -157,7 +157,7 @@ private static RuntimeTypeInfo TryResolveTypeSignature(this TypeSpecificationHan // [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2075:UnrecognizedReflectionPattern", Justification = "Resolves type references within metadata. We ensure metadata is consistent.")] - private static RuntimeTypeInfo TryResolveTypeReference(this TypeReferenceHandle typeReferenceHandle, MetadataReader reader, ref Exception exception) + private static RuntimeTypeInfo? TryResolveTypeReference(this TypeReferenceHandle typeReferenceHandle, MetadataReader reader, ref Exception? exception) { RuntimeTypeHandle resolvedRuntimeTypeHandle; if (ReflectionCoreExecution.ExecutionEnvironment.TryGetNamedTypeForTypeReference(reader, typeReferenceHandle, out resolvedRuntimeTypeHandle)) @@ -167,7 +167,7 @@ private static RuntimeTypeInfo TryResolveTypeReference(this TypeReferenceHandle string name = typeReference.TypeName.GetString(reader); Handle parent = typeReference.ParentNamespaceOrType; HandleType parentType = parent.HandleType; - TypeInfo outerTypeInfo = null; + TypeInfo? outerTypeInfo = null; // Check if this is a reference to a nested type. @@ -177,7 +177,7 @@ private static RuntimeTypeInfo TryResolveTypeReference(this TypeReferenceHandle } else if (parentType == HandleType.TypeReference) { - RuntimeTypeInfo outerType = parent.ToTypeReferenceHandle(reader).TryResolveTypeReference(reader, ref exception); + RuntimeTypeInfo? outerType = parent.ToTypeReferenceHandle(reader).TryResolveTypeReference(reader, ref exception); if (outerType == null) return null; outerTypeInfo = outerType; // Since we got to outerType via a metadata reference, we're assured GetTypeInfo() won't throw a MissingMetadataException. @@ -185,7 +185,7 @@ private static RuntimeTypeInfo TryResolveTypeReference(this TypeReferenceHandle if (outerTypeInfo != null) { // It was a nested type. We've already resolved the containing type recursively - just find the nested among its direct children. - TypeInfo resolvedTypeInfo = outerTypeInfo.GetDeclaredNestedType(name); + TypeInfo? resolvedTypeInfo = outerTypeInfo.GetDeclaredNestedType(name); if (resolvedTypeInfo == null) { exception = ReflectionCoreExecution.ExecutionDomain.CreateMissingMetadataException(outerTypeInfo, name); diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/TypeResolver.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/TypeResolver.cs similarity index 95% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/TypeResolver.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/TypeResolver.cs index fcf6e8d4470b04..f4665d08665672 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/TypeResolver.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/TypeResolver.cs @@ -24,14 +24,14 @@ internal static partial class TypeResolver // internal static RuntimeTypeInfo Resolve(this QTypeDefRefOrSpec typeDefOrRefOrSpec, TypeContext typeContext) { - Exception exception = null; + Exception? exception = null; RuntimeTypeInfo runtimeType = typeDefOrRefOrSpec.TryResolve(typeContext, ref exception); if (runtimeType == null) - throw exception; + throw exception!; return runtimeType; } - internal static RuntimeTypeInfo TryResolve(this QTypeDefRefOrSpec typeDefOrRefOrSpec, TypeContext typeContext, ref Exception exception) + internal static RuntimeTypeInfo TryResolve(this QTypeDefRefOrSpec typeDefOrRefOrSpec, TypeContext typeContext, ref Exception? exception) { if (typeDefOrRefOrSpec.IsNativeFormatMetadataBased) { diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/TypeUnifier.NativeFormat.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/TypeUnifier.NativeFormat.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/TypeUnifier.NativeFormat.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/TypeUnifier.NativeFormat.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/TypeUnifier.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/TypeUnifier.cs similarity index 99% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/TypeUnifier.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/TypeUnifier.cs index e9f8abb56ebfe2..cdc37f01a1b53d 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/TypeUnifier.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/General/TypeUnifier.cs @@ -117,7 +117,7 @@ private static RuntimeConstructedGenericTypeInfo WithVerifiedTypeHandle(this Run public static RuntimeTypeInfo GetTypeForRuntimeTypeHandle(this RuntimeTypeHandle typeHandle) { - Type type = Type.GetTypeFromHandle(typeHandle); + Type type = Type.GetTypeFromHandle(typeHandle)!; return type.CastToRuntimeTypeInfo(); } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/CustomMethodInvoker.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/CustomMethodInvoker.cs similarity index 95% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/CustomMethodInvoker.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/CustomMethodInvoker.cs index 9a00c6995cbe39..3ae697e0b84ad3 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/CustomMethodInvoker.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/CustomMethodInvoker.cs @@ -21,7 +21,7 @@ public CustomMethodInvoker(Type thisType, Type[] parameterTypes, InvokerOptions _parameterTypes = parameterTypes; } - protected sealed override object Invoke(object thisObject, object[] arguments, BinderBundle binderBundle, bool wrapInTargetInvocationException) + protected sealed override object? Invoke(object? thisObject, object?[] arguments, BinderBundle binderBundle, bool wrapInTargetInvocationException) { Debug.Assert(arguments != null); diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/CustomMethodInvokerAction.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/CustomMethodInvokerAction.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/CustomMethodInvokerAction.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/CustomMethodInvokerAction.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/CustomMethodMapper.Nullable.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/CustomMethodMapper.Nullable.cs similarity index 94% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/CustomMethodMapper.Nullable.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/CustomMethodMapper.Nullable.cs index bda098b67e7382..2b3c78ff342700 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/CustomMethodMapper.Nullable.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/CustomMethodMapper.Nullable.cs @@ -77,8 +77,9 @@ public static Dictionary Map map.AddMethod(type, nameof(Nullable.GetValueOrDefault), Array.Empty(), NullableGetValueOrDefault); + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2067:ParameterDoesntMeetParameterRequirements", + Justification = "Constructed MethodTable of a Nullable forces a constructed MethodTable of the element type")] static object NullableGetValueOrDefault(object thisObject, object[] args, - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type thisType) { if (thisObject == null) diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/CustomMethodMapper.String.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/CustomMethodMapper.String.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/CustomMethodMapper.String.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/CustomMethodMapper.String.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/CustomMethodMapper.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/CustomMethodMapper.cs similarity index 93% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/CustomMethodMapper.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/CustomMethodMapper.cs index 5848b2ed96b47b..6b81aaaeb2bf21 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/CustomMethodMapper.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/CustomMethodMapper.cs @@ -16,7 +16,7 @@ internal static partial class CustomMethodMapper // public static MethodInvoker GetCustomMethodInvokerIfNeeded(this MethodBase methodBase) { - Type declaringType = methodBase.DeclaringType; + Type declaringType = methodBase.DeclaringType!; bool isNullable = declaringType.IsConstructedGenericType && declaringType.GetGenericTypeDefinition() == typeof(Nullable<>); Dictionary map; @@ -27,7 +27,7 @@ public static MethodInvoker GetCustomMethodInvokerIfNeeded(this MethodBase metho else return null; - if (!(map.TryGetValue(methodBase.MetadataDefinitionMethod, out CustomMethodInvokerAction action))) + if (!map.TryGetValue(methodBase.MetadataDefinitionMethod, out CustomMethodInvokerAction? action)) return null; ParameterInfo[] parameterInfos = methodBase.GetParametersNoCopy(); @@ -52,7 +52,7 @@ private static void AddMethod(this Dictionary 0); - RuntimeTypeHandle[] genericArgHandles; + RuntimeTypeHandle[]? genericArgHandles; if (genericArgs != null) { genericArgHandles = new RuntimeTypeHandle[genericArgs.Length]; @@ -200,9 +200,9 @@ public RuntimeMethodHandle GetRuntimeMethodHandle(Type[] genericArgs) genericArgHandles = null; } - TypeManagerHandle typeManager = TypeLoaderEnvironment.Instance.ModuleList.GetModuleForMetadataReader(Reader); + TypeManagerHandle typeManager = RuntimeAugments.TypeLoaderCallbacks.GetModuleForMetadataReader(Reader); - return TypeLoaderEnvironment.Instance.GetRuntimeMethodHandleForComponents( + return RuntimeAugments.TypeLoaderCallbacks.GetRuntimeMethodHandleForComponents( DeclaringType.TypeHandle, Name, RuntimeSignature.CreateFromMethodHandle(typeManager, MethodHandle.AsInt()), diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/OpenMethodInvoker.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/OpenMethodInvoker.cs similarity index 86% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/OpenMethodInvoker.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/OpenMethodInvoker.cs index 945cc9e2a94d05..49e7f618c2518a 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/OpenMethodInvoker.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/OpenMethodInvoker.cs @@ -14,7 +14,7 @@ namespace System.Reflection.Runtime.MethodInfos { internal sealed class OpenMethodInvoker : MethodInvoker { - protected sealed override object Invoke(object thisObject, object[] arguments, BinderBundle binderBundle, bool wrapInTargetInvocationException) + protected sealed override object? Invoke(object? thisObject, object?[] arguments, BinderBundle binderBundle, bool wrapInTargetInvocationException) { throw new InvalidOperationException(SR.Arg_UnboundGenParam); } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeClsIdNullaryConstructorInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeClsIdNullaryConstructorInfo.cs similarity index 97% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeClsIdNullaryConstructorInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeClsIdNullaryConstructorInfo.cs index 7f5dde597cce89..5c5d30bbb9d438 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeClsIdNullaryConstructorInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeClsIdNullaryConstructorInfo.cs @@ -27,7 +27,7 @@ private RuntimeCLSIDNullaryConstructorInfo(RuntimeCLSIDTypeInfo declaringType) public sealed override MethodAttributes Attributes => MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; public sealed override CallingConventions CallingConvention => CallingConventions.Standard | CallingConventions.HasThis; - public sealed override IEnumerable CustomAttributes => Empty.Enumerable; + public sealed override IEnumerable CustomAttributes => Array.Empty(); public sealed override Type DeclaringType => _declaringType; public sealed override bool HasSameMetadataDefinitionAs(MemberInfo other) @@ -50,7 +50,7 @@ public sealed override bool Equals(object obj) public sealed override int GetHashCode() => _declaringType.GetHashCode(); - public sealed override object Invoke(BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture) + public sealed override object Invoke(BindingFlags invokeAttr, Binder binder, object?[]? parameters, CultureInfo culture) { throw new PlatformNotSupportedException(); } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructedGenericMethodInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructedGenericMethodInfo.cs similarity index 98% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructedGenericMethodInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructedGenericMethodInfo.cs index e46d25dd91f5d6..53cf1f0f963cca 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructedGenericMethodInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructedGenericMethodInfo.cs @@ -75,7 +75,7 @@ public sealed override int GetHashCode() return _genericMethodDefinition.GetHashCode(); } - public sealed override int GenericParameterCount => _genericMethodDefinition.GenericParameterCount; + internal sealed override int GenericParameterCount => _genericMethodDefinition.GenericParameterCount; public sealed override MethodInfo GetGenericMethodDefinition() { diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructorInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructorInfo.cs similarity index 94% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructorInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructorInfo.cs index 708e25cc99035b..3550d71105014b 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructorInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeConstructorInfo.cs @@ -66,10 +66,10 @@ public sealed override ParameterInfo[] GetParametersNoCopy() public abstract override bool HasSameMetadataDefinitionAs(MemberInfo other); - public abstract override object Invoke(BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture); + public abstract override object Invoke(BindingFlags invokeAttr, Binder? binder, object?[]? parameters, CultureInfo? culture); [DebuggerGuidedStepThrough] - public sealed override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture) + public sealed override object Invoke(object? obj, BindingFlags invokeAttr, Binder? binder, object?[]? parameters, CultureInfo? culture) { if (parameters == null) parameters = Array.Empty(); @@ -98,9 +98,9 @@ public sealed override object Invoke(object obj, BindingFlags invokeAttr, Binder throw; } - object result = methodInvoker.Invoke(obj, parameters, binder, invokeAttr, culture); + object? result = methodInvoker.Invoke(obj, parameters, binder, invokeAttr, culture); System.Diagnostics.DebugAnnotations.PreviousCallContainsDebuggerStepInCode(); - return result; + return result!; } public abstract override MethodBase MetadataDefinitionMethod { get; } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeDummyMethodInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeDummyMethodInfo.cs similarity index 97% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeDummyMethodInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeDummyMethodInfo.cs index 9220b3a0bb6ebb..409186ad654295 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeDummyMethodInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeDummyMethodInfo.cs @@ -31,7 +31,7 @@ private RuntimeDummyMethodInfo() { } public sealed override bool IsConstructedGenericMethod { get { throw NotImplemented.ByDesign; } } public sealed override bool IsGenericMethod { get { throw NotImplemented.ByDesign; } } public sealed override bool IsGenericMethodDefinition { get { throw NotImplemented.ByDesign; } } - public sealed override int GenericParameterCount { get { throw NotImplemented.ByDesign; } } + internal sealed override int GenericParameterCount { get { throw NotImplemented.ByDesign; } } public sealed override bool HasSameMetadataDefinitionAs(MemberInfo other) { throw NotImplemented.ByDesign; } public sealed override MethodImplAttributes MethodImplementationFlags { get { throw NotImplemented.ByDesign; } } public sealed override Module Module { get { throw NotImplemented.ByDesign; } } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeMethodHelpers.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeMethodHelpers.cs similarity index 98% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeMethodHelpers.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeMethodHelpers.cs index 2f17ba860e9493..48921164924297 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeMethodHelpers.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeMethodHelpers.cs @@ -105,7 +105,7 @@ internal static string ComputeToString(MethodBase contextMethod, RuntimeTypeInfo { sb.Append(sep); sep = ","; - string name = methodTypeArgument.InternalNameIfAvailable; + string? name = methodTypeArgument.InternalNameIfAvailable; if (name == null) name = Type.DefaultTypeNameWhenMissingMetadata; sb.Append(methodTypeArgument.Name); diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeMethodInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeMethodInfo.cs similarity index 98% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeMethodInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeMethodInfo.cs index 3d9fc962699bfc..e9907db30eb9cc 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeMethodInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeMethodInfo.cs @@ -132,7 +132,7 @@ public sealed override Type[] GetGenericArguments() return RuntimeGenericArgumentsOrParameters.CloneTypeArray(); } - public abstract override int GenericParameterCount { get; } + internal abstract override int GenericParameterCount { get; } public abstract override MethodInfo GetGenericMethodDefinition(); @@ -161,12 +161,12 @@ public sealed override ParameterInfo[] GetParametersNoCopy() public abstract override bool HasSameMetadataDefinitionAs(MemberInfo other); [DebuggerGuidedStepThroughAttribute] - public sealed override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture) + public sealed override object? Invoke(object? obj, BindingFlags invokeAttr, Binder binder, object?[]? parameters, CultureInfo culture) { if (parameters == null) parameters = Array.Empty(); MethodInvoker methodInvoker = this.MethodInvoker; - object result = methodInvoker.Invoke(obj, parameters, binder, invokeAttr, culture); + object? result = methodInvoker.Invoke(obj, parameters, binder, invokeAttr, culture); System.Diagnostics.DebugAnnotations.PreviousCallContainsDebuggerStepInCode(); return result; } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeNamedMethodInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeNamedMethodInfo.cs similarity index 97% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeNamedMethodInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeNamedMethodInfo.cs index 252c556e21d240..c75d371be48d77 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeNamedMethodInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeNamedMethodInfo.cs @@ -117,7 +117,7 @@ public sealed override bool IsGenericMethodDefinition } } - public sealed override int GenericParameterCount => _common.GenericParameterCount; + internal sealed override int GenericParameterCount => _common.GenericParameterCount; [RequiresDynamicCode("The native code for this instantiation might not be available at runtime.")] [RequiresUnreferencedCode("If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), trimming can't validate that the requirements of those annotations are met.")] @@ -135,7 +135,7 @@ public sealed override MethodInfo MakeGenericMethod(params Type[] typeArguments) throw new ArgumentNullException(); if (typeArgument is not RuntimeType) - throw new ArgumentException(SR.Format(SR.Reflection_CustomReflectionObjectsNotSupported, typeArguments[i]), "typeArguments[" + i + "]"); // Not a runtime type. + throw new PlatformNotSupportedException(SR.Format(SR.Reflection_CustomReflectionObjectsNotSupported, typeArguments[i])); if (typeArgument.IsByRefLike) throw new BadImageFormatException(SR.CannotUseByRefLikeTypeInInstantiation); @@ -318,7 +318,7 @@ internal sealed override MethodInvoker GetUncachedMethodInvoker(RuntimeTypeInfo[ static Type Unwrap(Type t) { while (t.HasElementType) - t = t.GetElementType(); + t = t.GetElementType()!; return t; } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimePlainConstructorInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimePlainConstructorInfo.cs similarity index 98% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimePlainConstructorInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimePlainConstructorInfo.cs index bd911ac844f621..acd2980e29194c 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimePlainConstructorInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimePlainConstructorInfo.cs @@ -76,7 +76,7 @@ public sealed override Type DeclaringType } [DebuggerGuidedStepThrough] - public sealed override object Invoke(BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture) + public sealed override object Invoke(BindingFlags invokeAttr, Binder? binder, object?[]? parameters, CultureInfo? culture) { if (parameters == null) parameters = Array.Empty(); @@ -86,7 +86,7 @@ public sealed override object Invoke(BindingFlags invokeAttr, Binder binder, obj // Reflection.Core does not hardcode these special cases. It's up to the ExecutionEnvironment to steer // us the right way by coordinating the implementation of NewObject and MethodInvoker. object newObject = ReflectionCoreExecution.ExecutionEnvironment.NewObject(this.DeclaringType.TypeHandle); - object ctorAllocatedObject = this.MethodInvoker.Invoke(newObject, parameters, binder, invokeAttr, culture); + object ctorAllocatedObject = this.MethodInvoker.Invoke(newObject, parameters, binder, invokeAttr, culture)!; System.Diagnostics.DebugAnnotations.PreviousCallContainsDebuggerStepInCode(); return newObject ?? ctorAllocatedObject; } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeSyntheticConstructorInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeSyntheticConstructorInfo.cs similarity index 97% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeSyntheticConstructorInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeSyntheticConstructorInfo.cs index f6129972b3169a..939535180b69eb 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeSyntheticConstructorInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeSyntheticConstructorInfo.cs @@ -48,7 +48,7 @@ public sealed override IEnumerable CustomAttributes { get { - return Empty.Enumerable; + return Array.Empty(); } } @@ -77,12 +77,12 @@ public sealed override int MetadataToken } [DebuggerGuidedStepThrough] - public sealed override object Invoke(BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture) + public sealed override object Invoke(BindingFlags invokeAttr, Binder? binder, object?[]? parameters, CultureInfo? culture) { if (parameters == null) parameters = Array.Empty(); - object ctorAllocatedObject = this.MethodInvoker.Invoke(null, parameters, binder, invokeAttr, culture); + object ctorAllocatedObject = this.MethodInvoker.Invoke(null, parameters, binder, invokeAttr, culture)!; System.Diagnostics.DebugAnnotations.PreviousCallContainsDebuggerStepInCode(); return ctorAllocatedObject; } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeSyntheticMethodInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeSyntheticMethodInfo.cs similarity index 98% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeSyntheticMethodInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeSyntheticMethodInfo.cs index 4d432d988244f5..8a03a7a2f3192a 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/RuntimeSyntheticMethodInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/RuntimeSyntheticMethodInfo.cs @@ -50,7 +50,7 @@ public sealed override IEnumerable CustomAttributes { get { - return Empty.Enumerable; + return Array.Empty(); } } @@ -108,7 +108,7 @@ public sealed override bool IsGenericMethodDefinition } } - public sealed override int GenericParameterCount => 0; + internal sealed override int GenericParameterCount => 0; [RequiresDynamicCode("The native code for this instantiation might not be available at runtime.")] [RequiresUnreferencedCode("If some of the generic arguments are annotated (either with DynamicallyAccessedMembersAttribute, or generic constraints), trimming can't validate that the requirements of those annotations are met.")] diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/SyntheticMethodId.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/SyntheticMethodId.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/SyntheticMethodId.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/SyntheticMethodId.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/VirtualRuntimeParameterInfoArray.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/VirtualRuntimeParameterInfoArray.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/MethodInfos/VirtualRuntimeParameterInfoArray.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/MethodInfos/VirtualRuntimeParameterInfoArray.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Modules/NativeFormat/NativeFormatRuntimeModule.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Modules/NativeFormat/NativeFormatRuntimeModule.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Modules/NativeFormat/NativeFormatRuntimeModule.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Modules/NativeFormat/NativeFormatRuntimeModule.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Modules/RuntimeModule.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Modules/RuntimeModule.cs similarity index 97% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Modules/RuntimeModule.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Modules/RuntimeModule.cs index c799a3db28a5e6..c98f84cb4f6d39 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/Modules/RuntimeModule.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Modules/RuntimeModule.cs @@ -25,8 +25,6 @@ protected RuntimeModule() public abstract override IEnumerable CustomAttributes { get; } - internal const string UnknownStringMessageInRAF = "Returns for modules with no file path"; - [RequiresAssemblyFiles(UnknownStringMessageInRAF)] public sealed override string FullyQualifiedName { diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/ParameterInfos/NativeFormat/NativeFormatMethodParameterInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/ParameterInfos/NativeFormat/NativeFormatMethodParameterInfo.cs similarity index 98% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/ParameterInfos/NativeFormat/NativeFormatMethodParameterInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/ParameterInfos/NativeFormat/NativeFormatMethodParameterInfo.cs index 9ca09006384523..3a49e94a9bd35a 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/ParameterInfos/NativeFormat/NativeFormatMethodParameterInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/ParameterInfos/NativeFormat/NativeFormatMethodParameterInfo.cs @@ -64,7 +64,7 @@ public sealed override int MetadataToken protected sealed override IEnumerable TrueCustomAttributes => RuntimeCustomAttributeData.GetCustomAttributes(this.Reader, _parameter.CustomAttributes); - protected sealed override bool GetDefaultValueIfAvailable(bool raw, out object defaultValue) + protected sealed override bool GetDefaultValueIfAvailable(bool raw, out object? defaultValue) { return DefaultValueParser.GetDefaultValueIfAny(Reader, _parameter.DefaultValue, ParameterType, CustomAttributes, raw, out defaultValue); } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/ParameterInfos/RuntimeFatMethodParameterInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/ParameterInfos/RuntimeFatMethodParameterInfo.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/ParameterInfos/RuntimeFatMethodParameterInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/ParameterInfos/RuntimeFatMethodParameterInfo.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/ParameterInfos/RuntimeMethodParameterInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/ParameterInfos/RuntimeMethodParameterInfo.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/ParameterInfos/RuntimeMethodParameterInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/ParameterInfos/RuntimeMethodParameterInfo.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/ParameterInfos/RuntimeParameterInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/ParameterInfos/RuntimeParameterInfo.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/ParameterInfos/RuntimeParameterInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/ParameterInfos/RuntimeParameterInfo.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/ParameterInfos/RuntimePropertyIndexParameterInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/ParameterInfos/RuntimePropertyIndexParameterInfo.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/ParameterInfos/RuntimePropertyIndexParameterInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/ParameterInfos/RuntimePropertyIndexParameterInfo.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/ParameterInfos/RuntimeSyntheticParameterInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/ParameterInfos/RuntimeSyntheticParameterInfo.cs similarity index 97% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/ParameterInfos/RuntimeSyntheticParameterInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/ParameterInfos/RuntimeSyntheticParameterInfo.cs index 505f8109297a41..2f68d703a80df3 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/ParameterInfos/RuntimeSyntheticParameterInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/ParameterInfos/RuntimeSyntheticParameterInfo.cs @@ -36,7 +36,7 @@ public sealed override IEnumerable CustomAttributes { get { - return Empty.Enumerable; + return Array.Empty(); } } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/ParameterInfos/RuntimeThinMethodParameterInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/ParameterInfos/RuntimeThinMethodParameterInfo.cs similarity index 97% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/ParameterInfos/RuntimeThinMethodParameterInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/ParameterInfos/RuntimeThinMethodParameterInfo.cs index cb53a3648beaa3..b1c543238de156 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/ParameterInfos/RuntimeThinMethodParameterInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/ParameterInfos/RuntimeThinMethodParameterInfo.cs @@ -34,7 +34,7 @@ public sealed override IEnumerable CustomAttributes { get { - return Empty.Enumerable; + return Array.Empty(); } } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/PropertyInfos/EcmaFormat/EcmaFormatRuntimePropertyInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/PropertyInfos/EcmaFormat/EcmaFormatRuntimePropertyInfo.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/PropertyInfos/EcmaFormat/EcmaFormatRuntimePropertyInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/PropertyInfos/EcmaFormat/EcmaFormatRuntimePropertyInfo.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/PropertyInfos/NativeFormat/NativeFormatRuntimePropertyInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/PropertyInfos/NativeFormat/NativeFormatRuntimePropertyInfo.cs similarity index 99% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/PropertyInfos/NativeFormat/NativeFormatRuntimePropertyInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/PropertyInfos/NativeFormat/NativeFormatRuntimePropertyInfo.cs index 23d45271e63a31..d87734708878cc 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/PropertyInfos/NativeFormat/NativeFormatRuntimePropertyInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/PropertyInfos/NativeFormat/NativeFormatRuntimePropertyInfo.cs @@ -127,7 +127,7 @@ protected sealed override QSignatureTypeHandle PropertyTypeHandle } } - protected sealed override bool GetDefaultValueIfAny(bool raw, out object defaultValue) + protected sealed override bool GetDefaultValueIfAny(bool raw, out object? defaultValue) { return DefaultValueParser.GetDefaultValueIfAny(_reader, _property.DefaultValue, PropertyType, CustomAttributes, raw, out defaultValue); } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/PropertyInfos/RuntimePropertyInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/PropertyInfos/RuntimePropertyInfo.cs similarity index 96% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/PropertyInfos/RuntimePropertyInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/PropertyInfos/RuntimePropertyInfo.cs index 32fb5ffa92644b..440eb9487952d3 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/PropertyInfos/RuntimePropertyInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/PropertyInfos/RuntimePropertyInfo.cs @@ -123,7 +123,7 @@ public sealed override MethodInfo GetMethod public sealed override Type[] GetRequiredCustomModifiers() => PropertyTypeHandle.GetCustomModifiers(ContextTypeInfo.TypeContext, optional: false); - public sealed override object GetValue(object obj, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture) + public sealed override object? GetValue(object? obj, BindingFlags invokeAttr, Binder? binder, object?[]? index, CultureInfo culture) { if (_lazyGetterInvoker == null) { @@ -186,7 +186,7 @@ public sealed override MethodInfo SetMethod } } - public sealed override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture) + public sealed override void SetValue(object? obj, object? value, BindingFlags invokeAttr, Binder? binder, object?[]? index, CultureInfo culture) { if (_lazySetterInvoker == null) { @@ -195,10 +195,10 @@ public sealed override void SetValue(object obj, object value, BindingFlags invo _lazySetterInvoker = Setter.GetUncachedMethodInvoker(Array.Empty(), this); } - object[] arguments; + object?[] arguments; if (index == null) { - arguments = new object[] { value }; + arguments = new object?[] { value }; } else { diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfo.cs similarity index 96% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfo.cs index 4144e4ae4d9fa9..b4789f8af68d17 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfo.cs @@ -58,7 +58,7 @@ protected sealed override int InternalGetHashCode() protected MetadataReader Reader { get; } - public sealed override string InternalGetNameIfAvailable(ref Type rootCauseForFailure) + internal sealed override string? InternalGetNameIfAvailable(ref Type? rootCauseForFailure) { if (_genericParameter.Name.IsNull(Reader)) return string.Empty; diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfoForMethods.UnificationKey.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfoForMethods.UnificationKey.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfoForMethods.UnificationKey.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfoForMethods.UnificationKey.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfoForMethods.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfoForMethods.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfoForMethods.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfoForMethods.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfoForTypes.UnificationKey.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfoForTypes.UnificationKey.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfoForTypes.UnificationKey.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfoForTypes.UnificationKey.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfoForTypes.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfoForTypes.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfoForTypes.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeGenericParameterTypeInfoForTypes.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeNamedTypeInfo.UnificationKey.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeNamedTypeInfo.UnificationKey.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeNamedTypeInfo.UnificationKey.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeNamedTypeInfo.UnificationKey.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeNamedTypeInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeNamedTypeInfo.cs similarity index 97% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeNamedTypeInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeNamedTypeInfo.cs index 80b394decba949..18c175185421fb 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeNamedTypeInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeNamedTypeInfo.cs @@ -106,7 +106,7 @@ public sealed override int MetadataToken public sealed override string ToString() { - StringBuilder sb = null; + StringBuilder? sb = null; foreach (GenericParameterHandle genericParameterHandle in _typeDefinition.GenericParameters) { @@ -148,7 +148,7 @@ internal sealed override Type InternalDeclaringType { get { - RuntimeTypeInfo declaringType = null; + RuntimeTypeInfo? declaringType = null; TypeDefinitionHandle enclosingTypeDefHandle = _typeDefinition.EnclosingType; if (!enclosingTypeDefHandle.IsNull(_reader)) { @@ -168,7 +168,7 @@ internal sealed override string InternalFullNameOfAssembly } } - public sealed override string InternalGetNameIfAvailable(ref Type rootCauseForFailure) + internal sealed override string? InternalGetNameIfAvailable(ref Type? rootCauseForFailure) { ConstantStringValueHandle nameHandle = _typeDefinition.Name; string name = nameHandle.GetString(_reader); @@ -271,10 +271,10 @@ internal PropertyHandleCollection DeclaredPropertyHandles } } - public bool Equals(NativeFormatRuntimeNamedTypeInfo other) + public bool Equals(NativeFormatRuntimeNamedTypeInfo? other) { // RuntimeTypeInfo.Equals(object) is the one that encapsulates our unification strategy so defer to him. - object otherAsObject = other; + object? otherAsObject = other; return base.Equals(otherAsObject); } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeTypeInfo.CoreGetDeclared.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeTypeInfo.CoreGetDeclared.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeTypeInfo.CoreGetDeclared.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/NativeFormat/NativeFormatRuntimeTypeInfo.CoreGetDeclared.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeArrayTypeInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeArrayTypeInfo.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeArrayTypeInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeArrayTypeInfo.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeBlockedTypeInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeBlockedTypeInfo.cs similarity index 98% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeBlockedTypeInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeBlockedTypeInfo.cs index c6835e724ef944..1e560f7f6991df 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeBlockedTypeInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeBlockedTypeInfo.cs @@ -56,7 +56,7 @@ public sealed override IEnumerable CustomAttributes { get { - return Empty.Enumerable; + return Array.Empty(); } } @@ -172,7 +172,7 @@ internal sealed override Type InternalDeclaringType } } - public sealed override string InternalGetNameIfAvailable(ref Type rootCauseForFailure) + internal sealed override string? InternalGetNameIfAvailable(ref Type? rootCauseForFailure) { return GeneratedName; } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeByRefTypeInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeByRefTypeInfo.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeByRefTypeInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeByRefTypeInfo.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeClsIdTypeInfo.UnificationKey.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeClsIdTypeInfo.UnificationKey.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeClsIdTypeInfo.UnificationKey.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeClsIdTypeInfo.UnificationKey.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeClsIdTypeInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeClsIdTypeInfo.cs similarity index 95% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeClsIdTypeInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeClsIdTypeInfo.cs index 0e6fda3edaa72d..1c767450be9962 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeClsIdTypeInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeClsIdTypeInfo.cs @@ -28,7 +28,7 @@ private RuntimeCLSIDTypeInfo(Guid clsid, string server) public sealed override bool ContainsGenericParameters => false; public sealed override string FullName => BaseType.FullName; public sealed override Guid GUID => _key.ClsId; - public sealed override string InternalGetNameIfAvailable(ref Type rootCauseForFailure) => BaseType.InternalGetNameIfAvailable(ref rootCauseForFailure); + internal sealed override string? InternalGetNameIfAvailable(ref Type? rootCauseForFailure) => BaseType.InternalGetNameIfAvailable(ref rootCauseForFailure); public sealed override bool IsGenericTypeDefinition => false; public sealed override int MetadataToken => BaseType.MetadataToken; public sealed override string Namespace => BaseType.Namespace; @@ -39,7 +39,7 @@ public sealed override IEnumerable CustomAttributes { get { - return Empty.Enumerable; + return Array.Empty(); } } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeConstructedGenericTypeInfo.UnificationKey.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeConstructedGenericTypeInfo.UnificationKey.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeConstructedGenericTypeInfo.UnificationKey.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeConstructedGenericTypeInfo.UnificationKey.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeConstructedGenericTypeInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeConstructedGenericTypeInfo.cs similarity index 98% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeConstructedGenericTypeInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeConstructedGenericTypeInfo.cs index 5cd6c23e8ca3a1..a2a010de909cef 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeConstructedGenericTypeInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeConstructedGenericTypeInfo.cs @@ -172,7 +172,7 @@ public sealed override string ToString() { // Get the FullName of the generic type definition in a pay-for-play safe way. RuntimeTypeInfo genericTypeDefinition = GenericTypeDefinitionTypeInfo; - string genericTypeDefinitionString = null; + string? genericTypeDefinitionString = null; if (genericTypeDefinition.InternalNameIfAvailable != null) // Want to avoid "cry-wolf" exceptions: if we can't even get the simple name, don't bother getting the FullName. { // Given our current pay for play policy, it should now be safe to attempt getting the FullName. (But guard with a try-catch in case this assumption is wrong.) @@ -259,7 +259,7 @@ internal sealed override string InternalFullNameOfAssembly } } - public sealed override string InternalGetNameIfAvailable(ref Type rootCauseForFailure) + internal sealed override string? InternalGetNameIfAvailable(ref Type? rootCauseForFailure) { return GenericTypeDefinitionTypeInfo.InternalGetNameIfAvailable(ref rootCauseForFailure); } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeGenericParameterTypeInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeGenericParameterTypeInfo.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeGenericParameterTypeInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeGenericParameterTypeInfo.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeHasElementTypeInfo.UnificationKey.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeHasElementTypeInfo.UnificationKey.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeHasElementTypeInfo.UnificationKey.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeHasElementTypeInfo.UnificationKey.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeHasElementTypeInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeHasElementTypeInfo.cs similarity index 95% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeHasElementTypeInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeHasElementTypeInfo.cs index 05a65a8c80a972..67fe290b14997f 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeHasElementTypeInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeHasElementTypeInfo.cs @@ -77,7 +77,7 @@ public sealed override IEnumerable CustomAttributes { get { - return Empty.Enumerable; + return Array.Empty(); } } @@ -162,9 +162,9 @@ internal sealed override Type InternalDeclaringType } } - public sealed override string InternalGetNameIfAvailable(ref Type rootCauseForFailure) + internal sealed override string? InternalGetNameIfAvailable(ref Type? rootCauseForFailure) { - string elementTypeName = _key.ElementType.InternalGetNameIfAvailable(ref rootCauseForFailure); + string? elementTypeName = _key.ElementType.InternalGetNameIfAvailable(ref rootCauseForFailure); if (elementTypeName == null) { rootCauseForFailure = _key.ElementType; diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeNamedTypeInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeNamedTypeInfo.cs similarity index 96% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeNamedTypeInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeNamedTypeInfo.cs index ddf99822a3ff32..ff70df743ffd21 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeNamedTypeInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeNamedTypeInfo.cs @@ -47,10 +47,10 @@ public sealed override IEnumerable CustomAttributes } } - public bool Equals(RuntimeNamedTypeInfo other) + public bool Equals(RuntimeNamedTypeInfo? other) { // RuntimeTypeInfo.Equals(object) is the one that encapsulates our unification strategy so defer to him. - object otherAsObject = other; + object? otherAsObject = other; return base.Equals(otherAsObject); } @@ -93,10 +93,10 @@ public sealed override string FullName string name = Name; - Type declaringType = this.DeclaringType; - if (declaringType != null) + Type? declaringType = this.DeclaringType; + if (declaringType is not null) { - string declaringTypeFullName = declaringType.FullName; + string? declaringTypeFullName = declaringType.FullName; return declaringTypeFullName + "+" + name; } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeNoMetadataNamedTypeInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeNoMetadataNamedTypeInfo.cs similarity index 98% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeNoMetadataNamedTypeInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeNoMetadataNamedTypeInfo.cs index 2939a881e75d28..7176f4901bc6b9 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeNoMetadataNamedTypeInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeNoMetadataNamedTypeInfo.cs @@ -152,7 +152,7 @@ internal sealed override Type InternalDeclaringType } } - public sealed override string InternalGetNameIfAvailable(ref Type rootCauseForFailure) + internal sealed override string? InternalGetNameIfAvailable(ref Type? rootCauseForFailure) { rootCauseForFailure = this; return null; diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimePointerTypeInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimePointerTypeInfo.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimePointerTypeInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimePointerTypeInfo.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeDefinitionTypeInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeDefinitionTypeInfo.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeDefinitionTypeInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeDefinitionTypeInfo.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.BindingFlags.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.BindingFlags.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.BindingFlags.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.BindingFlags.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.CoreGetDeclared.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.CoreGetDeclared.cs similarity index 96% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.CoreGetDeclared.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.CoreGetDeclared.cs index 0fd1fccfc35741..d97fada651f205 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.CoreGetDeclared.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.CoreGetDeclared.cs @@ -38,7 +38,7 @@ internal IEnumerable CoreGetDeclaredConstructors(NameFilter opt if (definingType != null) { // If there is a definingType, we do not support Synthetic constructors - Debug.Assert(object.ReferenceEquals(SyntheticConstructors, Empty.Enumerable)); + Debug.Assert(object.ReferenceEquals(SyntheticConstructors, Array.Empty())); return definingType.CoreGetDeclaredConstructors(optionalNameFilter, this); } @@ -61,7 +61,7 @@ internal IEnumerable CoreGetDeclaredMethods(NameFilter optionalNameF if (definingType != null) { // If there is a definingType, we do not support Synthetic constructors - Debug.Assert(object.ReferenceEquals(SyntheticMethods, Empty.Enumerable)); + Debug.Assert(object.ReferenceEquals(SyntheticMethods, Array.Empty())); return definingType.CoreGetDeclaredMethods(optionalNameFilter, reflectedType, this); } @@ -85,7 +85,7 @@ internal IEnumerable CoreGetDeclaredEvents(NameFilter optionalNameFil { return definingType.CoreGetDeclaredEvents(optionalNameFilter, reflectedType, this); } - return Empty.Enumerable; + return Array.Empty(); } internal IEnumerable CoreGetDeclaredFields(NameFilter optionalNameFilter, RuntimeTypeInfo reflectedType) @@ -95,7 +95,7 @@ internal IEnumerable CoreGetDeclaredFields(NameFilter optionalNameFil { return definingType.CoreGetDeclaredFields(optionalNameFilter, reflectedType, this); } - return Empty.Enumerable; + return Array.Empty(); } internal IEnumerable CoreGetDeclaredProperties(NameFilter optionalNameFilter, RuntimeTypeInfo reflectedType) @@ -106,7 +106,7 @@ internal IEnumerable CoreGetDeclaredProperties(NameFilter optional return definingType.CoreGetDeclaredProperties(optionalNameFilter, reflectedType, this); } - return Empty.Enumerable; + return Array.Empty(); } // diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.GetMember.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.GetMember.cs similarity index 84% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.GetMember.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.GetMember.cs index 439343d33027bb..832d741bbb7745 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.GetMember.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.GetMember.cs @@ -32,9 +32,9 @@ public sealed override MemberInfo[] GetMember(string name, MemberTypes type, Bin private MemberInfo[] GetMemberImpl(string optionalNameOrPrefix, MemberTypes type, BindingFlags bindingAttr) { bool prefixSearch = optionalNameOrPrefix != null && optionalNameOrPrefix.EndsWith("*", StringComparison.Ordinal); - string optionalName = prefixSearch ? null : optionalNameOrPrefix; + string? optionalName = prefixSearch ? null : optionalNameOrPrefix; - Func predicate = null; + Func? predicate = null; if (prefixSearch) { bool ignoreCase = (bindingAttr & BindingFlags.IgnoreCase) != 0; @@ -160,20 +160,5 @@ private M QueryMemberWithSameMetadataDefinitionAs(MemberInfo member) where M } return null; } - - // DynamicallyAccessedMemberTypes.All keeps more data than what a member can use: - // - Keeps info about interfaces - // - Complete Nested types (nested type body and all its members including other nested types) - // - Public and private base type information - // Instead, the GetAllMembers constant will keep: - // - The nested types body but not the members - // - Base type public information but not private information. This information should not - // be visible via the derived type and is ignored by reflection - internal const DynamicallyAccessedMemberTypes GetAllMembers = DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields | - DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods | - DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents | - DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties | - DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors | - DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes; } } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.InvokeMember.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.InvokeMember.cs similarity index 90% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.InvokeMember.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.InvokeMember.cs index 77dccda7966be1..aa845932759a34 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.InvokeMember.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.InvokeMember.cs @@ -12,9 +12,9 @@ namespace System.Reflection.Runtime.TypeInfos internal abstract partial class RuntimeTypeInfo { [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] - public sealed override object InvokeMember( - string name, BindingFlags bindingFlags, Binder binder, object target, - object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParams) + public sealed override object? InvokeMember( + string name, BindingFlags bindingFlags, Binder? binder, object? target, + object?[]? providedArgs, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParams) { const BindingFlags MemberBindingMask = (BindingFlags)0x000000FF; const BindingFlags InvocationMask = (BindingFlags)0x0000FF00; @@ -60,7 +60,7 @@ public sealed override object InvokeMember( #region COM Interop if (target != null && target.GetType().IsCOMObject) - throw new PlatformNotSupportedException(SR.Arg_PlatformNotSupportedInvokeMemberCom); + throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); #endregion #region Check that any named paramters are not null @@ -98,13 +98,8 @@ public sealed override object InvokeMember( if (name.Length == 0 || name.Equals(@"[DISPID=0]")) { - name = GetDefaultMemberName(); - - if (name == null) - { - // in InvokeMember we always pretend there is a default member if none is provided and we make it ToString - name = "ToString"; - } + // in InvokeMember we always pretend there is a default member if none is provided and we make it ToString + name = GetDefaultMemberName() ?? "ToString"; } #endregion @@ -143,10 +138,8 @@ public sealed override object InvokeMember( #endregion #region Lookup Field - FieldInfo selFld = null; - FieldInfo[] flds = GetMember(name, MemberTypes.Field, bindingFlags) as FieldInfo[]; - - Debug.Assert(flds != null); + FieldInfo? selFld = null; + FieldInfo[] flds = (FieldInfo[])GetMember(name, MemberTypes.Field, bindingFlags); if (flds.Length == 1) { @@ -177,13 +170,15 @@ public sealed override object InvokeMember( if (idxCnt > 0) { + Debug.Assert(providedArgs != null); + // Verify that all of the index values are ints int[] idx = new int[idxCnt]; for (int i = 0; i < idxCnt; i++) { try { - idx[i] = ((IConvertible)providedArgs[i]).ToInt32(null); + idx[i] = ((IConvertible)providedArgs[i]!).ToInt32(null); } catch (InvalidCastException) { @@ -192,7 +187,7 @@ public sealed override object InvokeMember( } // Set or get the value... - Array a = (Array)selFld.GetValue(target); + Array a = (Array)selFld.GetValue(target)!; // Set or get the value in the array if ((bindingFlags & BindingFlags.GetField) != 0) @@ -264,15 +259,15 @@ public sealed override object InvokeMember( } #endregion - MethodInfo[] finalists = null; - MethodInfo finalist = null; + MethodInfo[]? finalists = null; + MethodInfo? finalist = null; #region BindingFlags.InvokeMethod if ((bindingFlags & BindingFlags.InvokeMethod) != 0) { #region Lookup Methods - MethodInfo[] semiFinalists = GetMember(name, MemberTypes.Method, bindingFlags) as MethodInfo[]; - LowLevelListWithIList results = null; + MethodInfo[] semiFinalists = (MethodInfo[])GetMember(name, MemberTypes.Method, bindingFlags); + LowLevelListWithIList? results = null; for (int i = 0; i < semiFinalists.Length; i++) { @@ -314,12 +309,12 @@ public sealed override object InvokeMember( if (finalist == null && isGetProperty || isSetProperty) { #region Lookup Property - PropertyInfo[] semiFinalists = GetMember(name, MemberTypes.Property, bindingFlags) as PropertyInfo[]; - LowLevelListWithIList results = null; + PropertyInfo[] semiFinalists = (PropertyInfo[])GetMember(name, MemberTypes.Property, bindingFlags); + LowLevelListWithIList? results = null; for (int i = 0; i < semiFinalists.Length; i++) { - MethodInfo semiFinalist; + MethodInfo? semiFinalist; if (isSetProperty) { @@ -386,10 +381,10 @@ public sealed override object InvokeMember( if (providedArgs == null) providedArgs = Array.Empty(); - object state = null; + object? state = null; - MethodBase invokeMethod = null; + MethodBase? invokeMethod = null; try { invokeMethod = binder.BindToMethod(bindingFlags, finalists, ref providedArgs, modifiers, culture, namedParams, out state); } catch (MissingMethodException) { } @@ -400,7 +395,7 @@ public sealed override object InvokeMember( //if (useCache && argCnt == invokeMethod.GetParameters().Length) // AddMethodToCache(name, bindingFlags, argCnt, providedArgs, invokeMethod); - object result = ((MethodInfo)invokeMethod).Invoke(target, bindingFlags, binder, providedArgs, culture); + object? result = ((MethodInfo)invokeMethod).Invoke(target, bindingFlags, binder, providedArgs, culture); if (state != null) binder.ReorderArgumentArray(ref providedArgs, state); diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.TypeComponentsCache.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.TypeComponentsCache.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.TypeComponentsCache.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.TypeComponentsCache.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.cs similarity index 97% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.cs index 647b50e484a932..c52da3fb064814 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeInfos/RuntimeTypeInfo.cs @@ -183,7 +183,7 @@ public sealed override Type[] GenericTypeArguments | DynamicallyAccessedMemberTypes.PublicNestedTypes)] public sealed override MemberInfo[] GetDefaultMembers() { - string defaultMemberName = GetDefaultMemberName(); + string? defaultMemberName = GetDefaultMemberName(); return defaultMemberName != null ? GetMember(defaultMemberName) : Array.Empty(); } @@ -450,10 +450,10 @@ public sealed override Type MakeGenericType(params Type[] typeArguments) // the Type object for an inconsistent generic type - no MethodTable will ever match it so any attempt to "invoke" it // will throw an exception. bool foundSignatureType = false; - RuntimeTypeInfo[] runtimeTypeArguments = new RuntimeTypeInfo[typeArguments.Length]; + RuntimeTypeInfo?[] runtimeTypeArguments = new RuntimeTypeInfo[typeArguments.Length]; for (int i = 0; i < typeArguments.Length; i++) { - RuntimeTypeInfo runtimeTypeArgument = runtimeTypeArguments[i] = typeArguments[i] as RuntimeTypeInfo; + RuntimeTypeInfo? runtimeTypeArgument = runtimeTypeArguments[i] = typeArguments[i] as RuntimeTypeInfo; if (runtimeTypeArgument == null) { if (typeArguments[i] == null) @@ -465,7 +465,7 @@ public sealed override Type MakeGenericType(params Type[] typeArguments) } else { - throw new PlatformNotSupportedException(SR.PlatformNotSupported_MakeGenericType); // "PlatformNotSupported" because on desktop, passing in a foreign type is allowed and creates a RefEmit.TypeBuilder + throw new PlatformNotSupportedException(SR.Format(SR.Reflection_CustomReflectionObjectsNotSupported, typeArguments[i])); } } } @@ -475,7 +475,7 @@ public sealed override Type MakeGenericType(params Type[] typeArguments) for (int i = 0; i < typeArguments.Length; i++) { - RuntimeTypeInfo runtimeTypeArgument = runtimeTypeArguments[i]; + RuntimeTypeInfo runtimeTypeArgument = runtimeTypeArguments[i]!; // Desktop compatibility: Treat generic type definitions as a constructed generic type using the generic parameters as type arguments. if (runtimeTypeArgument.IsGenericTypeDefinition) @@ -485,7 +485,7 @@ public sealed override Type MakeGenericType(params Type[] typeArguments) throw new TypeLoadException(SR.CannotUseByRefLikeTypeInInstantiation); } - return this.GetConstructedGenericTypeWithTypeHandle(runtimeTypeArguments); + return this.GetConstructedGenericTypeWithTypeHandle(runtimeTypeArguments!); } public sealed override Type MakePointerType() @@ -505,8 +505,8 @@ public sealed override string Name { get { - Type rootCauseForFailure = null; - string name = InternalGetNameIfAvailable(ref rootCauseForFailure); + Type? rootCauseForFailure = null; + string? name = InternalGetNameIfAvailable(ref rootCauseForFailure); if (name == null) throw ReflectionCoreExecution.ExecutionDomain.CreateMissingMetadataException(rootCauseForFailure); return name; @@ -614,7 +614,7 @@ internal virtual RuntimeNamedTypeInfo AnchoringTypeDefinitionForDeclaredMembers // internal abstract string InternalFullNameOfAssembly { get; } - public abstract override string InternalGetNameIfAvailable(ref Type rootCauseForFailure); + internal abstract override string? InternalGetNameIfAvailable(ref Type? rootCauseForFailure); // // Left unsealed as HasElement types must override this. @@ -674,7 +674,7 @@ internal virtual IEnumerable SyntheticConstructors { get { - return Empty.Enumerable; + return Array.Empty(); } } @@ -685,7 +685,7 @@ internal virtual IEnumerable SyntheticMethods { get { - return Empty.Enumerable; + return Array.Empty(); } } @@ -776,7 +776,7 @@ internal virtual Type BaseTypeWithoutTheGenericParameterQuirk get { QTypeDefRefOrSpec baseTypeDefRefOrSpec = TypeRefDefOrSpecForBaseType; - RuntimeTypeInfo baseType = null; + RuntimeTypeInfo? baseType = null; if (!baseTypeDefRefOrSpec.IsValid) { baseType = baseTypeDefRefOrSpec.Resolve(this.TypeContext); @@ -785,10 +785,10 @@ internal virtual Type BaseTypeWithoutTheGenericParameterQuirk } } - private string GetDefaultMemberName() + private string? GetDefaultMemberName() { Type defaultMemberAttributeType = typeof(DefaultMemberAttribute); - for (Type type = this; type != null; type = type.BaseType) + for (Type type = this; type != null; type = type.BaseType!) { foreach (CustomAttributeData attribute in type.CustomAttributes) { @@ -800,7 +800,7 @@ private string GetDefaultMemberName() // constructor. Debug.Assert(attribute.ConstructorArguments.Count == 1 && attribute.ConstructorArguments[0].Value is string); - string memberName = (string)(attribute.ConstructorArguments[0].Value); + string? memberName = (string?)(attribute.ConstructorArguments[0].Value); return memberName; } } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeParsing/GetTypeOptions.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeParsing/GetTypeOptions.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeParsing/GetTypeOptions.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeParsing/GetTypeOptions.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeParsing/TypeLexer.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeParsing/TypeLexer.cs similarity index 100% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeParsing/TypeLexer.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeParsing/TypeLexer.cs diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeParsing/TypeName.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeParsing/TypeName.cs similarity index 99% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeParsing/TypeName.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeParsing/TypeName.cs index 91fcf3981c4b29..f4628ac0998c21 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeParsing/TypeName.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeParsing/TypeName.cs @@ -133,7 +133,7 @@ public sealed override Type ResolveType(Assembly containingAssemblyIfAny, GetTyp // Don't change these flags - we may be talking to a third party type here and we need to invoke it the way CoreClr does. BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic; - Type nestedType; + Type? nestedType; if (!getTypeOptions.IgnoreCase) { nestedType = declaringType.GetNestedType(_nestedTypeName, bf); diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeParsing/TypeParser.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeParsing/TypeParser.cs similarity index 99% rename from src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeParsing/TypeParser.cs rename to src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeParsing/TypeParser.cs index 507069941763b2..d51157cc5b41dc 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/TypeParsing/TypeParser.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/TypeParsing/TypeParser.cs @@ -198,7 +198,7 @@ private TypeName ParseGenericTypeArgument() } else if (token == TokenType.OpenSqBracket) { - RuntimeAssemblyName assemblyName = null; + RuntimeAssemblyName? assemblyName = null; NonQualifiedTypeName typeName = ParseNonQualifiedTypeName(); token = _lexer.GetNextToken(); if (token == TokenType.Comma) diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Type.Internal.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Type.Internal.cs index 0d6ec98de9fecc..cad92a13fcc975 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Type.Internal.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Type.Internal.cs @@ -3,6 +3,8 @@ using System.Reflection; +using Internal.Runtime.Augments; + namespace System { // @@ -11,14 +13,24 @@ namespace System // Before adding new entries to this, ask yourself: is it ever referenced by System.Private.CoreLib? // If not, don't put it here. Put it on RuntimeTypeInfo instead. // - // Some of these "internal" methods are declared "public" because both Reflection.Core and System.Private.CoreLib need to reference them. - // public abstract partial class Type { + internal bool TryGetEEType(out EETypePtr eeType) + { + RuntimeTypeHandle typeHandle = RuntimeAugments.Callbacks.GetTypeHandleIfAvailable(this); + if (typeHandle.IsNull) + { + eeType = default(EETypePtr); + return false; + } + eeType = typeHandle.ToEETypePtr(); + return true; + } + /// /// Return Type.Name if sufficient metadata is available to do so - otherwise return null. /// - public string InternalNameIfAvailable + public string? InternalNameIfAvailable { get { @@ -30,7 +42,7 @@ public string InternalNameIfAvailable /// /// Return Type.Name if sufficient metadata is available to do so - otherwise return null and set "rootCauseForFailure" to an object to pass to MissingMetadataException. /// - public virtual string InternalGetNameIfAvailable(ref Type? rootCauseForFailure) => Name; + internal virtual string? InternalGetNameIfAvailable(ref Type? rootCauseForFailure) => Name; /// /// Return Type.Name if sufficient metadata is available to do so - otherwise return a default (non-null) string. @@ -72,7 +84,7 @@ internal string FullNameOrDefault // // The Project N version takes a raw metadata handle rather than a completed type so that it remains robust in the face of missing metadata. // - public string FormatTypeNameForReflection() + internal string FormatTypeNameForReflection() { try { @@ -107,6 +119,6 @@ public string FormatTypeNameForReflection() } } - public const string DefaultTypeNameWhenMissingMetadata = "UnknownType"; + internal const string DefaultTypeNameWhenMissingMetadata = "UnknownType"; } } diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/ILLink/ILLink.Substitutions.xml b/src/coreclr/nativeaot/System.Private.Reflection.Core/src/ILLink/ILLink.Substitutions.xml deleted file mode 100644 index f7df139a82b626..00000000000000 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/ILLink/ILLink.Substitutions.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/Resources/Strings.resx b/src/coreclr/nativeaot/System.Private.Reflection.Core/src/Resources/Strings.resx deleted file mode 100644 index a19d41e9c09d87..00000000000000 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/Resources/Strings.resx +++ /dev/null @@ -1,369 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - A problem was found in this image's metadata. - - - Cannot create an instance of {0} because it is an abstract class. - - - Type initializer was not callable. - - - Cannot set a constant field. - - - A MemberInfo that matches '{0}' could not be found. - - - {0} is not a GenericMethodDefinition. MakeGenericMethod may only be called on a method for which MethodBase.IsGenericMethodDefinition is true. - - - Method may only be called on a Type for which Type.IsGenericParameter is true. - - - A null or zero length string does not represent a valid Type. - - - The type or method has {1} generic parameter(s), but {0} generic argument(s) were provided. A generic argument must be provided for each generic parameter. - - - The object '{0}' was created by a custom ReflectionContext and cannot be used here. - - - The type '{0}' cannot be found. - - - The type '{0}' cannot be found in assembly '{1}'. - - - Cannot load assembly '{0}'. No metadata found for this assembly. - - - Hashtable's capacity overflowed and went negative. Check load factor, capacity and the current size of the table. - - - Cannot bind to the target method because its signature is not compatible with that of the delegate type. - - - Type must derive from Delegate. - - - Cannot create a delegate on type '{0}' as it is missing metadata for the Invoke method. - - - An item with the same key has already been added. Key: {0} - - - The handle is invalid. - - - Type handle '{0}' and method handle with declaring type '{1}' are incompatible. Get RuntimeMethodHandle and declaring RuntimeTypeHandle off the same MethodBase. - - - Type handle '{0}' and field handle with declaring type '{1}' are incompatible. Get RuntimeFieldHandle and declaring RuntimeTypeHandle off the same FieldInfo. - - - Cannot resolve method {0} because the declaring type of the method handle is generic. Explicitly provide the declaring type to GetMethodFromHandle. - - - Cannot resolve field {0} because the declaring type of the field handle is generic. Explicitly provide the declaring type to GetFieldFromHandle. - - - Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true. - - - Type names passed to Assembly.GetType() must not specify an assembly. - - - Cannot add the event handler since no public add method exists for the event. - - - Cannot remove the event handler since no public remove method exists for the event. - - - {0} is not a GenericTypeDefinition. MakeGenericType may only be called on a type for which Type.IsGenericTypeDefinition is true. - - - PlatformNotSupported_MakeGenericType", @"MakeGenericType can only accept Type objects created by the runtime. - - - The type '{0}' may not be used as a type argument. - - - The type '{0}' may not be used as an array element type. - - - TypeHandles are not supported for types that return true for ContainsGenericParameters. - - - Must be an array type. - - - This operation is only valid on generic types. - - - Property get method not found. - - - Property set method not found. - - - Array may not be empty. - - - Member not found. - - - There is no metadata token available for the given member. - - - Field not found. - - - Type must be a type provided by the runtime. - - - ChangeType operation is not supported. - - - No parameterless constructor defined for this object. - - - Activation Attributes are not supported. - - - Vararg calling convention not supported. - - - Cannot create an instance of {0} because Type.ContainsGenericParameters is true. - - - Cannot dynamically create an instance of System.Void. - - - Method must be called on a Type for which Type.IsGenericParameter is false. - - - Must specify binding flags describing the invoke operation required (BindingFlags.InvokeMethod CreateInstance GetField SetField GetProperty SetProperty). - - - Named parameter array cannot be bigger than argument array. - - - Cannot specify both Get and Set on a property. - - - Cannot specify Set on a property and Invoke on a method. - - - Named parameter value must not be null. - - - Cannot specify both CreateInstance and another access type. - - - Cannot specify both Get and Set on a field. - - - Cannot specify both GetField and SetProperty. - - - Cannot specify both SetField and GetProperty. - - - Cannot specify Set on a Field and Invoke on a method. - - - All indexes must be of type Int32. - - - No arguments can be provided to Get a field value. - - - Only the field value can be specified to set a field value. - - - InvokeMember on a COM object is not supported on this platform. - - - Type must be a runtime Type object. - - - MethodInfo must be a runtime MethodInfo object. - - - Array must not be of length zero. - - - FieldInfo must be a runtime FieldInfo object. - - - Field in TypedReferences cannot be static. - - - FieldInfo does not match the target Type. - - - TypedReferences cannot be redefined as primitives. - - - TypedReference can only be made on nested value Types. - - - The TypedReference must be initialized. - - - Cannot create an abstract class. - - - Cannot create an instance of an interface. - - - Cannot create a byref of a byref: {0} - - - Cannot create a pointer to a byref: {0} - - - Literal value was not found. - - - Cannot create boxed ByRef-like values. - - - Cannot instantiate a generic type on a byref-like type. - - - Non-static method requires a target. - - - Object does not match target type. - - - Nullable object must have a value. - - - Interface maps for generic interfaces on arrays cannot be retrieved. - - - CodeBase is not supported on assemblies loaded from a single-file bundle. - - diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System.Private.Reflection.Core.csproj b/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System.Private.Reflection.Core.csproj deleted file mode 100644 index a770233c1ccacd..00000000000000 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System.Private.Reflection.Core.csproj +++ /dev/null @@ -1,200 +0,0 @@ - - - - $(NoWarn);CS0672 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - System\NotImplemented.cs - - - - System\Collections\Generic\LowLevelList.cs - - - System\Collections\Generic\LowLevelDictionary.cs - - - Internal\LowLevelLinq\LowLevelEnumerable.cs - - - Internal\LowLevelLinq\LowLevelEnumerable.ToArray.cs - - - System\Collections\HashHelpers.cs - - - System\Collections\Generic\EnumerableExtensions.cs - - - System\Collections\Generic\Empty.cs - - - System\Collections\Concurrent\ConcurrentUnifier.cs - - - System\Collections\Concurrent\ConcurrentUnifierW.cs - - - System\Collections\Concurrent\ConcurrentUnifierWKeyed.cs - - - System\Collections\Concurrent\IKeyedItem.cs - - - System\Runtime\CompilerServices\DeveloperExperienceModeOnlyAttribute.cs - - - System\Runtime\CompilerServices\DeveloperExperienceState.cs - - - System\Runtime\CompilerServices\__BlockAllReflectionAttribute.cs - - - - - - diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/NonOverriddenApis.cs b/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/NonOverriddenApis.cs deleted file mode 100644 index 61a8b4d76801e6..00000000000000 --- a/src/coreclr/nativeaot/System.Private.Reflection.Core/src/System/Reflection/Runtime/General/NonOverriddenApis.cs +++ /dev/null @@ -1,217 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// Why this file exists: -// -// Because the Reflection base types have so many overridable members, it becomes difficult to distinguish -// members we decided not to override vs. those we forgot to override. It would be nice if C# had a construct to -// tell the reader (and Intellisense) that we've made an explicit decision *not* to override an inherited member, -// but since it doesn't, we'll make do with this instead. -// -// In DEBUG builds, we'll add a base-delegating override so that it's clear we made an explicit decision -// to accept the base class's implementation. In RELEASE builds, we'll #if'd these out to avoid the extra metadata and runtime -// cost. That way, every overridable member is accounted for (i.e. the codebase should always be kept in a state -// where hitting "override" + SPACE never brings up additional suggestions in Intellisense.) -// -// To avoid introducing inadvertent inconsistencies between DEBUG and RELEASE behavior due to the fragile base class -// problem, only do this for public or protected members that already exist on the public api type. Since we know -// we'll never remove those members, we'll avoid the problem of "base" being compile-bound to something different -// from the runtime "base." -// - -using System; -using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Reflection; -using System.Globalization; -using System.Collections.Generic; - -namespace System.Reflection.Runtime.Assemblies -{ - internal partial class RuntimeAssemblyInfo - { -#if DEBUG - [RequiresUnreferencedCode("Assembly.CreateInstance is not supported with trimming. Use Type.GetType instead.")] - public sealed override object CreateInstance(string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture, object[] activationAttributes) => base.CreateInstance(typeName, ignoreCase, bindingAttr, binder, args, culture, activationAttributes); - [RequiresUnreferencedCode("Types might be removed")] - public sealed override Type GetType(string name) => base.GetType(name); - [RequiresUnreferencedCode("Types might be removed")] - public sealed override Type GetType(string name, bool throwOnError) => base.GetType(name, throwOnError); - public sealed override bool IsDynamic => base.IsDynamic; - public sealed override string ToString() => base.ToString(); - [RequiresAssemblyFilesAttribute("The code will return an empty string for assemblies embedded in a single-file app")] -#pragma warning disable SYSLIB0012 - public sealed override string EscapedCodeBase => base.EscapedCodeBase; -#pragma warning restore SYSLIB0012 - [RequiresAssemblyFiles("The code will throw for assemblies embedded in a single-file app")] - public sealed override FileStream[] GetFiles() => base.GetFiles(); -#endif //DEBUG - } -} - -namespace System.Reflection.Runtime.MethodInfos -{ - internal abstract partial class RuntimeConstructorInfo - { -#if DEBUG - public sealed override MemberTypes MemberType => base.MemberType; -#endif //DEBUG - } -} - -namespace System.Reflection.Runtime.CustomAttributes -{ - internal abstract partial class RuntimeCustomAttributeData - { -#if DEBUG - public sealed override bool Equals(object obj) => base.Equals(obj); - public sealed override int GetHashCode() => base.GetHashCode(); -#endif //DEBUG - } -} - -namespace System.Reflection.Runtime.EventInfos -{ - internal abstract partial class RuntimeEventInfo - { -#if DEBUG - public sealed override MemberTypes MemberType => base.MemberType; - public sealed override bool IsMulticast => base.IsMulticast; - public sealed override void AddEventHandler(object target, Delegate handler) => base.AddEventHandler(target, handler); - public sealed override void RemoveEventHandler(object target, Delegate handler) => base.RemoveEventHandler(target, handler); -#endif //DEBUG - } -} - -namespace System.Reflection.Runtime.FieldInfos -{ - internal abstract partial class RuntimeFieldInfo - { -#if DEBUG - public sealed override MemberTypes MemberType => base.MemberType; - public sealed override bool IsSecurityCritical => base.IsSecurityCritical; - public sealed override bool IsSecuritySafeCritical => base.IsSecuritySafeCritical; - public sealed override bool IsSecurityTransparent => base.IsSecurityTransparent; -#endif //DEBUG - } -} - -namespace System.Reflection.Runtime.MethodInfos -{ - internal abstract partial class RuntimeMethodInfo - { -#if DEBUG - public sealed override MemberTypes MemberType => base.MemberType; -#endif //DEBUG - } -} - -namespace System.Reflection.Runtime.Modules -{ - internal abstract partial class RuntimeModule - { -#if DEBUG - [RequiresUnreferencedCode("Types might be removed")] - public sealed override Type[] FindTypes(TypeFilter filter, object filterCriteria) => base.FindTypes(filter, filterCriteria); - [RequiresUnreferencedCode("Types might be removed")] - public sealed override Type GetType(string className) => base.GetType(className); - [RequiresUnreferencedCode("Types might be removed")] - public sealed override Type GetType(string className, bool ignoreCase) => base.GetType(className, ignoreCase); - public sealed override string ToString() => base.ToString(); -#endif //DEBUG - } -} - -namespace System.Reflection.Runtime.ParameterInfos -{ - internal abstract partial class RuntimeParameterInfo - { -#if DEBUG -#endif //DEBUG - } -} - -namespace System.Reflection.Runtime.PropertyInfos -{ - internal abstract partial class RuntimePropertyInfo - { -#if DEBUG - public sealed override MemberTypes MemberType => base.MemberType; - public sealed override object GetValue(object obj, object[] index) => base.GetValue(obj, index); - public sealed override void SetValue(object obj, object value, object[] index) => base.SetValue(obj, value, index); -#endif //DEBUG - } -} - -namespace System.Reflection.Runtime.TypeInfos -{ - internal abstract partial class RuntimeTypeInfo - { -#if DEBUG - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] - public sealed override Type[] FindInterfaces(TypeFilter filter, object filterCriteria) => base.FindInterfaces(filter, filterCriteria); - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] - public sealed override MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter filter, object filterCriteria) => base.FindMembers(memberType, bindingAttr, filter, filterCriteria); - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents)] - public sealed override EventInfo[] GetEvents() => base.GetEvents(); - protected sealed override bool IsContextfulImpl() => base.IsContextfulImpl(); - public sealed override bool IsSubclassOf(Type c) => base.IsSubclassOf(c); - protected sealed override bool IsMarshalByRefImpl() => base.IsMarshalByRefImpl(); - public sealed override bool IsInstanceOfType(object o) => base.IsInstanceOfType(o); - public sealed override bool IsSerializable => base.IsSerializable; - public sealed override bool IsEquivalentTo(Type other) => base.IsEquivalentTo(other); // Note: If we enable COM type equivalence, this is no longer the correct implementation. - public sealed override bool IsSignatureType => base.IsSignatureType; - - public sealed override IEnumerable DeclaredConstructors - { - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] - get => base.DeclaredConstructors; - } - public sealed override IEnumerable DeclaredEvents - { - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] - get => base.DeclaredEvents; - } - public sealed override IEnumerable DeclaredFields - { - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] - get => base.DeclaredFields; - } - public sealed override IEnumerable DeclaredMembers - { - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] - get => base.DeclaredMembers; - } - public sealed override IEnumerable DeclaredMethods - { - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] - get => base.DeclaredMethods; - } - public sealed override IEnumerable DeclaredNestedTypes - { - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] - get => base.DeclaredNestedTypes; - } - public sealed override IEnumerable DeclaredProperties - { - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] - get => base.DeclaredProperties; - } - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] - public sealed override EventInfo GetDeclaredEvent(string name) => base.GetDeclaredEvent(name); - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] - public sealed override FieldInfo GetDeclaredField(string name) => base.GetDeclaredField(name); - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] - public sealed override MethodInfo GetDeclaredMethod(string name) => base.GetDeclaredMethod(name); - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] - public sealed override TypeInfo GetDeclaredNestedType(string name) => base.GetDeclaredNestedType(name); - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] - public sealed override PropertyInfo GetDeclaredProperty(string name) => base.GetDeclaredProperty(name); - - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] - public sealed override IEnumerable GetDeclaredMethods(string name) => base.GetDeclaredMethods(name); -#endif //DEBUG - } -} diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/PayForPlayExperience/MissingMetadataExceptionCreator.cs b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/PayForPlayExperience/MissingMetadataExceptionCreator.cs index db347ad0b787ba..8b25905240d7bd 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/PayForPlayExperience/MissingMetadataExceptionCreator.cs +++ b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/PayForPlayExperience/MissingMetadataExceptionCreator.cs @@ -15,17 +15,17 @@ namespace Internal.Reflection.Execution.PayForPlayExperience { public static class MissingMetadataExceptionCreator { - internal static MissingMetadataException Create(string resourceId, MemberInfo pertainant) + internal static MissingMetadataException Create(string resourceId, MemberInfo? pertainant) { return CreateFromMetadataObject(resourceId, pertainant); } - internal static MissingMetadataException Create(TypeInfo pertainant) + internal static MissingMetadataException Create(TypeInfo? pertainant) { return CreateFromMetadataObject(SR.Reflection_InsufficientMetadata_EdbNeeded, pertainant); } - internal static MissingMetadataException Create(TypeInfo pertainant, string nestedTypeName) + internal static MissingMetadataException Create(TypeInfo? pertainant, string nestedTypeName) { if (pertainant == null) return new MissingMetadataException(SR.Format(SR.Reflection_InsufficientMetadata_NoHelpAvailable, "")); @@ -40,7 +40,7 @@ internal static MissingMetadataException Create(TypeInfo pertainant, string nest } } - internal static MissingMetadataException Create(Type pertainant) + internal static MissingMetadataException Create(Type? pertainant) { return CreateFromMetadataObject(SR.Reflection_InsufficientMetadata_EdbNeeded, pertainant); } @@ -50,7 +50,7 @@ internal static MissingMetadataException Create(RuntimeTypeHandle pertainant) return CreateFromMetadataObject(SR.Reflection_InsufficientMetadata_EdbNeeded, pertainant); } - private static MissingMetadataException CreateFromString(string pertainant) + private static MissingMetadataException CreateFromString(string? pertainant) { if (pertainant == null) return new MissingMetadataException(SR.Format(SR.Reflection_InsufficientMetadata_NoHelpAvailable, "")); @@ -71,7 +71,7 @@ internal static MissingMetadataException CreateMissingConstructedGenericTypeExce return CreateFromString(s); } - internal static MissingMetadataException CreateFromMetadataObject(string resourceId, object pertainant) + internal static MissingMetadataException CreateFromMetadataObject(string resourceId, object? pertainant) { if (pertainant == null) return new MissingMetadataException(SR.Format(SR.Reflection_InsufficientMetadata_NoHelpAvailable, "")); diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/System.Private.Reflection.Execution.csproj b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/System.Private.Reflection.Execution.csproj index e8b65e31ca05f9..d7883b5f2ebe77 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/System.Private.Reflection.Execution.csproj +++ b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/System.Private.Reflection.Execution.csproj @@ -2,7 +2,6 @@ - diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.cs index 702baa4e22ecc6..310534e09451cf 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.cs @@ -25,6 +25,11 @@ namespace Internal.Runtime.TypeLoader { internal class Callbacks : TypeLoaderCallbacks { + public override TypeManagerHandle GetModuleForMetadataReader(MetadataReader reader) + { + return TypeLoaderEnvironment.Instance.ModuleList.GetModuleForMetadataReader(reader); + } + public override bool TryGetConstructedGenericTypeForComponents(RuntimeTypeHandle genericTypeDefinitionHandle, RuntimeTypeHandle[] genericTypeArgumentHandles, out RuntimeTypeHandle runtimeTypeHandle) { return TypeLoaderEnvironment.Instance.TryGetConstructedGenericTypeForComponents(genericTypeDefinitionHandle, genericTypeArgumentHandles, out runtimeTypeHandle); @@ -45,6 +50,11 @@ public override bool GetRuntimeMethodHandleComponents(RuntimeMethodHandle runtim return TypeLoaderEnvironment.Instance.TryGetRuntimeMethodHandleComponents(runtimeMethodHandle, out declaringTypeHandle, out nameAndSignature, out genericMethodArgs); } + public override RuntimeMethodHandle GetRuntimeMethodHandleForComponents(RuntimeTypeHandle declaringTypeHandle, string methodName, RuntimeSignature methodSignature, RuntimeTypeHandle[] genericMethodArgs) + { + return TypeLoaderEnvironment.Instance.GetRuntimeMethodHandleForComponents(declaringTypeHandle, methodName, methodSignature, genericMethodArgs); + } + public override bool CompareMethodSignatures(RuntimeSignature signature1, RuntimeSignature signature2) { return TypeLoaderEnvironment.Instance.CompareMethodSignatures(signature1, signature2); @@ -72,6 +82,11 @@ public override bool GetRuntimeFieldHandleComponents(RuntimeFieldHandle runtimeF return TypeLoaderEnvironment.Instance.TryGetRuntimeFieldHandleComponents(runtimeFieldHandle, out declaringTypeHandle, out fieldName); } + public override RuntimeFieldHandle GetRuntimeFieldHandleForComponents(RuntimeTypeHandle declaringTypeHandle, string fieldName) + { + return TypeLoaderEnvironment.Instance.GetRuntimeFieldHandleForComponents(declaringTypeHandle, fieldName); + } + public override IntPtr ConvertUnboxingFunctionPointerToUnderlyingNonUnboxingPointer(IntPtr unboxingFunctionPointer, RuntimeTypeHandle declaringType) { return TypeLoaderEnvironment.ConvertUnboxingFunctionPointerToUnderlyingNonUnboxingPointer(unboxingFunctionPointer, declaringType); diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/System.Private.TypeLoader.csproj b/src/coreclr/nativeaot/System.Private.TypeLoader/src/System.Private.TypeLoader.csproj index 73332581e50252..b9532d1de4c51e 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/System.Private.TypeLoader.csproj +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/System.Private.TypeLoader.csproj @@ -270,7 +270,6 @@ - @@ -281,7 +280,6 @@ - @@ -328,8 +326,6 @@ - - System\Runtime\CompilerServices\__BlockAllReflectionAttribute.cs diff --git a/src/coreclr/nativeaot/nativeaot.sln b/src/coreclr/nativeaot/nativeaot.sln index f2bbfe6e9fb4a0..7812cd25d4925c 100644 --- a/src/coreclr/nativeaot/nativeaot.sln +++ b/src/coreclr/nativeaot/nativeaot.sln @@ -7,8 +7,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.CoreLib", "S EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.DisabledReflection", "System.Private.DisabledReflection\src\System.Private.DisabledReflection.csproj", "{ADA691AE-4E1F-4212-97E6-51A27EFCE7E4}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.Reflection.Core", "System.Private.Reflection.Core\src\System.Private.Reflection.Core.csproj", "{6147AF1A-5054-492A-9309-FA868A184414}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.Reflection.Execution", "System.Private.Reflection.Execution\src\System.Private.Reflection.Execution.csproj", "{7498DD7C-76C1-4912-AF72-DA84E05B568F}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.StackTraceMetadata", "System.Private.StackTraceMetadata\src\System.Private.StackTraceMetadata.csproj", "{33CAE331-16EE-443C-A0CC-4337B94A02AD}" diff --git a/src/coreclr/vm/typeparse.cpp b/src/coreclr/vm/typeparse.cpp index f5e1a979b018f2..0defa23f4cf072 100644 --- a/src/coreclr/vm/typeparse.cpp +++ b/src/coreclr/vm/typeparse.cpp @@ -1094,7 +1094,7 @@ TypeHandle TypeName::GetTypeFromAsm() { if (bThrowIfNotFound) { - COMPlusThrow(kArgumentException, IDS_EE_ASSEMBLY_GETTYPE_CANNONT_HAVE_ASSEMBLY_SPEC); + COMPlusThrow(kArgumentException, W("Argument_AssemblyGetTypeCannotSpecifyAssembly")); } else { diff --git a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx index 1654cc1cd06df8..3caedf01be9575 100644 --- a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx +++ b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx @@ -2791,6 +2791,9 @@ Cannot create arrays of ByRef-like values. + + Cannot instantiate a generic type on a ByRef-like type. + ByRef to ByRef-like return values are not supported in reflection invocation. @@ -3940,4 +3943,37 @@ {0} is missing delegate marshalling data. To enable delegate marshalling data, add a MarshalDelegate directive to the application rd.xml file. For more information, please visit http://go.microsoft.com/fwlink/?LinkID=393965 - \ No newline at end of file + + Type names passed to Assembly.GetType() must not specify an assembly. + + + There is no metadata token available for the given member. + + + The type '{0}' may not be used as a type argument. + + + The type '{0}' may not be used as an array element type. + + + TypeHandles are not supported for types that return true for ContainsGenericParameters. + + + The type '{0}' was created by a custom ReflectionContext and cannot be used here. + + + Cannot create a byref of a byref: {0} + + + Cannot create a pointer to a byref: {0} + + + The type '{0}' cannot be found. + + + The type '{0}' cannot be found in assembly '{1}'. + + + Cannot load assembly '{0}'. No metadata found for this assembly. + + diff --git a/src/libraries/System.Private.CoreLib/src/System/DefaultBinder.cs b/src/libraries/System.Private.CoreLib/src/System/DefaultBinder.cs index 2bbb99a9d2d312..8c918899d878fb 100644 --- a/src/libraries/System.Private.CoreLib/src/System/DefaultBinder.cs +++ b/src/libraries/System.Private.CoreLib/src/System/DefaultBinder.cs @@ -11,12 +11,7 @@ namespace System { -#if NATIVEAOT - public sealed -#else - internal -#endif - partial class DefaultBinder : Binder + internal partial class DefaultBinder : Binder { // This method is passed a set of methods and must choose the best // fit. The methods all have the same number of arguments and the object diff --git a/src/libraries/System.Private.CoreLib/src/System/Empty.cs b/src/libraries/System.Private.CoreLib/src/System/Empty.cs index c73eb71c368ee3..b110f5303f849b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Empty.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Empty.cs @@ -3,12 +3,7 @@ namespace System { -#if NATIVEAOT - public // Needs to be public so that Reflection.Core can see it. -#else - internal -#endif - sealed class Empty + internal sealed class Empty { private Empty() { diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInfo.Internal.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInfo.Internal.cs index 9cb576fdc9fe15..f4a89403bbbde0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInfo.Internal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodInfo.Internal.cs @@ -5,11 +5,6 @@ namespace System.Reflection { public abstract partial class MethodInfo : MethodBase { -#if NATIVEAOT - public // Needs to be public so that Reflection.Core can see it. -#else - internal -#endif - virtual int GenericParameterCount => GetGenericArguments().Length; + internal virtual int GenericParameterCount => GetGenericArguments().Length; } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/SignatureTypeExtensions.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/SignatureTypeExtensions.cs index e624073af7cc49..ad3158abb302a8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/SignatureTypeExtensions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/SignatureTypeExtensions.cs @@ -5,13 +5,7 @@ namespace System.Reflection { -#if NATIVEAOT - [System.Runtime.CompilerServices.ReflectionBlocked] - public // Needs to be public so that Reflection.Core can see it. -#else - internal -#endif - static class SignatureTypeExtensions + internal static class SignatureTypeExtensions { /// /// This is semantically identical to From 7227526a53578e151aee044380ea5f6c56e779ba Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Sun, 12 Jun 2022 19:56:07 +0200 Subject: [PATCH 068/337] disable ClientOptions_TargetHostNull_OK on Android (#70619) --- .../tests/FunctionalTests/SslAuthenticationOptionsTest.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/SslAuthenticationOptionsTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/SslAuthenticationOptionsTest.cs index 75afa305b54c4b..45c9e171ac512d 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/SslAuthenticationOptionsTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/SslAuthenticationOptionsTest.cs @@ -116,6 +116,7 @@ public async Task ClientOptions_ServerOptions_NotMutatedDuringAuthentication() } [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/68206", TestPlatforms.Android)] public async Task ClientOptions_TargetHostNull_OK() { (SslStream client, SslStream server) = TestHelper.GetConnectedSslStreams(); From d9d6e827d864d66a26ce18ac99ed05f926b1674f Mon Sep 17 00:00:00 2001 From: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> Date: Sun, 12 Jun 2022 22:55:55 +0300 Subject: [PATCH 069/337] Forbid creating layout-less `TYP_STRUCT` `LCL_FLD` nodes (#70170) * Fold ADD(ADDR(LCL_VAR), CONST) => ADDR(LCL_FLD) * Add an assert for layout-less LCL_FLD * Query the handle in "gtGetStructHandleIfPresent" * Add layout checks to "Compare" and "gtHashValue" --- src/coreclr/jit/gentree.cpp | 10 ++- src/coreclr/jit/gentree.h | 4 +- src/coreclr/jit/morph.cpp | 137 ++++++++++++----------------------- src/coreclr/jit/valuenum.cpp | 3 +- 4 files changed, 60 insertions(+), 94 deletions(-) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 70384056e0709a..46cec07a192ffb 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -2396,7 +2396,8 @@ bool GenTree::Compare(GenTree* op1, GenTree* op2, bool swapOK) case GT_LCL_FLD: if ((op1->AsLclFld()->GetLclNum() != op2->AsLclFld()->GetLclNum()) || - (op1->AsLclFld()->GetLclOffs() != op2->AsLclFld()->GetLclOffs())) + (op1->AsLclFld()->GetLclOffs() != op2->AsLclFld()->GetLclOffs()) || + (op1->AsLclFld()->GetLayout() != op2->AsLclFld()->GetLayout())) { break; } @@ -2792,6 +2793,7 @@ unsigned Compiler::gtHashValue(GenTree* tree) break; case GT_LCL_FLD: hash = genTreeHashAdd(hash, tree->AsLclFld()->GetLclNum()); + hash = genTreeHashAdd(hash, tree->AsLclFld()->GetLayout()); add = tree->AsLclFld()->GetLclOffs(); break; @@ -17200,7 +17202,11 @@ CORINFO_CLASS_HANDLE Compiler::gtGetStructHandleIfPresent(GenTree* tree) } #endif } + else #endif + { + structHnd = tree->AsLclFld()->GetLayout()->GetClassHandle(); + } break; case GT_LCL_VAR: { @@ -23128,7 +23134,7 @@ unsigned GenTreeHWIntrinsic::GetResultOpNumForFMA(GenTree* use, GenTree* op1, Ge unsigned GenTreeLclFld::GetSize() const { - return genTypeSize(TypeGet()); + return TypeIs(TYP_STRUCT) ? GetLayout()->GetSize() : genTypeSize(TypeGet()); } #ifdef TARGET_ARM diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index 4f90d3d880df22..5728b9e43fc890 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -3681,9 +3681,10 @@ struct GenTreeLclFld : public GenTreeLclVarCommon public: GenTreeLclFld(genTreeOps oper, var_types type, unsigned lclNum, unsigned lclOffs, ClassLayout* layout = nullptr) - : GenTreeLclVarCommon(oper, type, lclNum), m_lclOffs(static_cast(lclOffs)), m_layout(layout) + : GenTreeLclVarCommon(oper, type, lclNum), m_lclOffs(static_cast(lclOffs)) { assert(lclOffs <= UINT16_MAX); + SetLayout(layout); } uint16_t GetLclOffs() const @@ -3699,6 +3700,7 @@ struct GenTreeLclFld : public GenTreeLclVarCommon ClassLayout* GetLayout() const { + assert(!TypeIs(TYP_STRUCT) || (m_layout != nullptr)); return m_layout; } diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 29ea92a874092a..4e65b06d9a75fc 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -11194,7 +11194,6 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac) */ GenTree* temp; - size_t ival1; GenTree* lclVarTree; GenTree* effectiveOp1; FieldSeqNode* fieldSeq = nullptr; @@ -11571,15 +11570,14 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac) bool foldAndReturnTemp = false; temp = nullptr; - ival1 = 0; // Don't remove a volatile GT_IND, even if the address points to a local variable. - if ((tree->gtFlags & GTF_IND_VOLATILE) == 0) + // + if (!tree->AsIndir()->IsVolatile()) { /* Try to Fold *(&X) into X */ if (op1->gtOper == GT_ADDR) { - // Can not remove a GT_ADDR if it is currently a CSE candidate. if (gtIsActiveCSE_Candidate(op1)) { break; @@ -11679,98 +11677,34 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac) } } #endif // TARGET_ARM - - /* Try to change *(&lcl + cns) into lcl[cns] to prevent materialization of &lcl */ - - if (op1->AsOp()->gtOp1->OperGet() == GT_ADDR && op1->AsOp()->gtOp2->OperGet() == GT_CNS_INT && - opts.OptimizationEnabled()) - { - // No overflow arithmetic with pointers - noway_assert(!op1->gtOverflow()); - - temp = op1->AsOp()->gtOp1->AsOp()->gtOp1; - if (!temp->OperIsLocal()) - { - temp = nullptr; - break; - } - - // Can not remove the GT_ADDR if it is currently a CSE candidate. - if (gtIsActiveCSE_Candidate(op1->AsOp()->gtOp1)) - { - break; - } - - ival1 = op1->AsOp()->gtOp2->AsIntCon()->gtIconVal; - fieldSeq = op1->AsOp()->gtOp2->AsIntCon()->gtFieldSeq; - - if (ival1 == 0 && typ == temp->TypeGet() && temp->TypeGet() != TYP_STRUCT) - { - noway_assert(!varTypeIsGC(temp->TypeGet())); - foldAndReturnTemp = true; - } - else - { - // The emitter can't handle large offsets - if (ival1 != (unsigned short)ival1) - { - break; - } - - // The emitter can get confused by invalid offsets - if (ival1 >= Compiler::lvaLclSize(temp->AsLclVarCommon()->GetLclNum())) - { - break; - } - } - // Now we can fold this into a GT_LCL_FLD below - // where we check (temp != nullptr) - } } } - // At this point we may have a lclVar or lclFld that might be foldable with a bit of extra massaging: - // - We may have a load of a local where the load has a different type than the local - // - We may have a load of a local plus an offset - // - // In these cases, we will change the lclVar or lclFld into a lclFld of the appropriate type and - // offset if doing so is legal. The only cases in which this transformation is illegal are if the load - // begins before the local or if the load extends beyond the end of the local (i.e. if the load is - // out-of-bounds w.r.t. the local). + // At this point we may have a lclVar or lclFld of some mismatched type. In this case, we will change + // the lclVar or lclFld into a lclFld of the appropriate type if doing so is legal. The only cases in + // which this transformation is illegal is when we have a STRUCT indirection, as we do not have the + // necessary layout information, or if the load would extend beyond the local. if ((temp != nullptr) && !foldAndReturnTemp) { - assert(temp->OperIsLocal()); + assert(temp->OperIs(GT_LCL_VAR, GT_LCL_FLD)); - unsigned lclNum = temp->AsLclVarCommon()->GetLclNum(); + unsigned lclNum = temp->AsLclVarCommon()->GetLclNum(); + unsigned lclOffs = temp->AsLclVarCommon()->GetLclOffs(); // Make sure we do not enregister this lclVar. lvaSetVarDoNotEnregister(lclNum DEBUGARG(DoNotEnregisterReason::LocalField)); - // If the size of the load is greater than the size of the lclVar, we cannot fold this access into - // a lclFld: the access represented by an lclFld node must begin at or after the start of the - // lclVar and must not extend beyond the end of the lclVar. - if ((ival1 >= 0) && ((ival1 + genTypeSize(typ)) <= lvaLclExactSize(lclNum))) + if ((typ != TYP_STRUCT) && ((lclOffs + genTypeSize(typ)) <= lvaLclExactSize(lclNum))) { - GenTreeLclFld* lclFld; - - // We will turn a GT_LCL_VAR into a GT_LCL_FLD with an gtLclOffs of 'ival' - // or if we already have a GT_LCL_FLD we will adjust the gtLclOffs by adding 'ival' - // Then we change the type of the GT_LCL_FLD to match the orginal GT_IND type. + // We will change the type of the node to match the orginal GT_IND type. // - if (temp->OperGet() == GT_LCL_FLD) - { - lclFld = temp->AsLclFld(); - lclFld->SetLclOffs(lclFld->GetLclOffs() + static_cast(ival1)); - } - else // We have a GT_LCL_VAR. + temp->gtType = typ; + + if (temp->OperIs(GT_LCL_VAR)) { - assert(temp->OperGet() == GT_LCL_VAR); - temp->ChangeOper(GT_LCL_FLD); // Note that this makes the gtFieldSeq "NotAField". - lclFld = temp->AsLclFld(); - lclFld->SetLclOffs(static_cast(ival1)); + temp->ChangeOper(GT_LCL_FLD); } - temp->gtType = tree->gtType; foldAndReturnTemp = true; } } @@ -11779,7 +11713,7 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac) { assert(temp != nullptr); assert(temp->TypeGet() == typ); - assert((op1->OperGet() == GT_ADD) || (op1->OperGet() == GT_ADDR)); + assert(op1->OperIs(GT_ADDR)); // Copy the value of GTF_DONT_CSE from the original tree to `temp`: it can be set for // 'temp' because a GT_ADDR always marks it for its operand. @@ -11787,12 +11721,7 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac) temp->gtFlags |= (tree->gtFlags & GTF_DONT_CSE); temp->SetVNsFromNode(tree); - if (op1->OperGet() == GT_ADD) - { - DEBUG_DESTROY_NODE(op1->AsOp()->gtOp1); // GT_ADDR - DEBUG_DESTROY_NODE(op1->AsOp()->gtOp2); // GT_CNS_INT - } - DEBUG_DESTROY_NODE(op1); // GT_ADD or GT_ADDR + DEBUG_DESTROY_NODE(op1); // GT_ADDR DEBUG_DESTROY_NODE(tree); // GT_IND // If the result of the fold is a local var, we may need to perform further adjustments e.g. for @@ -12794,9 +12723,39 @@ GenTree* Compiler::fgOptimizeAddition(GenTreeOp* add) return op1; } - // Note that these transformations are legal for floating-point ADDs as well. if (opts.OptimizationEnabled()) { + // Reduce local addresses: "ADD(ADDR(LCL_VAR), OFFSET)" => "ADDR(LCL_FLD OFFSET)". + // TODO-ADDR: do "ADD(LCL_FLD/VAR_ADDR, OFFSET)" => "LCL_FLD_ADDR" instead. + // + if (op1->OperIs(GT_ADDR) && op2->IsCnsIntOrI() && op1->gtGetOp1()->OperIsLocalRead()) + { + GenTreeUnOp* addrNode = op1->AsUnOp(); + GenTreeLclVarCommon* lclNode = addrNode->gtGetOp1()->AsLclVarCommon(); + GenTreeIntCon* offsetNode = op2->AsIntCon(); + if (FitsIn(offsetNode->IconValue())) + { + unsigned offset = lclNode->GetLclOffs() + static_cast(offsetNode->IconValue()); + + // Note: the emitter does not expect out-of-bounds access for LCL_FLD_ADDR. + if (FitsIn(offset) && (offset < lvaLclExactSize(lclNode->GetLclNum()))) + { + // Types of location nodes under ADDRs do not matter. We arbitrarily choose TYP_UBYTE. + lclNode->ChangeType(TYP_UBYTE); + lclNode->SetOper(GT_LCL_FLD); + lclNode->AsLclFld()->SetLclOffs(offset); + lvaSetVarDoNotEnregister(lclNode->GetLclNum() DEBUGARG(DoNotEnregisterReason::LocalField)); + + addrNode->SetVNsFromNode(add); + + DEBUG_DESTROY_NODE(offsetNode); + DEBUG_DESTROY_NODE(add); + + return addrNode; + } + } + } + // - a + b = > b - a // ADD((NEG(a), b) => SUB(b, a) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index f32b7d79ddb0b9..c97fb6dc11ce14 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -8490,8 +8490,7 @@ void Compiler::fgValueNumberTree(GenTree* tree) { unsigned lclNum = lclFld->GetLclNum(); - // TODO-ADDR: delete the "GetSize" check once location nodes are no more. - if (!lvaInSsa(lclFld->GetLclNum()) || !lclFld->HasSsaName() || (lclFld->GetSize() == 0)) + if (!lvaInSsa(lclFld->GetLclNum()) || !lclFld->HasSsaName()) { lclFld->gtVNPair.SetBoth(vnStore->VNForExpr(compCurBB, lclFld->TypeGet())); } From ffff070b2ab06ff49a1100b04e6c5d1aa66f8c16 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Sun, 12 Jun 2022 17:34:12 -0400 Subject: [PATCH 070/337] Omit calls to CCCryptorFinal --- .../Interop.Symmetric.cs | 8 --- .../Cryptography/AppleCCCryptorLite.cs | 52 ++++++------------- .../entrypoints.c | 1 - .../pal_symmetric.c | 21 -------- .../pal_symmetric.h | 8 --- 5 files changed, 17 insertions(+), 73 deletions(-) diff --git a/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Symmetric.cs b/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Symmetric.cs index 3ba39364f3d065..2cda7d25df23d6 100644 --- a/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Symmetric.cs +++ b/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Symmetric.cs @@ -68,14 +68,6 @@ internal static unsafe partial int CryptorUpdate( out int cbWritten, out int ccStatus); - [LibraryImport(Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_CryptorFinal")] - internal static unsafe partial int CryptorFinal( - SafeAppleCryptorHandle cryptor, - byte* pbOutput, - int cbOutput, - out int cbWritten, - out int ccStatus); - [LibraryImport(Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_CryptorReset")] internal static unsafe partial int CryptorReset(SafeAppleCryptorHandle cryptor, byte* pbIv, out int ccStatus); } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AppleCCCryptorLite.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AppleCCCryptorLite.cs index 779af66e7e7055..c4ea20503f629d 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AppleCCCryptorLite.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/AppleCCCryptorLite.cs @@ -75,6 +75,21 @@ public int TransformFinal(ReadOnlySpan input, Span output) _isFinalized = true; #endif + // We just use CCCryptorUpdate instead of CCCryptorFinal. From the + // Apple documentation: + + // In the following cases, the CCCryptorFinal() is superfluous as + // it will not yield any data nor return an error: + // 1. Encrypting or decrypting with a block cipher with padding + // disabled, when the total amount of data provided to + // CCCryptorUpdate() is an integral multiple of the block size. + // 2. Encrypting or decrypting with a stream cipher. + + // For case 1, we do all of our padding manually and the cipher is opened with + // PAL_PaddingMode.None. So that condition is met. For the second part, we always + // submit data as a multiple of the block size, and is asserted below. So this condition + // is met. + Debug.Assert((input.Length % PaddingSizeInBytes) == 0); Debug.Assert(input.Length <= output.Length); @@ -86,7 +101,7 @@ public int TransformFinal(ReadOnlySpan input, Span output) try { - written = ProcessFinalBlock(input, rented); + written = CipherUpdate(input, rented); rented.AsSpan(0, written).CopyTo(output); } finally @@ -96,7 +111,7 @@ public int TransformFinal(ReadOnlySpan input, Span output) } else { - written = ProcessFinalBlock(input, output); + written = CipherUpdate(input, output); } return written; @@ -183,39 +198,6 @@ private static PAL_ChainingMode GetPalChainMode(PAL_SymmetricAlgorithm algorithm }; } - private unsafe int ProcessFinalBlock(ReadOnlySpan input, Span output) - { - if (input.Length == 0) - { - return 0; - } - - int outputBytes = CipherUpdate(input, output); - int ret; - int errorCode; - - Debug.Assert(output.Length > 0); - - fixed (byte* outputStart = output) - { - byte* outputCurrent = outputStart + outputBytes; - int bytesWritten; - - ret = Interop.AppleCrypto.CryptorFinal( - _cryptor, - outputCurrent, - output.Length - outputBytes, - out bytesWritten, - out errorCode); - - outputBytes += bytesWritten; - } - - ProcessInteropError(ret, errorCode); - - return outputBytes; - } - private static void ProcessInteropError(int functionReturnCode, int ccStatus) { // Success diff --git a/src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c b/src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c index 5bd8d16efc7fcb..16e1efe9d25d1d 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c +++ b/src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c @@ -96,7 +96,6 @@ static const Entry s_cryptoAppleNative[] = DllImportEntry(AppleCryptoNative_CryptorFree) DllImportEntry(AppleCryptoNative_CryptorCreate) DllImportEntry(AppleCryptoNative_CryptorUpdate) - DllImportEntry(AppleCryptoNative_CryptorFinal) DllImportEntry(AppleCryptoNative_CryptorReset) DllImportEntry(AppleCryptoNative_StoreEnumerateUserRoot) DllImportEntry(AppleCryptoNative_StoreEnumerateMachineRoot) diff --git a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_symmetric.c b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_symmetric.c index 3bf564695203fa..b395a86d869a7c 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_symmetric.c +++ b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_symmetric.c @@ -108,27 +108,6 @@ int32_t AppleCryptoNative_CryptorUpdate(CCCryptorRef cryptor, return status == kCCSuccess; } -int32_t AppleCryptoNative_CryptorFinal( - CCCryptorRef cryptor, uint8_t* pbOutput, int32_t cbOutput, int32_t* pcbWritten, int32_t* pccStatus) -{ - if (pccStatus == NULL) - return -1; - - *pccStatus = 0; - - if (pbOutput == NULL || cbOutput < 0 || pcbWritten == NULL) - return -1; - - size_t sizeWritten = 0; - CCStatus status = - CCCryptorFinal(cryptor, pbOutput, (size_t)cbOutput, &sizeWritten); - - // Safe because sizeWritten is bounded by cbOutput. - *pcbWritten = SizeTToInt32(sizeWritten); - *pccStatus = status; - return status == kCCSuccess; -} - int32_t AppleCryptoNative_CryptorReset(CCCryptorRef cryptor, const uint8_t* pbIv, int32_t* pccStatus) { if (pccStatus == NULL) diff --git a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_symmetric.h b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_symmetric.h index 0238635dc2d625..5dcaee2e4fea1d 100644 --- a/src/native/libs/System.Security.Cryptography.Native.Apple/pal_symmetric.h +++ b/src/native/libs/System.Security.Cryptography.Native.Apple/pal_symmetric.h @@ -91,14 +91,6 @@ PALEXPORT int32_t AppleCryptoNative_CryptorUpdate(CCCryptorRef cryptor, int32_t* pcbWritten, int32_t* pkCCStatus); -/* -Shims CCCryptorFinal, updating *pkCCStatus as its output. - -Returns 1 on success, 0 on system error, -1 on input error. -*/ -PALEXPORT int32_t AppleCryptoNative_CryptorFinal( - CCCryptorRef cryptor, uint8_t* pbOutput, int32_t cbOutput, int32_t* pcbWritten, int32_t* pkCCStatus); - /* Shims CCCryptorReset, updating *pkCCStatus as its output. From f1f940f68cb10858776dd3fe3a827a7723a57dba Mon Sep 17 00:00:00 2001 From: Aaron Robinson Date: Sun, 12 Jun 2022 15:27:29 -0700 Subject: [PATCH 071/337] Remove unused code (#70624) * Remove unused AllowZeroAllocator and DefaultAllocator. * Remove static_assert_n. * Remove the native Regex implementation and replace with a minimal version from TPOP. Add attribution in third party notices. --- THIRD-PARTY-NOTICES.TXT | 10 + src/coreclr/inc/defaultallocator.h | 48 -- src/coreclr/inc/iallocator.h | 44 -- src/coreclr/inc/regex_base.h | 972 ---------------------------- src/coreclr/inc/regex_util.h | 208 ------ src/coreclr/inc/static_assert.h | 6 - src/coreclr/utilcode/CMakeLists.txt | 1 - src/coreclr/utilcode/iallocator.cpp | 9 - src/coreclr/vm/eeconfig.cpp | 65 +- 9 files changed, 64 insertions(+), 1299 deletions(-) delete mode 100644 src/coreclr/inc/defaultallocator.h delete mode 100644 src/coreclr/inc/regex_base.h delete mode 100644 src/coreclr/inc/regex_util.h delete mode 100644 src/coreclr/utilcode/iallocator.cpp diff --git a/THIRD-PARTY-NOTICES.TXT b/THIRD-PARTY-NOTICES.TXT index 307da15465cec2..bfbc03e9c599fc 100644 --- a/THIRD-PARTY-NOTICES.TXT +++ b/THIRD-PARTY-NOTICES.TXT @@ -1099,3 +1099,13 @@ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +License notice for code from The Practice of Programming +------------------------------- + +Copyright (C) 1999 Lucent Technologies + +Excerpted from 'The Practice of Programming +by Brian W. Kernighan and Rob Pike + +You may use this code for any purpose, as long as you leave the copyright notice and book citation attached. \ No newline at end of file diff --git a/src/coreclr/inc/defaultallocator.h b/src/coreclr/inc/defaultallocator.h deleted file mode 100644 index 111fb5e7f94c0a..00000000000000 --- a/src/coreclr/inc/defaultallocator.h +++ /dev/null @@ -1,48 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#ifndef _DEFAULTALLOCATOR_H_ -#define _DEFAULTALLOCATOR_H_ - -// The "DefaultAllocator" class may be used by classes that wish to -// provide the flexibility of using an "IAllocator" may avoid writing -// conditionals at allocation sites about whether a non-default -// "IAllocator" has been provided: if none is, they can simply set the -// allocator to DefaultAllocator::Singleton(). -class DefaultAllocator: public IAllocator -{ - static DefaultAllocator s_singleton; - -public: - void* Alloc(size_t sz) - { - return ::operator new(sz); - } - - void* ArrayAlloc(size_t elemSize, size_t numElems) - { - ClrSafeInt safeElemSize(elemSize); - ClrSafeInt safeNumElems(numElems); - ClrSafeInt sz = safeElemSize * safeNumElems; - if (sz.IsOverflow()) - { - return NULL; - } - else - { - return ::operator new(sz.Value()); - } - } - - virtual void Free(void * p) - { - ::operator delete(p); - } - - static DefaultAllocator* Singleton() - { - return &s_singleton; - } -}; - -#endif // _DEFAULTALLOCATOR_H_ diff --git a/src/coreclr/inc/iallocator.h b/src/coreclr/inc/iallocator.h index a5b467a9905b83..f8e0978c6f10ff 100644 --- a/src/coreclr/inc/iallocator.h +++ b/src/coreclr/inc/iallocator.h @@ -29,48 +29,4 @@ class IAllocator virtual void Free(void* p) = 0; }; -// This class wraps an allocator that does not allow zero-length allocations, -// producing one that does (every zero-length allocation produces a pointer to the same -// statically-allocated memory, and freeing that pointer is a no-op). -class AllowZeroAllocator: public IAllocator -{ - int m_zeroLenAllocTarg; - IAllocator* m_alloc; - -public: - AllowZeroAllocator(IAllocator* alloc) : m_alloc(alloc) {} - - void* Alloc(size_t sz) - { - if (sz == 0) - { - return (void*)(&m_zeroLenAllocTarg); - } - else - { - return m_alloc->Alloc(sz); - } - } - - void* ArrayAlloc(size_t elemSize, size_t numElems) - { - if (elemSize == 0 || numElems == 0) - { - return (void*)(&m_zeroLenAllocTarg); - } - else - { - return m_alloc->ArrayAlloc(elemSize, numElems); - } - } - - virtual void Free(void * p) - { - if (p != (void*)(&m_zeroLenAllocTarg)) - { - m_alloc->Free(p); - } - } -}; - #endif // _IALLOCATOR_DEFINED_ diff --git a/src/coreclr/inc/regex_base.h b/src/coreclr/inc/regex_base.h deleted file mode 100644 index fd6103f5da4b31..00000000000000 --- a/src/coreclr/inc/regex_base.h +++ /dev/null @@ -1,972 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// -// Provides basic interpreted regular expression matching. This is meant as a debugging tool, -// and if regular expressions become necessary in a non-debug scenario great care should be -// used to ensure that performance is not impaired, and a more thorough review of this could -// would also be a good thing. This file does not include any concrete instantiations but -// instead provides the basic building blocks. Some concrete instantiations can be found in -// regex_util.h. -// -// NOTE: See code:clr::regex::RegExBase (below) for description of supported regex language. -// -// NOTE: we had to forego standard options such as tr1::regex -// (http://en.wikipedia.org/wiki/Technical_Report_1#Regular_Expressions) and Microsoft's -// internal GRETA regular expressions (http://toolbox/sites/987/default.aspx) because they -// both rely heavily on the STL, which can not currently be used within the CLR. -// -// NOTE: If this becomes non-debug-only, then read the comment on WCHARItemTraits for what -// what needs fixing. -// - -// - -#ifndef _REGEX_BASE_H_ -#define _REGEX_BASE_H_ - -// Forward declare namespace so that it is not debug-only (even if currently there is nothing -// but debug-only code in the namespace). This enables a "using namespace clr;" line in a -// header file without having to worry about whether or not it's in a debug-only block. -namespace clr {} - -#ifdef _DEBUG - -#include "utilcode.h" // for string hash functions -#include "sstring.h" - -namespace clr { -namespace regex { - -// Implementation details. Code contained in any "imp" namespace should never be directly used -// by clients of RegEx. -namespace imp { - - //=================================================================================================== - // Helper for clr::regex::RegExBase. See class definition for clr::regex::RegExBase below for more - // information. - - template - class RegExBaseHelper : protected ITEM_TRAITS - { - public: - typedef typename ITEM_TRAITS::RegexIterator RegexIterator; - typedef typename ITEM_TRAITS::InputIterator InputIterator; - - typedef typename ITEM_TRAITS::MatchFlags MatchFlags; - static const MatchFlags DefaultMatchFlags = ITEM_TRAITS::DefaultMatchFlags; - - // Arguments: - // regex : marks the start of the regular expression string. - // regexEnd : marks the end of the regular expression string. - // input : marks the start of the input string against which regex will be matched. - // inputEnd : marks the end of the input string. - // groups : recipient of regular expression groups. - // - // Returns true if the regular expression was successfully matched against the input string; - // otherwise false. - - RegExBaseHelper(const RegexIterator& regex, - const RegexIterator& regexEnd, - const InputIterator& input, - const InputIterator& inputEnd, - GROUP_CONTAINER& groups, - const MatchFlags flags = DefaultMatchFlags); - - // The main entrypoint to RegExBaseHelper, Match will attempt to match the regular expression - // defined by [regex,regexEnd) against the input defined by [input,inputEnd). - bool Match() - { WRAPPER_NO_CONTRACT; return DoMatch(m_regex, m_input); } - - protected: - typedef typename ITEM_TRAITS::Item Item; - typedef typename ITEM_TRAITS::ItemType ItemType; - - // Try to match regex at any point within input, starting with the first character and moving - // along one at a time until a match is found or the end of the input is encountered, whichever - // comes first. - bool DoMatch( - const RegexIterator& regex, - InputIterator input); - - // Try to match regex starting exactly at input. - bool DoMatchHere( - const RegexIterator& regex, - const InputIterator& input); - - // The function returns true if a match is found consisting of zero or more items c followed by a - // successful match of regex on the remaining input; otherwise false is returned. This is a - // conservative match, so it starts with trying to match zero items followed by regex, - // and will then try to match one item followed by regex. - bool DoMatchStar( - const Item& c, - const RegexIterator& regex, - InputIterator input); - - // The function returns true if a match is found consisting of zero or more items c followed by a - // successful match of regex on the remaining input; otherwise false is returned. This is a - // greedy match, so it starts with trying to match as many items as it can followed by regex, - // and on failure will try again with one less items matched. - bool DoMatchStarEagerly( - const Item& c, - const RegexIterator& regex, - InputIterator input); - - // Convenience method. - Item GetItem( - const RegexIterator ®ex) - { WRAPPER_NO_CONTRACT; return ITEM_TRAITS::GetItem(regex, m_regexEnd, m_flags); } - - // Convenience method. - bool MatchItem( - const Item& c, - const InputIterator& input) - { WRAPPER_NO_CONTRACT; return ITEM_TRAITS::MatchItem(c, input, m_inputEnd, m_flags); } - - // Declared as protected to prevent direct instantiation. - RegExBaseHelper() - {} - - RegexIterator m_regex; - RegexIterator m_regexEnd; - InputIterator m_input; - InputIterator m_inputEnd; - GROUP_CONTAINER& m_groups; - MatchFlags m_flags; - }; - - //--------------------------------------------------------------------------------------------------- - // This method simply stores the end iterators for the regular expression and the input strings, as - // well as the group collection object and flags, and forwards the call to DoMatch. - - template - RegExBaseHelper::RegExBaseHelper( - const RegexIterator& regex, - const RegexIterator& regexEnd, - const InputIterator& input, - const InputIterator& inputEnd, - GROUP_CONTAINER& groups, - const MatchFlags flags) - : m_regex(regex), - m_regexEnd(regexEnd), - m_input(input), - m_inputEnd(inputEnd), - m_groups(groups), - m_flags(flags) - { WRAPPER_NO_CONTRACT; } - - //--------------------------------------------------------------------------------------------------- - // This method checks if the regular expression starts with a caret, indicating that any match must - // be anchored at the start of the input string. If such a caret exists, one match attempt is made - // on the input starting with the first character and the result is returned. If the regex does not - // start with a caret, the method attempts to match against the input string, starting at the first - // character and moving one character over for each successive attempt, until a match is found or - // the end of the input is encountered, whichever comes first. - - template - inline bool - RegExBaseHelper::DoMatch( - const RegexIterator& regex, - InputIterator input) - { - WRAPPER_NO_CONTRACT; - - if (GetItem(regex).GetType() == ITEM_TRAITS::CARET) - { // Match must occur from the beginning of the line - m_groups.OpenGroup(input, m_inputEnd); - bool res = DoMatchHere(regex+1, input); - if (!res) - m_groups.CancelGroup(); - return res; - } - else - { // Match can happen anywhere in the string - do - { // Attempt to match against each substring [x,inputEnd) for x = 0...inputEnd - - // Begin the group that contains the entire match. - m_groups.OpenGroup(input, m_inputEnd); - - if (DoMatchHere(regex, input)) - { // Success. Note that the entire match group is closed elsewhere on a - // successful match. - return true; - } - - // On failure, cancel the group so that it can be reopened on the new substring - m_groups.CancelGroup(); - } while (input++ != m_inputEnd); - } - - // No successful match found. - return false; - } - - //------------------------------------------------------------------------------------------------------- - // This is the main loop, which handles grouping constructs, repetition directives (*, *?, +, +?), and - // EOL matches ($), delegating all character matching to ITEM_TRAITS::MatchItem - // The general algorithm is: - // 1. Get the next item. - // 2. If the item is a DOLLAR type, check to see if we're at the end of the retular expression and - // the input string, and if so return success. - // 3. If the item is a grouping construct, open or close the appropriate group and continue matching. - // On failure, roll back the grouping change so that subsequent attemts will have correct state. - // 4. Check to see if the item following the current is a repetition directive, and if so take the - // appropriate action. - // 5. Otherwise defer to ITEM_TRAITS::MatchItem and if successful continue to match the remaining - // regular expression and input string; otherwise return failure. - - template - inline bool - RegExBaseHelper::DoMatchHere( - const RegexIterator& regex, - const InputIterator& input) - { - WRAPPER_NO_CONTRACT; - - if (regex == m_regexEnd) - { // Reached the end of the regular expression without ever returning false, - // implying a successful match. Close the overall match group and return. - m_groups.CloseGroup(input); - return true; - } - - Item c0 = GetItem(regex); - if (c0.GetType() == ITEM_TRAITS::DOLLAR && (c0.GetNext() == m_regexEnd)) - { // Matches EOL if a '$' is encountered at the end of the input. - m_groups.CloseGroup(input); - // Success only if we're actually at the end of the input string. - return input == m_inputEnd; - } - if (c0.GetType() == ITEM_TRAITS::PAREN_OPEN) - { // Encountered an open parenthesis ('('); open a new grouping. - m_groups.OpenGroup(input, m_inputEnd); - bool res = DoMatchHere(c0.GetNext(), input); - if (!res) - { // If a match fails, there could be further attempts (such as if - // there is an active repetition matching frame beneath us), so - // need to cancel the group we just opened so that the grouping - // structure remains consistent. - m_groups.CancelGroup(); - } - return res; - } - if (c0.GetType() == ITEM_TRAITS::PAREN_CLOSE) - { // Close the most recent open grouping. - COUNT_T i = m_groups.CloseGroup(input); - bool res = DoMatchHere(c0.GetNext(), input); - if (!res) - { // For the same reasons as the need to cancel an opened group - // explained above, we need to reopen the closed group if a - // match fails. - m_groups.ReopenGroup(i, m_inputEnd); - } - return res; - } - - if (c0.GetNext() != m_regexEnd) - { // If there is another item in the regex string following the current one, get - // it to see if it is a repetition matching directive. - Item c1 = GetItem(c0.GetNext()); - if (c1.GetType() == ITEM_TRAITS::STAR) - { // '*' matching directive encountered - if (c1.GetNext() != m_regexEnd) - { - Item c2 = GetItem(c1.GetNext()); - if (c2.GetType() == ITEM_TRAITS::QUESTION_MARK) - { // conservative matching semantics requested - return DoMatchStar(c0, c2.GetNext(), input); - } - } - // Eager matching - return DoMatchStarEagerly(c0, c1.GetNext(), input); - } - if (c1.GetType() == ITEM_TRAITS::PLUS) - { // '+' matching directive encountered. - if (c1.GetNext() != m_regexEnd) - { - Item c2 = GetItem(c1.GetNext()); - if (c2.GetType() == ITEM_TRAITS::QUESTION_MARK) - { // conservative matching semantics requested - return MatchItem(c0, input) && DoMatchStar(c0, c2.GetNext(), input+1); - } - } - // Eager matching - return MatchItem(c0, input) && DoMatchStarEagerly(c0, c1.GetNext(), input+1); - } - if (c1.GetType() == ITEM_TRAITS::QUESTION_MARK) - { // '?' matching directive encountered - return (MatchItem(c0, input) && DoMatchHere(c1.GetNext(), input+1)) || DoMatchHere(c1.GetNext(), input); - } - } - - // No special matching semantics encountered, delegate the matching to ITEM_TRAITS::MatchItem - return MatchItem(c0, input) && DoMatchHere(c0.GetNext(), input+1); - } - - //------------------------------------------------------------------------------------------------------- - // Conservative '*' repetition matching. This attempts to match zero items c followed by a match of - // regex. If this fails, attempt to match one item c followed by a match of regex. Repeat until item c - // does not match or a successful match is found. - - template - inline bool - RegExBaseHelper::DoMatchStar( - const Item& c, - const RegexIterator& regex, - InputIterator input) - { - WRAPPER_NO_CONTRACT; - CONSISTENCY_CHECK(input != m_inputEnd); - - do { - if (DoMatchHere(regex, input)) - { // A successful match is found! - return true; - } - // No successful match, so try to match one more item and then attempt to match regex on the - // remaining input. - } while (input != m_inputEnd && MatchItem(c, input++)); - return false; - } - - //------------------------------------------------------------------------------------------------------- - // Similar to DoMatchStar above, except this algorithm matches as many items c as possible first followed - // by regex on the remaining input, and on failure tries again with a match against one less item c - // followed by regex on the remaining input, and repeats until there are no items c remaining to match - // and the zero item match followed by a match of regex on the entire remaining input fails. If any of - // the match attempts succeed, return success. - - template - inline bool - RegExBaseHelper::DoMatchStarEagerly( - const Item& c, - const RegexIterator& regex, - InputIterator input) - { - WRAPPER_NO_CONTRACT; - - // Make sure we keep a hold of how far back we can unwind. - InputIterator inputOrig = input; - - // First, determine the maximum number of matches against item c. - while (input != m_inputEnd && MatchItem(c, input)) - { - ++input; - } - - do - { // Work backwards from the maximum number of matches of item c until a match is found - // or until we have backed right up to the starting value of input (saved in inputOrig), - // at which time we admit failure. - if (DoMatchHere(regex, input)) - return true; - } while (inputOrig != input--); - return false; - } - -} // namespace imp - -//======================================================================================================= -// Represents a matched group using iterators to denote the string contained by [Begin(),End()). - -template -class Group -{ -public: - typedef INPUT_ITERATOR InputIterator; - - // - // Functions for accessing group properties - // - - // Returns the iterator indicating the start of the group - const InputIterator& Begin() const - { LIMITED_METHOD_CONTRACT; return m_begin; } - - // Returns the iterator indicating the first non-member of the group - const InputIterator& End() const - { LIMITED_METHOD_CONTRACT; return m_end; } - - // It is possible that m_end - m_begin could be greater than the maximum of COUNT_T. m_end and - // m_begin are the end and start of a string, so is entirely unlikely to overflow a COUNT_T. - // Conbined with the fact that this is debug-only code, opting not to replace all COUNT_T - // uses with SIZE_T. - COUNT_T Length() const - { WRAPPER_NO_CONTRACT; return static_cast(m_end - m_begin); } - - // - // Functions used by RegExBaseHelper to create grouping constructs. - // - - Group() - : m_isClosed(false), m_begin(), m_end() - { WRAPPER_NO_CONTRACT; } - - Group(const InputIterator& start, const InputIterator& end, bool isClosed = false) - : m_isClosed(isClosed), m_begin(start), m_end(end) - { WRAPPER_NO_CONTRACT; } - - void SetBegin(const InputIterator& start) - { WRAPPER_NO_CONTRACT; m_begin = start; } - - void SetEnd(const InputIterator& end) - { WRAPPER_NO_CONTRACT; m_end = end; } - - bool IsClosed() const - { LIMITED_METHOD_CONTRACT; return m_isClosed; } - - void SetIsClosed(bool isClosed) - { WRAPPER_NO_CONTRACT; m_isClosed = isClosed; } - -protected: - bool m_isClosed; - InputIterator m_begin; - InputIterator m_end; -}; - -//======================================================================================================= -// Represents a generic container of groups, defaulting to using Group as its element -// type. This container satisfies the method requrements of RegExBase. When a match is successful, the -// match groups may be accessed using the index operator or the iterators definin the matched groups -// [Begin(), End()). - -template > -class GroupContainer -{ -public: - typedef typename SArray::Iterator Iterator; - - // - // Functions for enumerating groups - // - - GROUP_TYPE & operator[](COUNT_T idx) - { - WRAPPER_NO_CONTRACT; - CONSISTENCY_CHECK(((COUNT_T)(COUNT_T)idx) == idx); - return m_array[idx]; - } - - // Returns an iterator to the first matched group (which is always the string for the - // entire successfully matched string. Specific groups start at Begin()+1 and continue - // to End()-1. - Iterator Begin() - { WRAPPER_NO_CONTRACT; return m_array.Begin(); } - - // Returns the first invalid iterator value. - Iterator End() - { WRAPPER_NO_CONTRACT; return m_array.End(); } - - // - COUNT_T Count() const - { WRAPPER_NO_CONTRACT; return m_array.GetCount(); } - - // - // Functions used by RegExBaseHelper to create grouping constructs. - // - - // Note: OpenGroup takes an end iterator so that the group will have a valid (if possibly - // incorrect) endpoint in the case that the regular expression has unbalanced grouping - // parentheses. - void OpenGroup(const INPUT_ITERATOR& start, const INPUT_ITERATOR& end) - { WRAPPER_NO_CONTRACT; m_array.Append(GROUP_TYPE(start, end, false)); } - - COUNT_T CloseGroup(const INPUT_ITERATOR& end); - - void ReopenGroup(COUNT_T i, const INPUT_ITERATOR& end); - - void CancelGroup() - { WRAPPER_NO_CONTRACT; m_array.Delete(m_array.End() - 1); } - -private: - SArray m_array; -}; - -//------------------------------------------------------------------------------------------------------- -// Works backwards from the most recently created group looking for an open group to close. Returns -// the index of the group that was closed, which is used in the event that a group needs to be -// reopened. - -template -COUNT_T -GroupContainer::CloseGroup( - const INPUT_ITERATOR& end) -{ - WRAPPER_NO_CONTRACT; - - for (COUNT_T i = (COUNT_T)Count(); i > 0; --i) - { - if (!m_array[i-1].IsClosed()) - { - m_array[i-1].SetEnd(end); - m_array[i-1].SetIsClosed(true); - return i-1; - } - } - - _ASSERTE(!"Unmatched grouping constructs!"); - return 0; -} - -//------------------------------------------------------------------------------------------------------- -// Reopen a group at the given index, using 'end' to overwrite the current end. - -template -void -GroupContainer::ReopenGroup( - COUNT_T i, - const INPUT_ITERATOR& end) -{ - WRAPPER_NO_CONTRACT; - CONSISTENCY_CHECK(i > 0 && i < Count()); - - if (i > 0 && i < Count()) - { - m_array[i].SetEnd(end); - m_array[i].SetIsClosed(false); - } -} - -//======================================================================================================= -// Empty group container that satisfies the method requirements of RegExBase but has empty bodies. This -// allows for non-allocating matches when grouping is not required. - -template -class NullGroupContainer -{ -public: - void OpenGroup(INPUT_ITERATOR, INPUT_ITERATOR) {} - COUNT_T CloseGroup(INPUT_ITERATOR) { return 0; } - void ReopenGroup(COUNT_T, INPUT_ITERATOR) {} - void CancelGroup() {} -}; - -//======================================================================================================= -// This mini-implementation of regular expression matching supports the -// following constructs: -// ^ matches the beginning of the input string -// $ matches the end of the input string -// * matches zero or more occurrences of the previous item eagerly -// *? matches zero or more occurrences of the previous item conservatively -// + matches 1 or more occurrences of the previous item eagerly -// +? matches 1 or more occurrences of the previous item conservatively -// ? matches 0 or 1 occurrences of the previous item -// ( starts a grouping -// ) ends a grouping -// -// IMPORTANT: These are just anchoring and grouping constructs. See the definition for ItemTraitsBase -// below for information on the default character classes that are supported. (The intent of -// this separation is to allow customization of the character classes where required.) - -// ITEM_TRAITS provides traits for individual tokens in a regular expression, as well as a mechanism for -// matching said individual components with the target string. RegexBase derives from ITEM_TRAITS in a -// protected fashion, and is responsible for providing the following: -// 1. "RegexIterator" typedef -// Used as an iterator into the regular expression, and used as arguments to indicate the start -// and the end of the regular expression string. -// 2. "InputIterator" typedef -// Used as an iterator into the input string, and used as arguments to indicate the start -// and the end of the input string. -// (NOTE: RegexIterator and InputIterator are often typedef'ed to be the same thing.) -// 3. "Item" typedef. -// This will be used with methods GetItem and MatchItem (see below). Item must -// define the following methods: -// ItemType GetType() : returns the type of the item. See below for explanation of ItemType -// const RegexIterator& GetNext() : iterator pointing to the start of the next item. -// 4. "MatchFlags" typedef, and "static const DefaultMatchFlags" value. -// Provided for calls to "Match" and "Matches", and passed on to calls "GetItem" and "MatchItem". -// 5. enum ItemType -// Defines the following minimum values: -// DOT -// CARET -// DOLLAR -// STAR -// QUESTION_MARK -// PLUS -// PAREN_OPEN -// PAREN_CLOSE -// ItemType may include more values, and may even choose to ignore the above enum types, all of -// which must be recognized by GetItem and MatchItem (see below). -// 6. static Item GetItem(const RegexIterator& regex, -// const RegexIterator& regexEnd, -// const MatchFlags& flags) -// This method takes a regular expression iterator and returns the next regular expression -// element (Item) pointed to by the iterator. -// 7. static bool MatchItem(const Item& c, -// const InputIterator& input, -// const InputIterator& inputEnd, -// const MatchFlags &flags) - -// GROUP_CONTAINER provides functionality for keeping track of regular expression groups. This is a generic -// argument to Match, and the type of the object must support the following methods: -// 1. void OpenGroup(const InputIterator& start, const InputIterator& end); -// Called when a PAREN_OPEN item is encountered. -// 2. COUNT_T CloseGroup(const InputIterator& end); -// Called when a PAREN_CLOSE item is encountered. Returns the index of the group that was closed. -// 3. void ReopenGroup(COUNT_T i, const InputIterator& end); -// Called when a match following a call to CloseGroup fails, essentially requesting a rollback -// of the call to CloseGroup. -// 4. void CancelGroup(); -// Called when a match following a call to OpenGroup fails, essentially requesting a rollback -// of the call to OpenGroup. - -template -class RegExBase : public ITEM_TRAITS -{ -public: - typedef typename ITEM_TRAITS::RegexIterator RegexIterator; - typedef typename ITEM_TRAITS::InputIterator InputIterator; - - // This is a convenience typedef that allows a caller to easily declare a grouping container - // to be passed to a call to Match. An example would be (see regex_util.h for a definition of - // SStringRegEx): - // - // SString input(SL"Simmons"); - // SStringRegEx::GroupingContainer container; - // if (SStringRegEx::Match(SL"(Sim+on)", input, container)) { - // printf("%S", container[1].GetSString(input).GetUnicode()); - // } - // - typedef GroupContainer > GroupingContainer; - - // Pulls down the typedef for MatchFlags and initialized a static representing the default flags. - typedef typename ITEM_TRAITS::MatchFlags MatchFlags; - static const MatchFlags DefaultMatchFlags = ITEM_TRAITS::DefaultMatchFlags; - - template - static bool Match(RegexIterator regex, - RegexIterator regexEnd, - InputIterator input, - InputIterator inputEnd, - GROUP_CONTAINER& groups, - MatchFlags flags = DefaultMatchFlags) - { - imp::RegExBaseHelper - re(regex, regexEnd, input, inputEnd, groups, flags); - return re.Match(); - } - - static bool Matches(RegexIterator regex, - RegexIterator regexEnd, - InputIterator input, - InputIterator inputEnd, - MatchFlags flags = DefaultMatchFlags) - { - NullGroupContainer ngc; - return Match(regex, regexEnd, input, inputEnd, ngc, flags); - } -}; - -//======================================================================================================= -// In addition to requirements specified on RegExBase, StandardItemTraits provides the following -// additinal regular expression item types. -// c matches any literal character c -// . matches any single character -// \d any literal digit character -// \w any alpha character -// \s any whitespace character -// -// Child types of ItemTraitsBase must implement GetItem and MatchItem (see below for full -// signature requirements). Current child type implementations permit a backslash ('\') to escape -// special characters ('.', '$', '*', etc.) and allow them to be interpreted as literal characters. -// -// This type describes a particular behaviour, but must be subtyped for the particular target character -// needed, and GetItem and MatchItem must be implemented. -// - -template -class ItemTraitsBase -{ -public: - typedef ITERATOR_TYPE RegexIterator; - typedef ITERATOR_TYPE InputIterator; - - enum MatchFlags - { - MF_NONE = 0x00, - MF_CASE_INSENSITIVE = 0x01 // Match character literals as case insensitive. - }; - - static const MatchFlags DefaultMatchFlags = MF_NONE; - -protected: - ItemTraitsBase() - {} - - enum ItemType - { - // REQUIRED, as described in RegExBase - CARET, - DOLLAR, - STAR, - QUESTION_MARK, - PLUS, - PAREN_OPEN, - PAREN_CLOSE, - // ADDITIONAL - DOT, // any literal character - DIGIT, // any digit - ALPHA, // any alpha character, upper or lower case - WHITESPACE, // any whitespace character - NON_WHITESPACE, // any non-whitespace character - CHARACTER, // a specific literal character - }; - - class Item - { - public: - Item(ItemType type, CHAR_TYPE val, const RegexIterator& next) - : m_type(type), m_val(val), m_next(next) - { WRAPPER_NO_CONTRACT; } - - Item(ItemType type, const RegexIterator& next) - : m_type(type), m_val(0), m_next(next) - { WRAPPER_NO_CONTRACT; } - - ItemType GetType() const - { LIMITED_METHOD_CONTRACT; return m_type; } - - const RegexIterator& GetNext() const - { LIMITED_METHOD_CONTRACT; return m_next; } - - CHAR_TYPE GetValue() const - { LIMITED_METHOD_CONTRACT; return m_val; } - - protected: - ItemType m_type; - CHAR_TYPE m_val; - RegexIterator m_next; - }; - - // All deriving types must add the following methods: - // static Item GetItem(const RegexIterator& regex, const RegexIterator& regexEnd); - // static bool MatchItem(const Item& c, const InputIterator& input, const InputIterator& inputEnd); -}; - -//======================================================================================================= -// Implements ItemTraitsBase, provides matching for UNICODE characters. -// -// !!!IMPORTANT!!! -// This is not a complete unicode implementation - only the equivalent of ASCII alpha characters are -// consider to be part of the alpha set, and this is also the only set on which case insensitive -// operations will correctly work. If RegEx is moved out of DEBUG ONLY, then this will have to be fixed -// to properly address these issues. -// !!!IMPORTANT!!! - -template -class WCHARItemTraits : public ItemTraitsBase -{ -public: - typedef ItemTraitsBase PARENT_TYPE; - typedef typename PARENT_TYPE::RegexIterator RegexIterator; - typedef typename PARENT_TYPE::InputIterator InputIterator; - typedef typename PARENT_TYPE::Item Item; - typedef typename PARENT_TYPE::MatchFlags MatchFlags; - - static Item GetItem(const RegexIterator& regex, const RegexIterator& regexEnd, MatchFlags flags); - static bool MatchItem(const Item& c, const InputIterator& input, const InputIterator& inputEnd, MatchFlags flags); - -protected: - WCHARItemTraits() - {} - -private: - static inline bool IS_UPPER_A_TO_Z(WCHAR x) - { WRAPPER_NO_CONTRACT; return (((x) >= W('A')) && ((x) <= W('Z'))); } - - static inline bool IS_LOWER_A_TO_Z(WCHAR x) - { WRAPPER_NO_CONTRACT; return (((x) >= W('a')) && ((x) <= W('z'))); } - - static inline WCHAR UPCASE(WCHAR x) - { WRAPPER_NO_CONTRACT; return (IS_LOWER_A_TO_Z(x) ? ((x) - W('a') + W('A')) : (x)); } - - static inline WCHAR DOWNCASE(WCHAR x) - { WRAPPER_NO_CONTRACT; return (IS_UPPER_A_TO_Z(x) ? ((x) - W('A') + W('a')) : (x)); } - - static bool MatchCharacter(WCHAR c1, WCHAR c2, MatchFlags flags) - { WRAPPER_NO_CONTRACT; return (flags & PARENT_TYPE::MF_CASE_INSENSITIVE) ? (DOWNCASE(c1) == DOWNCASE(c2)) : (c1 == c2); } -}; - -//------------------------------------------------------------------------------------------------------- -// Reads the next item from regex, recognizing special characters outlined in ItemTraitsBase. - -template -typename WCHARItemTraits::Item -WCHARItemTraits::GetItem( - const RegexIterator& regex, - const RegexIterator& regexEnd, - MatchFlags flags) -{ - WRAPPER_NO_CONTRACT; - - if (*regex == W('\\')) - { - const RegexIterator regexNext = regex+1; - if (regexNext == regexEnd) - return Item(PARENT_TYPE::CHARACTER, W('\\'), regexNext); - if (*regexNext == W('d')) - return Item(PARENT_TYPE::DIGIT, regexNext+1); - if (*regexNext == W('w')) - return Item(PARENT_TYPE::ALPHA, regexNext+1); - if (*regexNext == W('s')) - return Item(PARENT_TYPE::WHITESPACE, regexNext+1); - if (*regexNext == W('S')) - return Item(PARENT_TYPE::NON_WHITESPACE, regexNext+1); - return Item(PARENT_TYPE::CHARACTER, *regexNext, regexNext+1); - } - else if (*regex == W('.')) - return Item(PARENT_TYPE::DOT, W('.'), regex+1); - else if (*regex == W('^')) - return Item(PARENT_TYPE::CARET, W('^'), regex+1); - else if (*regex == W('$')) - return Item(PARENT_TYPE::DOLLAR, W('$'), regex+1); - else if (*regex == W('*')) - return Item(PARENT_TYPE::STAR, W('*'), regex+1); - else if (*regex == W('?')) - return Item(PARENT_TYPE::QUESTION_MARK, W('?'), regex+1); - else if (*regex == W('+')) - return Item(PARENT_TYPE::PLUS, W('+'), regex+1); - else if (*regex == W('(')) - return Item(PARENT_TYPE::PAREN_OPEN, W('('), regex+1); - else if (*regex == W(')')) - return Item(PARENT_TYPE::PAREN_CLOSE, W(')'), regex+1); - else - return Item(PARENT_TYPE::CHARACTER, *regex, regex + 1); -} - -//------------------------------------------------------------------------------------------------------- -// Returns true if the next character point to by input matches the character class described by c. - -template -bool -WCHARItemTraits::MatchItem( - const Item& c, - const InputIterator& input, - const InputIterator& inputEnd, - MatchFlags flags) -{ - WRAPPER_NO_CONTRACT; - - if (c.GetType() == PARENT_TYPE::DIGIT) - return *input >= W('0') && *input <= W('9'); - else if (c.GetType() == PARENT_TYPE::ALPHA) - return (*input >= W('a') && *input <= W('z')) || (*input >= W('A') && *input <= W('Z')); - else if (c.GetType() == PARENT_TYPE::WHITESPACE) - return *input == W(' ') || *input == W('\t'); - else if (c.GetType() == PARENT_TYPE::NON_WHITESPACE) - return !(*input == W(' ') || *input == W('\t')); - else - return c.GetType() == PARENT_TYPE::DOT || MatchCharacter(c.GetValue(), *input, flags); -} - -//======================================================================================================= -// Implements ItemTraitsBase, provides matching for ASCII (*not* UTF8) characters. - -template -class CHARItemTraits : public ItemTraitsBase -{ -public: - typedef ItemTraitsBase PARENT_TYPE; - typedef typename PARENT_TYPE::RegexIterator RegexIterator; - typedef typename PARENT_TYPE::InputIterator InputIterator; - typedef typename PARENT_TYPE::Item Item; - typedef typename PARENT_TYPE::MatchFlags MatchFlags; - - static Item GetItem(const RegexIterator& regex, const RegexIterator& regexEnd, MatchFlags flags); - static bool MatchItem(const Item& c, const InputIterator& input, const InputIterator& inputEnd, MatchFlags flags); - -protected: - CHARItemTraits() - {} - -private: - static inline bool IS_UPPER_A_TO_Z(CHAR x) - { WRAPPER_NO_CONTRACT; return (((x) >= 'A') && ((x) <= 'Z')); } - - static inline bool IS_LOWER_A_TO_Z(CHAR x) - { WRAPPER_NO_CONTRACT; return (((x) >= 'a') && ((x) <= 'z')); } - - static inline CHAR UPCASE(CHAR x) - { WRAPPER_NO_CONTRACT; return (IS_LOWER_A_TO_Z(x) ? ((x) - 'a' + 'A') : (x)); } - - static inline CHAR DOWNCASE(CHAR x) - { WRAPPER_NO_CONTRACT; return (IS_UPPER_A_TO_Z(x) ? ((x) - 'A' + 'a') : (x)); } - - static bool MatchCharacter(CHAR c1, CHAR c2, MatchFlags flags) - { WRAPPER_NO_CONTRACT; return (flags & PARENT_TYPE::MF_CASE_INSENSITIVE) ? (DOWNCASE(c1) == DOWNCASE(c2)) : (c1 == c2); } -}; - -//------------------------------------------------------------------------------------------------------- -// Reads the next item from regex, recognizing special characters outlined in ItemTraitsBase. - -template -typename CHARItemTraits::Item -CHARItemTraits::GetItem( - const RegexIterator& regex, - const RegexIterator& regexEnd, - MatchFlags flags) -{ - WRAPPER_NO_CONTRACT; - - if (*regex == '\\') - { - const RegexIterator regexNext = regex+1; - if (regexNext == regexEnd) - return Item(PARENT_TYPE::CHARACTER, W('\\'), regexNext); - if (*regexNext == 'd') - return Item(PARENT_TYPE::DIGIT, regexNext+1); - if (*regexNext == 'w') - return Item(PARENT_TYPE::ALPHA, regexNext+1); - if (*regexNext == 's') - return Item(PARENT_TYPE::WHITESPACE, regexNext+1); - return Item(PARENT_TYPE::CHARACTER, *regexNext, regexNext+1); - } - else if (*regex == '.') - return Item(PARENT_TYPE::DOT, '.', regex+1); - else if (*regex == '^') - return Item(PARENT_TYPE::CARET, '^', regex+1); - else if (*regex == '$') - return Item(PARENT_TYPE::DOLLAR, '$', regex+1); - else if (*regex == '*') - return Item(PARENT_TYPE::STAR, '*', regex+1); - else if (*regex == '?') - return Item(PARENT_TYPE::QUESTION_MARK, '?', regex+1); - else if (*regex == '+') - return Item(PARENT_TYPE::PLUS, '+', regex+1); - else if (*regex == '(') - return Item(PARENT_TYPE::PAREN_OPEN, '(', regex+1); - else if (*regex == ')') - return Item(PARENT_TYPE::PAREN_CLOSE, ')', regex+1); - else - return Item(PARENT_TYPE::CHARACTER, *regex, regex + 1); -} - -//------------------------------------------------------------------------------------------------------- -// Returns true if the next character point to by input matches the character class described by c. - -template -bool -CHARItemTraits::MatchItem( - const Item& c, - const InputIterator& input, - const InputIterator& inputEnd, - MatchFlags flags) -{ - WRAPPER_NO_CONTRACT; - - if (c.GetType() == PARENT_TYPE::DIGIT) - return *input >= W('0') && *input <= W('9'); - else if (c.GetType() == PARENT_TYPE::ALPHA) - return (*input >= W('a') && *input <= W('z')) || (*input >= W('A') && *input <= W('Z')); - else if (c.GetType() == PARENT_TYPE::WHITESPACE) - return *input == W(' ') || *input == W('\t'); - else - return c.GetType() == PARENT_TYPE::DOT || MatchCharacter(c.GetValue(), *input, flags); -} - -} /* namespace regex */ -} /* namespace clr */ - -#endif // _DEBUG - -#endif // _REGEX_BASE_H_ diff --git a/src/coreclr/inc/regex_util.h b/src/coreclr/inc/regex_util.h deleted file mode 100644 index d96c7423198b26..00000000000000 --- a/src/coreclr/inc/regex_util.h +++ /dev/null @@ -1,208 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// See regex_base.h for more information. -// -// This header creates some concrete instantiations of RegExBase for commonly used scenarios. In -// particular, basic regular expression matching base on the regular expression language described in -// clr::regex::ItemTraitsBase (found in regex_base.h) is instantiated for use with SString, ASCII and -// UNICODE strings (clr::regex::SStringRegex, clr::regex::WSTRRegEx, and clr::regex::STRRegEx -// respectively). Each type definition includes an example of its use. -// - -// - -#ifndef _REGEX_UTIL_H_ -#define _REGEX_UTIL_H_ - -#ifndef MODE_ANY -#define MODE_ANY -#endif - -#include "regex_base.h" - -#ifdef _DEBUG - -namespace clr -{ -namespace regex -{ - -//======================================================================================================= -// Derives from Group to provide two additional convenience methods (GetSString variants). - -class SStringGroup : public Group -{ -public: - SStringGroup() - : Group() - { WRAPPER_NO_CONTRACT; } - - SStringGroup(const InputIterator& _start, const InputIterator& _end, bool _isClosed = false) - : Group(_start, _end, _isClosed) - { WRAPPER_NO_CONTRACT; } - - // Since SStrings constructed from ranges require the original source string, this is a required - // input argument. Returns the input substring that matches the corresponding grouping. - SString GetSString(const SString& src) - { WRAPPER_NO_CONTRACT; return SString(src, Begin(), End()); } - - // Since SStrings constructed from ranges require the original source string, this is a required - // input argument. This version takes a target SString as a buffer, and also returns this buffer - // as a reference. Returns the input substring that matches the corresponding grouping. - SString& GetSString(const SString& src, SString& tgt) - { WRAPPER_NO_CONTRACT; tgt.Set(src, Begin(), End()); return tgt; } -}; - -//======================================================================================================= -typedef WCHARItemTraits SStringItemTraits; - -//======================================================================================================= -// Regular expression matching with SStrings. -// -// Here is an example of how to use SStringRegEx with grouping enabled. -// -// using namespace clr::regex; -// SString input(SL"Simmons"); // usually this is derived from some variable source -// SStringRegEx::GroupingContainer container; -// if (SStringRegEx::Match(SL"(Sim+on)", input, container)) { -// printf("%S", container[1].GetSString(input).GetUnicode()); -// } -// -// This sample should result in "Simmon" being printed. - - -class SStringRegEx : public RegExBase -{ - typedef RegExBase PARENT_TYPE; - -public: - using PARENT_TYPE::Match; - using PARENT_TYPE::Matches; - - typedef PARENT_TYPE::InputIterator InputIterator; - - typedef GroupContainer GroupingContainer; - - static bool Match( - const SString& regex, - const SString& input, - GroupingContainer& groups, - MatchFlags flags = DefaultMatchFlags) - { - WRAPPER_NO_CONTRACT; - return Match(regex.Begin(), regex.End(), input.Begin(), input.End(), groups, flags); - } - - static bool Matches( - const SString& regex, - const SString& input, - MatchFlags flags = DefaultMatchFlags) - { - WRAPPER_NO_CONTRACT; - return Matches(regex.Begin(), regex.End(), input.Begin(), input.End(), flags); - } - -}; - -//======================================================================================================= -// Regular expression matching with UNICODE strings. -// -// Here is an example of how to use WSTRRegEx to match against a null-terminated string without grouping. -// -// using namespace clr::regex; -// LPCWSTR input = L"Simmons"; -// if (WSTRRegEx::Matches(L"Sim+on", input)) -// printf("Match succeeded"); -// else -// printf("Match failed"); -// -// This sample should result in "Match succeeded" being printed. - -class WSTRRegEx : public RegExBase > -{ - typedef RegExBase > PARENT_TYPE; - -public: - using PARENT_TYPE::Match; - using PARENT_TYPE::Matches; - - static bool Match( - LPCWSTR regex, - LPCWSTR input, - GroupingContainer& groups, - MatchFlags flags = DefaultMatchFlags) - { - WRAPPER_NO_CONTRACT; - return Match(regex, regex + wcslen(regex), input, input + wcslen(input), groups, flags); - } - - static bool Matches( - LPCWSTR regex, - LPCWSTR input, - MatchFlags flags = DefaultMatchFlags) - { - CONTRACTL { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } CONTRACTL_END; - - return Matches(regex, regex + wcslen(regex), input, input + wcslen(input), flags); - } -}; - -//======================================================================================================= -// Regular expression matching with ASCII strings. -// -// Here is an example of how to use STRRegEx to match against a substring based on begin and end range -// pointers, with grouping disabled and case insensitivity enabled. -// -// using namespace clr::regex; -// LPCSTR input = "123Simmons456"; -// if (STRRegEx::Matches("Sim+on", input+3, input+10, STRRegEx::MF_CASE_INSENSITIVE)) -// printf("Match succeeded"); -// else -// printf("Match failed"); -// -// This sample should result in "Match succeeded" being printed. - -class STRRegEx : public RegExBase > -{ - typedef RegExBase > PARENT_TYPE; - -public: - using PARENT_TYPE::Match; - using PARENT_TYPE::Matches; - - static bool Match( - LPCSTR regex, - LPCSTR input, - GroupingContainer& groups, - MatchFlags flags = DefaultMatchFlags) - { - WRAPPER_NO_CONTRACT; - return Match(regex, regex + strlen(regex), input, input + strlen(input), groups, flags); - } - - static bool Matches( - LPCSTR regex, - LPCSTR input, - MatchFlags flags = DefaultMatchFlags) - { - CONTRACTL { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } CONTRACTL_END; - - return Matches(regex, regex + strlen(regex), input, input + strlen(input), flags); - } -}; - -} // namespace regex -} // namespace clr - -#endif // _DEBUG - -#endif // _REGEX_UTIL_H_ diff --git a/src/coreclr/inc/static_assert.h b/src/coreclr/inc/static_assert.h index e344e83baca554..67336e1290394d 100644 --- a/src/coreclr/inc/static_assert.h +++ b/src/coreclr/inc/static_assert.h @@ -14,12 +14,6 @@ #ifndef __STATIC_ASSERT_H__ #define __STATIC_ASSERT_H__ -// static_assert( cond, msg ) is now a compiler-supported intrinsic in Dev10 C++ compiler. -// Replaces previous uses of STATIC_ASSERT_MSG and COMPILE_TIME_ASSERT_MSG. - -// Replaces previous uses of CPP_ASSERT -#define static_assert_n( n, cond ) static_assert( cond, #cond ) - // Replaces previous uses of C_ASSERT and COMPILE_TIME_ASSERT #define static_assert_no_msg( cond ) static_assert( cond, #cond ) diff --git a/src/coreclr/utilcode/CMakeLists.txt b/src/coreclr/utilcode/CMakeLists.txt index c55965b239600d..76d5b0e61dc0fe 100644 --- a/src/coreclr/utilcode/CMakeLists.txt +++ b/src/coreclr/utilcode/CMakeLists.txt @@ -27,7 +27,6 @@ set(UTILCODE_COMMON_SOURCES comex.cpp guidfromname.cpp memorypool.cpp - iallocator.cpp loaderheap.cpp outstring.cpp ilformatter.cpp diff --git a/src/coreclr/utilcode/iallocator.cpp b/src/coreclr/utilcode/iallocator.cpp deleted file mode 100644 index 9e1ea5ed906627..00000000000000 --- a/src/coreclr/utilcode/iallocator.cpp +++ /dev/null @@ -1,9 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#include "stdafx.h" // Precompiled header key. -#include "iallocator.h" -#include "defaultallocator.h" - -// static -DefaultAllocator DefaultAllocator::s_singleton; diff --git a/src/coreclr/vm/eeconfig.cpp b/src/coreclr/vm/eeconfig.cpp index 87692b656eb018..3b4ad3176e6dac 100644 --- a/src/coreclr/vm/eeconfig.cpp +++ b/src/coreclr/vm/eeconfig.cpp @@ -15,7 +15,6 @@ #include "eventtrace.h" #include "eehash.h" #include "corhost.h" -#include "regex_util.h" #include "clr/fs/path.h" #include "configuration.h" @@ -943,6 +942,56 @@ TypeNamesList::TypeNamesList() LIMITED_METHOD_CONTRACT; } +namespace +{ + // + // Slight modification of Rob Pike's minimal regex from The Practice of Programming. + // See https://www.cs.princeton.edu/~bwk/tpop.webpage/code.html - 'Grep program from Chapter 9' + // + + /* Copyright (C) 1999 Lucent Technologies */ + /* Excerpted from 'The Practice of Programming' */ + /* by Brian W. Kernighan and Rob Pike */ + bool matchhere(const char *regexp, const char* regexe, const char *text); + bool matchstar(char c, const char *regexp, const char* regexe, const char *text); + + /* match: search for regexp anywhere in text */ + bool match(const char *regexp, const char* regexe, const char *text) + { + if (regexp[0] == '^') + return matchhere(regexp+1, regexe, text); + do { /* must look even if string is empty */ + if (matchhere(regexp, regexe, text)) + return true; + } while (*text++ != '\0'); + return false; + } + + /* matchhere: search for regexp at beginning of text */ + bool matchhere(const char *regexp, const char* regexe, const char *text) + { + if (regexp[0] == '\0' || regexp == regexe) + return 1; + if (regexp[1] == '*') + return matchstar(regexp[0], regexp+2, regexe, text); + if (regexp[0] == '$' && (regexp[1] == '\0' || (regexp+1) == regexe)) + return *text == '\0'; + if (*text!='\0' && (regexp[0]=='.' || regexp[0]==*text)) + return matchhere(regexp+1, regexe, text+1); + return false; + } + + /* matchstar: search for c*regexp at beginning of text */ + bool matchstar(char c, const char *regexp, const char* regexe, const char *text) + { + do { /* a * matches zero or more instances */ + if (matchhere(regexp, regexe, text)) + return true; + } while (*text != '\0' && (*text++ == c || c == '.')); + return false; + } +} + bool EEConfig::RegexOrExactMatch(LPCUTF8 regex, LPCUTF8 input) { CONTRACTL @@ -961,16 +1010,10 @@ bool EEConfig::RegexOrExactMatch(LPCUTF8 regex, LPCUTF8 input) // Debug only, so we can live with it. CONTRACT_VIOLATION(ThrowsViolation); - regex::STRRegEx::GroupingContainer groups; - if (regex::STRRegEx::Match("^/(.*)/(i?)$", regex, groups)) - { - regex::STRRegEx::MatchFlags flags = regex::STRRegEx::DefaultMatchFlags; - if (groups[2].Length() != 0) - flags = (regex::STRRegEx::MatchFlags)(flags | regex::STRRegEx::MF_CASE_INSENSITIVE); - - return regex::STRRegEx::Matches(groups[1].Begin(), groups[1].End(), - input, input + strlen(input), flags); - } + regex++; + const char* end = strchr(regex, '/'); + if (end != NULL) + return match(regex, end, input); } return strcmp(regex, input) == 0; } From f54c15a4c3467b472865a0c728ba39b1ef71adbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Mon, 13 Jun 2022 10:42:08 +0900 Subject: [PATCH 072/337] Precisely track reflected on fields (#70546) The AOT compiler used simple logic to decide what fields should be kept/generated: if a type is considered constructed, generate all fields. This works, but it's not very efficient. With this change I'm introducing precise tracking of each field that should be accessible from reflection at runtime. The fields are represented by new nodes within the dependency graph. We track fields on individual generic instantiations and ensure we end up in a consistent state where if e.g. we decided `Class.Foo` should be reflection accessible and `Class` is used elsewhere in the program, `Class.Foo` is also reflection accessible. This matches how IL Linker thinks about reflectability where genericness doesn't matter. We could be more optimal here, but various suppressions in framework rely on this logic. Additional reflectable fields only cost tens of bytes. I had to update various places within the compiler that didn't bother specifying field dependencies because they didn't matter in the past. Added a couple new tests that test the various invariants. This saves 2% in size on a `dotnet new webapi` template project with IlcTrimMetadata on. It is a small regression with `IlcTrimMetadata` off because we actually now track more things for the reflectable field: previously we would not make sure the field is reflection-accessible at runtime. We need a `TypeHandle` for the field type for it to be usable. As a potential future optimization, we could look into allowing reflection to see "unconstructed" `TypeHandles` (and use that one). Reflection is currently not allowed to see unconstructed `TypeHandles` to prevent people falling into a `RuntimeHelpers.AllocateUninitializedObject(someField.FieldType.TypeHandle)` trap that has a bad failure mode right now. Once we fix the failure mode, we could potentially allow it. --- .../Compiler/Dataflow/ReflectionMarker.cs | 4 +- ...CustomAttributeBasedDependencyAlgorithm.cs | 26 ++- .../DependencyAnalysis/FieldMetadataNode.cs | 2 +- .../DependencyAnalysis/GCStaticsNode.cs | 1 + .../DependencyAnalysis/MethodMetadataNode.cs | 2 +- .../DependencyAnalysis/NodeFactory.cs | 11 + .../DependencyAnalysis/NonGCStaticsNode.cs | 1 + .../ReflectableFieldNode.cs | 105 +++++++++ .../DependencyAnalysis/ThreadStaticsNode.cs | 3 +- .../DependencyAnalysis/TypeMetadataNode.cs | 10 + .../Compiler/IRootingServiceProvider.cs | 1 + .../Compiler/MetadataManager.cs | 35 +-- .../Compiler/RootingHelpers.cs | 93 ++++---- .../Compiler/RootingServiceProvider.cs | 6 + .../Compiler/UsageBasedMetadataManager.cs | 199 ++++++++---------- .../IL/ILImporter.Scanner.cs | 3 +- .../ILCompiler.Compiler.csproj | 1 + .../nativeaot/SmokeTests/Dataflow/Dataflow.cs | 4 +- .../DeadCodeElimination.cs | 9 +- .../SmokeTests/Reflection/Reflection.cs | 110 +++++++++- 20 files changed, 442 insertions(+), 184 deletions(-) create mode 100644 src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ReflectableFieldNode.cs diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMarker.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMarker.cs index 3b19dbfcf1ad24..70f3d523ed9e43 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMarker.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMarker.cs @@ -161,7 +161,9 @@ internal void MarkStaticConstructor(in MessageOrigin origin, TypeDesc type) { if (!type.IsGenericDefinition && !type.ContainsSignatureVariables(treatGenericParameterLikeSignatureVariable: true) && type.HasStaticConstructor) { - _dependencies.Add(_factory.CanonicalEntrypoint(type.GetStaticConstructor()), "RunClassConstructor reference"); + // Mark the GC static base - it contains a pointer to the class constructor, but also info + // about whether the class constructor already executed and it's what is looked at at runtime. + _dependencies.Add(_factory.TypeNonGCStaticsSymbol((MetadataType)type), "RunClassConstructor reference"); } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/CustomAttributeBasedDependencyAlgorithm.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/CustomAttributeBasedDependencyAlgorithm.cs index 09111876ceca61..3a8a1438b2bf21 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/CustomAttributeBasedDependencyAlgorithm.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/CustomAttributeBasedDependencyAlgorithm.cs @@ -168,7 +168,8 @@ private static bool AddDependenciesFromCustomAttributeBlob(DependencyList depend { if (decodedArgument.Kind == CustomAttributeNamedArgumentKind.Field) { - // This is an instance field. We don't track them right now. + if (!AddDependenciesFromField(dependencies, factory, attributeType, decodedArgument.Name)) + return false; } else { @@ -186,6 +187,29 @@ private static bool AddDependenciesFromCustomAttributeBlob(DependencyList depend return true; } + private static bool AddDependenciesFromField(DependencyList dependencies, NodeFactory factory, TypeDesc attributeType, string fieldName) + { + FieldDesc field = attributeType.GetField(fieldName); + if (field is not null) + { + if (factory.MetadataManager.IsReflectionBlocked(field)) + return false; + + dependencies.Add(factory.ReflectableField(field), "Custom attribute blob"); + + return true; + } + + // Haven't found it in current type. Check the base type. + TypeDesc baseType = attributeType.BaseType; + + if (baseType != null) + return AddDependenciesFromField(dependencies, factory, baseType, fieldName); + + // Not found. This is bad metadata that will result in a runtime failure, but we shouldn't fail the compilation. + return true; + } + private static bool AddDependenciesFromPropertySetter(DependencyList dependencies, NodeFactory factory, TypeDesc attributeType, string propertyName) { EcmaType attributeTypeDefinition = (EcmaType)attributeType.GetTypeDefinition(); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FieldMetadataNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FieldMetadataNode.cs index 8f701ceb236d3e..603f7c7068fdc7 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FieldMetadataNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/FieldMetadataNode.cs @@ -41,7 +41,7 @@ public override IEnumerable GetStaticDependencies(NodeFacto } protected override string GetName(NodeFactory factory) { - return "Reflectable field: " + _field.ToString(); + return "Field metadata: " + _field.ToString(); } protected override void OnMarked(NodeFactory factory) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GCStaticsNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GCStaticsNode.cs index 0272852f07606d..d4f419c1b424df 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GCStaticsNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/GCStaticsNode.cs @@ -19,6 +19,7 @@ public class GCStaticsNode : ObjectNode, ISymbolDefinitionNode, ISortableSymbolN public GCStaticsNode(MetadataType type, PreinitializationManager preinitManager) { Debug.Assert(!type.IsCanonicalSubtype(CanonicalFormKind.Specific)); + Debug.Assert(!type.IsGenericDefinition); _type = type; if (preinitManager.IsPreinitialized(type)) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MethodMetadataNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MethodMetadataNode.cs index 8f1269d8fdfa3e..427b589090fae2 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MethodMetadataNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/MethodMetadataNode.cs @@ -49,7 +49,7 @@ public override IEnumerable GetStaticDependencies(NodeFacto } protected override string GetName(NodeFactory factory) { - return "Reflectable method: " + _method.ToString(); + return "Method metadata: " + _method.ToString(); } protected override void OnMarked(NodeFactory factory) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs index 6597476d51cabc..54efc8c15c0260 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NodeFactory.cs @@ -294,6 +294,11 @@ private void CreateNodeCaches() return new ReflectableMethodNode(method); }); + _reflectableFields = new NodeCache(field => + { + return new ReflectableFieldNode(field); + }); + _objectGetTypeFlowDependencies = new NodeCache(type => { return new ObjectGetTypeFlowDependenciesNode(type); @@ -852,6 +857,12 @@ public ReflectableMethodNode ReflectableMethod(MethodDesc method) return _reflectableMethods.GetOrAdd(method); } + private NodeCache _reflectableFields; + public ReflectableFieldNode ReflectableField(FieldDesc field) + { + return _reflectableFields.GetOrAdd(field); + } + private NodeCache _objectGetTypeFlowDependencies; internal ObjectGetTypeFlowDependenciesNode ObjectGetTypeFlowDependencies(MetadataType type) { diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NonGCStaticsNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NonGCStaticsNode.cs index 2e52019a1e1532..3c06c90b3c1447 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NonGCStaticsNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/NonGCStaticsNode.cs @@ -25,6 +25,7 @@ public class NonGCStaticsNode : ObjectNode, ISymbolDefinitionNode, ISortableSymb public NonGCStaticsNode(MetadataType type, PreinitializationManager preinitializationManager) { Debug.Assert(!type.IsCanonicalSubtype(CanonicalFormKind.Specific)); + Debug.Assert(!type.IsGenericDefinition); _type = type; _preinitializationManager = preinitializationManager; } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ReflectableFieldNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ReflectableFieldNode.cs new file mode 100644 index 00000000000000..c5bd4945050676 --- /dev/null +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ReflectableFieldNode.cs @@ -0,0 +1,105 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; + +using ILCompiler.DependencyAnalysisFramework; + +using Internal.TypeSystem; + +using Debug = System.Diagnostics.Debug; + +namespace ILCompiler.DependencyAnalysis +{ + /// + /// Represents a field that is gettable/settable from reflection. + /// + public class ReflectableFieldNode : DependencyNodeCore + { + private readonly FieldDesc _field; + + public ReflectableFieldNode(FieldDesc field) + { + Debug.Assert(!field.OwningType.IsCanonicalSubtype(CanonicalFormKind.Any) + || field.OwningType.ConvertToCanonForm(CanonicalFormKind.Specific) == field.OwningType); + _field = field; + } + + public FieldDesc Field => _field; + + public override IEnumerable GetStaticDependencies(NodeFactory factory) + { + Debug.Assert(!factory.MetadataManager.IsReflectionBlocked(_field.GetTypicalFieldDefinition())); + + DependencyList dependencies = new DependencyList(); + factory.MetadataManager.GetDependenciesDueToReflectability(ref dependencies, factory, _field); + + // No runtime artifacts needed if this is a generic definition or literal field + if (_field.OwningType.IsGenericDefinition || _field.IsLiteral) + { + return dependencies; + } + + FieldDesc typicalField = _field.GetTypicalFieldDefinition(); + if (typicalField != _field) + { + // Ensure we consistently apply reflectability to all fields sharing the same definition. + // Bases for different instantiations of the field have a conditional dependency on the definition node that + // brings a ReflectableField of the instantiated field if it's necessary for it to be reflectable. + dependencies.Add(factory.ReflectableField(typicalField), "Definition of the reflectable field"); + } + + // Runtime reflection stack needs to see the type handle of the owning type + dependencies.Add(factory.MaximallyConstructableType(_field.OwningType), "Instance base of a reflectable field"); + + // Root the static base of the type + if (_field.IsStatic && !_field.OwningType.IsCanonicalSubtype(CanonicalFormKind.Any)) + { + // Infrastructure around static constructors is stashed in the NonGC static base + bool needsNonGcStaticBase = factory.PreinitializationManager.HasLazyStaticConstructor(Field.OwningType); + + if (_field.HasRva) + { + // No reflection access right now + } + else if (_field.IsThreadStatic) + { + dependencies.Add(factory.TypeThreadStaticIndex((MetadataType)_field.OwningType), "Threadstatic base of a reflectable field"); + } + else if (_field.HasGCStaticBase) + { + dependencies.Add(factory.TypeGCStaticsSymbol((MetadataType)_field.OwningType), "GC static base of a reflectable field"); + } + else + { + dependencies.Add(factory.TypeNonGCStaticsSymbol((MetadataType)_field.OwningType), "NonGC static base of a reflectable field"); + needsNonGcStaticBase = false; + } + + if (needsNonGcStaticBase) + { + dependencies.Add(factory.TypeNonGCStaticsSymbol((MetadataType)_field.OwningType), "CCtor context"); + } + } + + // Runtime reflection stack needs to obtain the type handle of the field + // (but there's no type handles for function pointers) + if (!_field.FieldType.IsFunctionPointer) + dependencies.Add(factory.MaximallyConstructableType(_field.FieldType.NormalizeInstantiation()), "Type of the field"); + + return dependencies; + } + protected override string GetName(NodeFactory factory) + { + return "Reflectable field: " + _field.ToString(); + } + + public override bool InterestingForDynamicDependencyAnalysis => false; + public override bool HasDynamicDependencies => false; + public override bool HasConditionalStaticDependencies => false; + public override bool StaticDependenciesAreComputed => true; + public override IEnumerable GetConditionalStaticDependencies(NodeFactory factory) => null; + public override IEnumerable SearchDynamicDependencies(List> markedNodes, int firstNode, NodeFactory factory) => null; + } +} diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ThreadStaticsNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ThreadStaticsNode.cs index 91733ace5276c9..03e318318a7f8c 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ThreadStaticsNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ThreadStaticsNode.cs @@ -19,7 +19,8 @@ public class ThreadStaticsNode : EmbeddedObjectNode, ISymbolDefinitionNode public ThreadStaticsNode(MetadataType type, NodeFactory factory) { - Debug.Assert(factory.Target.Abi == TargetAbi.NativeAot || factory.Target.Abi == TargetAbi.CppCodegen); + Debug.Assert(!type.IsCanonicalSubtype(CanonicalFormKind.Specific)); + Debug.Assert(!type.IsGenericDefinition); _type = type; } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeMetadataNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeMetadataNode.cs index e2bff8eb335f23..a85e669a17a532 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeMetadataNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeMetadataNode.cs @@ -58,6 +58,16 @@ public override IEnumerable GetStaticDependencies(NodeFacto // A lot of the enum reflection actually happens on top of the respective MethodTable (e.g. getting the underlying type), // so for enums also include their MethodTable. dependencies.Add(factory.MaximallyConstructableType(_type), "Reflectable enum"); + + // Enums are not useful without their literal fields. The literal fields are not referenced + // from anywhere (source code reference to enums compiles to the underlying numerical constants in IL). + foreach (FieldDesc enumField in _type.GetFields()) + { + if (enumField.IsLiteral) + { + dependencies.Add(factory.FieldMetadata(enumField), "Value of a reflectable enum"); + } + } } // If the user asked for complete metadata to be generated for all types that are getting metadata, ensure that. diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/IRootingServiceProvider.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/IRootingServiceProvider.cs index adff5b36116e1b..c368c762e64ca8 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/IRootingServiceProvider.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/IRootingServiceProvider.cs @@ -13,6 +13,7 @@ public interface IRootingServiceProvider void AddCompilationRoot(MethodDesc method, string reason, string exportName = null); void AddCompilationRoot(TypeDesc type, string reason); void AddReflectionRoot(MethodDesc method, string reason); + void AddReflectionRoot(FieldDesc field, string reason); void RootThreadStaticBaseForType(TypeDesc type, string reason); void RootGCStaticBaseForType(TypeDesc type, string reason); void RootNonGCStaticBaseForType(TypeDesc type, string reason); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs index 5ebf7f1ed3a247..ed672d351e01ce 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/MetadataManager.cs @@ -345,6 +345,19 @@ public void GetDependenciesDueToReflectability(ref DependencyList dependencies, } } + /// + /// This method is an extension point that can provide additional metadata-based dependencies to generated fields. + /// + public void GetDependenciesDueToReflectability(ref DependencyList dependencies, NodeFactory factory, FieldDesc field) + { + MetadataCategory category = GetMetadataCategory(field); + + if ((category & MetadataCategory.Description) != 0) + { + GetMetadataDependenciesDueToReflectability(ref dependencies, factory, field); + } + } + /// /// This method is an extension point that can provide additional metadata-based dependencies on a virtual method. /// @@ -359,6 +372,13 @@ protected virtual void GetMetadataDependenciesDueToReflectability(ref Dependency // and property setters) } + protected virtual void GetMetadataDependenciesDueToReflectability(ref DependencyList dependencies, NodeFactory factory, FieldDesc field) + { + // MetadataManagers can override this to provide additional dependencies caused by the emission of metadata + // (E.g. dependencies caused by the field having custom attributes applied to it: making sure we compile the attribute constructor + // and property setters) + } + /// /// This method is an extension point that can provide additional metadata-based dependencies to generated EETypes. /// @@ -371,15 +391,6 @@ public void GetDependenciesDueToReflectability(ref DependencyList dependencies, GetMetadataDependenciesDueToReflectability(ref dependencies, factory, type); } - if ((category & MetadataCategory.RuntimeMapping) != 0) - { - // We're going to generate a mapping table entry for this. Collect dependencies. - - // Nothing special is needed for the mapping table (we only emit the MethodTable and we already - // have one, since we got this callback). But check if a child wants to do something extra. - GetRuntimeMappingDependenciesDueToReflectability(ref dependencies, factory, type); - } - GetDependenciesDueToEETypePresence(ref dependencies, factory, type); } @@ -390,12 +401,6 @@ protected virtual void GetMetadataDependenciesDueToReflectability(ref Dependency // and property setters) } - protected virtual void GetRuntimeMappingDependenciesDueToReflectability(ref DependencyList dependencies, NodeFactory factory, TypeDesc type) - { - // MetadataManagers can override this to provide additional dependencies caused by the emission of a runtime - // mapping for a type. - } - protected virtual void GetDependenciesDueToEETypePresence(ref DependencyList dependencies, NodeFactory factory, TypeDesc type) { // MetadataManagers can override this to provide additional dependencies caused by the emission of an MethodTable. diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/RootingHelpers.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/RootingHelpers.cs index cd9cdcf8f7039b..a15550b5fa46a9 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/RootingHelpers.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/RootingHelpers.cs @@ -90,6 +90,11 @@ public static void RootType(IRootingServiceProvider rootProvider, TypeDesc type, TryRootMethod(rootProvider, method, reason); } } + + foreach (FieldDesc field in type.GetFields()) + { + TryRootField(rootProvider, field, reason); + } } } @@ -114,6 +119,38 @@ public static void RootMethod(IRootingServiceProvider rootProvider, MethodDesc m rootProvider.AddReflectionRoot(method, reason); } + public static bool TryRootField(IRootingServiceProvider rootProvider, FieldDesc field, string reason) + { + try + { + RootField(rootProvider, field, reason); + return true; + } + catch (TypeSystemException) + { + return false; + } + } + + public static void RootField(IRootingServiceProvider rootProvider, FieldDesc field, string reason) + { + // Make sure we're not putting something into the graph that will crash later. + if (field.IsLiteral) + { + // Nothing to check + } + else if (field.IsStatic) + { + field.OwningType.ComputeStaticFieldLayout(StaticLayoutKind.StaticRegionSizes); + } + else + { + field.OwningType.ComputeInstanceLayout(InstanceLayoutKind.TypeOnly); + } + + rootProvider.AddReflectionRoot(field, reason); + } + public static bool TryGetDependenciesForReflectedMethod(ref DependencyList dependencies, NodeFactory factory, MethodDesc method, string reason) { MethodDesc typicalMethod = method.GetTypicalMethodDefinition(); @@ -180,6 +217,22 @@ public static bool TryGetDependenciesForReflectedMethod(ref DependencyList depen public static bool TryGetDependenciesForReflectedField(ref DependencyList dependencies, NodeFactory factory, FieldDesc field, string reason) { + FieldDesc typicalField = field.GetTypicalFieldDefinition(); + if (factory.MetadataManager.IsReflectionBlocked(typicalField)) + { + return false; + } + + dependencies ??= new DependencyList(); + + // If this is a field on generic type, make sure we at minimum have the metadata + // for it. This hedges against the risk that we fail to figure out an instantiated base + // for it below. + if (typicalField.OwningType.HasInstantiation) + { + dependencies.Add(factory.ReflectableField(typicalField), reason); + } + // If there's any genericness involved, try to create a fitting instantiation that would be usable at runtime. // This is not a complete solution to the problem. // If we ever decide that MakeGenericType/MakeGenericMethod should simply be considered unsafe, this code can be deleted @@ -198,45 +251,7 @@ public static bool TryGetDependenciesForReflectedField(ref DependencyList depend ((MetadataType)owningType).MakeInstantiatedType(inst)); } - if (factory.MetadataManager.IsReflectionBlocked(field)) - { - return false; - } - - if (!TryGetDependenciesForReflectedType(ref dependencies, factory, field.OwningType, reason)) - { - return false; - } - - // Currently generating the base of the type is enough to make the field reflectable. - - if (field.OwningType.IsCanonicalSubtype(CanonicalFormKind.Any)) - { - return true; - } - - if (field.IsStatic && !field.IsLiteral && !field.HasRva) - { - bool cctorContextAdded = false; - if (field.IsThreadStatic) - { - dependencies.Add(factory.TypeThreadStaticIndex((MetadataType)field.OwningType), reason); - } - else if (field.HasGCStaticBase) - { - dependencies.Add(factory.TypeGCStaticsSymbol((MetadataType)field.OwningType), reason); - } - else - { - dependencies.Add(factory.TypeNonGCStaticsSymbol((MetadataType)field.OwningType), reason); - cctorContextAdded = true; - } - - if (!cctorContextAdded && factory.PreinitializationManager.HasLazyStaticConstructor(field.OwningType)) - { - dependencies.Add(factory.TypeNonGCStaticsSymbol((MetadataType)field.OwningType), reason); - } - } + dependencies.Add(factory.ReflectableField(field), reason); return true; } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/RootingServiceProvider.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/RootingServiceProvider.cs index ce5dd8f931f919..31419393a1d846 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/RootingServiceProvider.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/RootingServiceProvider.cs @@ -46,6 +46,12 @@ public void AddReflectionRoot(MethodDesc method, string reason) _rootAdder(_factory.ReflectableMethod(method), reason); } + public void AddReflectionRoot(FieldDesc field, string reason) + { + if (!_factory.MetadataManager.IsReflectionBlocked(field)) + _rootAdder(_factory.ReflectableField(field), reason); + } + public void RootThreadStaticBaseForType(TypeDesc type, string reason) { Debug.Assert(!type.IsGenericDefinition); diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs index c5b5a458afbd3f..c4fedd71ae1f35 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs @@ -40,7 +40,6 @@ public sealed class UsageBasedMetadataManager : GeneratingMetadataManager private readonly CompilationModuleGroup _compilationModuleGroup; internal readonly UsageBasedMetadataGenerationOptions _generationOptions; - private readonly bool _hasPreciseFieldUsageInformation; private readonly FeatureSwitchHashtable _featureSwitchHashtable; @@ -48,6 +47,7 @@ public sealed class UsageBasedMetadataManager : GeneratingMetadataManager private readonly List _fieldsWithMetadata = new List(); private readonly List _methodsWithMetadata = new List(); private readonly List _typesWithMetadata = new List(); + private readonly List _fieldsWithRuntimeMapping = new List(); private readonly List _customAttributesWithMetadata = new List(); private readonly HashSet _rootEntireAssembliesExaminedModules = new HashSet(); @@ -75,8 +75,6 @@ public UsageBasedMetadataManager( IEnumerable trimmedAssemblies) : base(typeSystemContext, blockingPolicy, resourceBlockingPolicy, logFile, stackTracePolicy, invokeThunkGenerationPolicy) { - // We use this to mark places that would behave differently if we tracked exact fields used. - _hasPreciseFieldUsageInformation = false; _compilationModuleGroup = group; _generationOptions = generationOptions; @@ -122,6 +120,22 @@ protected override void Graph_NewMarkedNode(DependencyNodeCore obj) { _customAttributesWithMetadata.Add(customAttributeMetadataNode.CustomAttribute); } + + var reflectableFieldNode = obj as ReflectableFieldNode; + if (reflectableFieldNode != null) + { + FieldDesc field = reflectableFieldNode.Field; + TypeDesc fieldOwningType = field.OwningType; + + // Filter out to those that make sense to have in the mapping tables + if (!fieldOwningType.IsGenericDefinition + && !field.IsLiteral + && (!fieldOwningType.IsCanonicalSubtype(CanonicalFormKind.Specific) || !field.IsStatic)) + { + Debug.Assert((GetMetadataCategory(field) & MetadataCategory.RuntimeMapping) != 0); + _fieldsWithRuntimeMapping.Add(field); + } + } } protected override MetadataCategory GetMetadataCategory(FieldDesc field) @@ -192,26 +206,16 @@ protected override void GetMetadataDependenciesDueToReflectability(ref Dependenc dependencies.Add(factory.MethodMetadata(method.GetTypicalMethodDefinition()), "Reflectable method"); } + protected override void GetMetadataDependenciesDueToReflectability(ref DependencyList dependencies, NodeFactory factory, FieldDesc field) + { + dependencies = dependencies ?? new DependencyList(); + dependencies.Add(factory.FieldMetadata(field.GetTypicalFieldDefinition()), "Reflectable field"); + } + protected override void GetMetadataDependenciesDueToReflectability(ref DependencyList dependencies, NodeFactory factory, TypeDesc type) { TypeMetadataNode.GetMetadataDependencies(ref dependencies, factory, type, "Reflectable type"); - // If we don't have precise field usage information, apply policy that all fields that - // are eligible to have metadata get metadata. - if (!_hasPreciseFieldUsageInformation) - { - TypeDesc typeDefinition = type.GetTypeDefinition(); - - foreach (FieldDesc field in typeDefinition.GetFields()) - { - if ((GetMetadataCategory(field) & MetadataCategory.Description) != 0) - { - dependencies = dependencies ?? new DependencyList(); - dependencies.Add(factory.FieldMetadata(field), "Field of a reflectable type"); - } - } - } - MetadataType mdType = type as MetadataType; // If anonymous type heuristic is turned on and this is an anonymous type, make sure we have @@ -338,48 +342,19 @@ private static bool IsTrimmableAssembly(ModuleDesc assembly) return false; } - protected override void GetRuntimeMappingDependenciesDueToReflectability(ref DependencyList dependencies, NodeFactory factory, TypeDesc type) + public override bool HasConditionalDependenciesDueToEETypePresence(TypeDesc type) { - // If we precisely track field usage, we don't need the logic below. - if (_hasPreciseFieldUsageInformation) - return; - - const string reason = "Reflection"; - - // This logic is applying policy: if a type is reflectable (has a runtime mapping), all of it's fields - // are reflectable (with a runtime mapping) as well. - // This is potentially overly broad (we don't know if any of the fields will actually be eligile - // for metadata - e.g. they could all be reflection blocked). This is fine since lack of - // precise field usage information is already not ideal from a size on disk perspective. - // The more precise way to do this would be to go over each field, check that it's eligible for RuntimeMapping - // according to the policy (e.g. it's not blocked), and only then root the base of the field. - if (type is MetadataType metadataType && !type.IsGenericDefinition) - { - Debug.Assert(!type.IsCanonicalSubtype(CanonicalFormKind.Any)); - - if (metadataType.GCStaticFieldSize.AsInt > 0) - { - dependencies.Add(factory.TypeGCStaticsSymbol(metadataType), reason); - } - - if (metadataType.NonGCStaticFieldSize.AsInt > 0 || factory.PreinitializationManager.HasLazyStaticConstructor(metadataType)) - { - dependencies.Add(factory.TypeNonGCStaticsSymbol(metadataType), reason); - } + // Note: these are duplicated with the checks in GetConditionalDependenciesDueToEETypePresence - if (metadataType.ThreadGcStaticFieldSize.AsInt > 0) - { - dependencies.Add(factory.TypeThreadStaticIndex(metadataType), reason); - } + // If there's dataflow annotations on the type, we have conditional dependencies + if (type.IsDefType && !type.IsInterface && FlowAnnotations.GetTypeAnnotation(type) != default) + return true; - Debug.Assert(metadataType.ThreadNonGcStaticFieldSize.AsInt == 0); - } - } + // If we need to ensure fields are consistently reflectable on various generic instances + if (type.HasInstantiation && !type.IsGenericDefinition && !IsReflectionBlocked(type)) + return true; - public override bool HasConditionalDependenciesDueToEETypePresence(TypeDesc type) - { - // Note: duplicated with the check in GetConditionalDependenciesDueToEETypePresence - return type.IsDefType && !type.IsInterface && FlowAnnotations.GetTypeAnnotation(type) != default; + return false; } public override void GetConditionalDependenciesDueToEETypePresence(ref CombinedDependencyList dependencies, NodeFactory factory, TypeDesc type) @@ -435,16 +410,34 @@ public override void GetConditionalDependenciesDueToEETypePresence(ref CombinedD // of the bases/interfaces are annotated. // ObjectGetTypeFlowDependencies don't need to be conditional in that case. They'll be added as needed. } + + // Ensure fields can be consistently reflection set & get. + if (type.HasInstantiation && !type.IsTypeDefinition && !IsReflectionBlocked(type)) + { + foreach (FieldDesc field in type.GetFields()) + { + // Tiny optimization: no get/set for literal fields since they only exist in metadata + if (field.IsLiteral) + continue; + + if (IsReflectionBlocked(field)) + continue; + + dependencies ??= new CombinedDependencyList(); + dependencies.Add(new DependencyNodeCore.CombinedDependencyListEntry( + factory.ReflectableField(field), + factory.ReflectableField(field.GetTypicalFieldDefinition()), + "GetType called on the interface")); + } + } } public override void GetDependenciesDueToLdToken(ref DependencyList dependencies, NodeFactory factory, FieldDesc field) { - // In order for the RuntimeFieldHandle data structure to be usable at runtime, ensure the field - // is generating metadata. - if ((GetMetadataCategory(field) & MetadataCategory.Description) == MetadataCategory.Description) + if (!IsReflectionBlocked(field)) { dependencies = dependencies ?? new DependencyList(); - dependencies.Add(factory.FieldMetadata(field.GetTypicalFieldDefinition()), "LDTOKEN field"); + dependencies.Add(factory.ReflectableField(field), "LDTOKEN field"); } } @@ -571,26 +564,7 @@ public override void GetDependenciesDueToVirtualMethodReflectability(ref Depende protected override IEnumerable GetFieldsWithRuntimeMapping() { - if (_hasPreciseFieldUsageInformation) - { - // TODO - } - else - { - // This applies a policy that fields inherit runtime mapping from their owning type, - // unless they are blocked. - foreach (var type in GetTypesWithRuntimeMapping()) - { - if (type.IsGenericDefinition) - continue; - - foreach (var field in type.GetFields()) - { - if ((GetMetadataCategory(field) & MetadataCategory.RuntimeMapping) != 0) - yield return field; - } - } - } + return _fieldsWithRuntimeMapping; } public override IEnumerable GetCompilationModulesWithMetadata() @@ -625,6 +599,28 @@ public override void GetDependenciesDueToAccess(ref DependencyList dependencies, dependencies = dependencies ?? new DependencyList(); dependencies.Add(factory.DataflowAnalyzedMethod(methodIL.GetMethodILDefinition()), "Access to interesting field"); } + + if ((_generationOptions & UsageBasedMetadataGenerationOptions.ReflectedMembersOnly) == 0 + && !IsReflectionBlocked(writtenField)) + { + FieldDesc fieldToReport = writtenField; + + // The field could be on something odd like Foo<__Canon, object>. Normalize to Foo<__Canon, __Canon>. + TypeDesc fieldOwningType = writtenField.OwningType; + if (fieldOwningType.IsCanonicalSubtype(CanonicalFormKind.Specific)) + { + TypeDesc fieldOwningTypeNormalized = fieldOwningType.NormalizeInstantiation(); + if (fieldOwningType != fieldOwningTypeNormalized) + { + fieldToReport = factory.TypeSystemContext.GetFieldForInstantiatedType( + writtenField.GetTypicalFieldDefinition(), + (InstantiatedType)fieldOwningTypeNormalized); + } + } + + dependencies = dependencies ?? new DependencyList(); + dependencies.Add(factory.ReflectableField(fieldToReport), "Use of a field"); + } } public override void GetDependenciesDueToAccess(ref DependencyList dependencies, NodeFactory factory, MethodIL methodIL, MethodDesc calledMethod) @@ -795,41 +791,16 @@ public MetadataManager ToAnalysisBasedMetadataManager() reflectableFields[fieldWithMetadata] = MetadataCategory.Description; } - if (_hasPreciseFieldUsageInformation) - { - // TODO - } - else + foreach (var fieldWithRuntimeMapping in _fieldsWithRuntimeMapping) { - // If we don't have precise field usage information we apply a policy that - // says the fields inherit the setting from the type, potentially restricted by blocking. - // (I.e. if a type has RuntimeMapping metadata, the field has RuntimeMapping too, unless blocked.) - foreach (var reflectableType in reflectableTypes.ToEnumerable()) - { - if (reflectableType.Entity.IsGenericDefinition) - continue; + reflectableFields[fieldWithRuntimeMapping] |= MetadataCategory.RuntimeMapping; - if (reflectableType.Entity.IsCanonicalSubtype(CanonicalFormKind.Specific)) - continue; - - if ((reflectableType.Category & MetadataCategory.RuntimeMapping) == 0) - continue; - - foreach (var field in reflectableType.Entity.GetFields()) - { - if (!IsReflectionBlocked(field)) - { - reflectableFields[field] |= MetadataCategory.RuntimeMapping; - - // Also set the description bit if the definition is getting metadata. - FieldDesc typicalField = field.GetTypicalFieldDefinition(); - if (field != typicalField && - (reflectableFields[typicalField] & MetadataCategory.Description) != 0) - { - reflectableFields[field] |= MetadataCategory.Description; - } - } - } + // Also set the description bit if the definition is getting metadata. + FieldDesc typicalField = fieldWithRuntimeMapping.GetTypicalFieldDefinition(); + if (fieldWithRuntimeMapping != typicalField && + (reflectableFields[typicalField] & MetadataCategory.Description) != 0) + { + reflectableFields[fieldWithRuntimeMapping] |= MetadataCategory.Description; } } 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 20246847b661c1..a5f1ce07c3c220 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs @@ -975,8 +975,9 @@ private void ImportReadOnlyPrefix() private void ImportFieldAccess(int token, bool isStatic, string reason) { var field = (FieldDesc)_methodIL.GetObject(token); + var canonField = (FieldDesc)_canonMethodIL.GetObject(token); - _compilation.NodeFactory.MetadataManager.GetDependenciesDueToAccess(ref _dependencies, _compilation.NodeFactory, _canonMethodIL, field); + _compilation.NodeFactory.MetadataManager.GetDependenciesDueToAccess(ref _dependencies, _compilation.NodeFactory, _canonMethodIL, canonField); // Covers both ldsfld/ldsflda and ldfld/ldflda with a static field if (isStatic || field.IsStatic) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj b/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj index 6f19f9f7acc733..92718ba7ce9303 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj @@ -351,6 +351,7 @@ + diff --git a/src/tests/nativeaot/SmokeTests/Dataflow/Dataflow.cs b/src/tests/nativeaot/SmokeTests/Dataflow/Dataflow.cs index da7578fed1bf2d..ea614207540041 100644 --- a/src/tests/nativeaot/SmokeTests/Dataflow/Dataflow.cs +++ b/src/tests/nativeaot/SmokeTests/Dataflow/Dataflow.cs @@ -108,8 +108,8 @@ public static void Run() Assert.NotNull(typeof(TestType1).GetMethod(nameof(TestType1.TestMethod))); Assert.Equal(1, typeof(TestType1).CountMethods()); - //Assert.NotNull(typeof(TestType1).GetField(nameof(TestType1.TestField))); - //Assert.Equal(1, typeof(TestType1).CountFields()); + Assert.NotNull(typeof(TestType1).GetField(nameof(TestType1.TestField))); + Assert.Equal(1, typeof(TestType1).CountFields()); Assert.NotNull(typeof(TestType2).GetProperty(nameof(TestType2.TestProperty))); Assert.NotNull(typeof(TestType2).GetProperty(nameof(TestType2.TestProperty)).GetGetMethod()); diff --git a/src/tests/nativeaot/SmokeTests/DeadCodeElimination/DeadCodeElimination.cs b/src/tests/nativeaot/SmokeTests/DeadCodeElimination/DeadCodeElimination.cs index a638598f1e91fd..f133eb28f5d2b2 100644 --- a/src/tests/nativeaot/SmokeTests/DeadCodeElimination/DeadCodeElimination.cs +++ b/src/tests/nativeaot/SmokeTests/DeadCodeElimination/DeadCodeElimination.cs @@ -47,9 +47,7 @@ class NeverAllocatedType public Type DoSomething() => typeof(UnreferencedType); } -#if DEBUG - static NeverAllocatedType s_instance = null; -#else +#if !DEBUG static object s_instance = new object[10]; #endif @@ -58,8 +56,9 @@ public static void Run() Console.WriteLine("Testing instance methods on unallocated types"); #if DEBUG - if (s_instance != null) - s_instance.DoSomething(); + NeverAllocatedType instance = null; + if (instance != null) + instance.DoSomething(); #else // In release builds additionally test that the "is" check didn't introduce the constructed type if (s_instance is NeverAllocatedType never) diff --git a/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs b/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs index 53a2100b287960..ab559549cdfc84 100644 --- a/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs +++ b/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs @@ -30,6 +30,7 @@ private static int Main() TestSimpleDelegateTargets.Run(); TestVirtualDelegateTargets.Run(); TestRunClassConstructor.Run(); + TestFieldMetadata.Run(); #if !OPTIMIZED_MODE_WITHOUT_SCANNER TestContainment.Run(); TestInterfaceMethod.Run(); @@ -1756,6 +1757,104 @@ public static void Run() } } + class TestFieldMetadata + { + class ClassWithTwoFields + { + public static int UsedField; + public static UnusedClass UnusedField; + } + + class UnusedClass { } + + interface IMessWithYou { } + class GenericTypeWithUnsatisfiableConstrains where T : struct, IMessWithYou + { + public static int SomeField; + } + + class GenericClass + { + public static string SomeField; + } + + struct Atom1 { } + struct Atom2 { } + struct Atom3 { } + + public static void Run() + { + ClassWithTwoFields.UsedField = 123; + +#if REFLECTION_FROM_USAGE + // Merely accessing a field should trigger full reflectability of it when reflection from + // usage is active. + Type classWithTwoFields = GetTestType(nameof(TestFieldMetadata), nameof(ClassWithTwoFields)); + if ((int)classWithTwoFields.GetField(nameof(ClassWithTwoFields.UsedField)).GetValue(null) != 123) + { + throw new Exception(); + } + + // But the unused field should not exist + if (classWithTwoFields.GetField(nameof(ClassWithTwoFields.UnusedField)) != null) + { + throw new Exception(); + } +#else + // If reflection from usage is not active, we shouldn't even see the owning type, despite the field use + if (SecretGetType(nameof(TestFieldMetadata), nameof(ClassWithTwoFields)) != null) + { + throw new Exception(); + } +#endif + // The type of the unused field shouldn't be generated under any circumstances + if (SecretGetType(nameof(TestFieldMetadata), nameof(UnusedClass)) != null) + { + throw new Exception(); + } + + // The compiler cannot fulfil this instantiation without universal shared code. + // We should get a working metadata-only type that can be inspected. + if (typeof(GenericTypeWithUnsatisfiableConstrains<>).GetField("SomeField").Name != "SomeField") + { + throw new Exception(); + } + + // Access a field on a generic type in an obvious way + if (typeof(GenericClass).GetField(nameof(GenericClass.SomeField)).Name != "SomeField") + { + throw new Exception(); + } + + // We should be able to reflection-see the field on other reflection visible generic instances + // of the same generic type definition. + GetGenericClassOfAtom2().GetField("SomeField").SetValue(null, "Cookie"); + static Type GetGenericClassOfAtom2() => typeof(GenericClass); + + GenericClass.SomeField = "1234"; +#if REFLECTION_FROM_USAGE + // If we're doing reflection from usage, we used the field and we expect it to be reflectable + typeof(GenericClass<>).MakeGenericType(GetAtom3()).GetField("SomeField").SetValue(null, "Cookie"); +#else + // If we're not doing reflection from usage, the generic instance shouldn't even exist. + // We only touched the static base of the type, not the whole type. + bool exists = false; + try + { + typeof(GenericClass<>).MakeGenericType(GetAtom3()); + exists = true; + } + catch + { + exists = false; + } + if (exists) + throw new Exception(); +#endif + static Type GetAtom3() => typeof(Atom3); + } + } + class TestRunClassConstructor { static class TypeWithNoStaticFieldsButACCtor @@ -1778,12 +1877,17 @@ public static void Run() #region Helpers - private static Type GetTestType(string testName, string typeName) + private static Type SecretGetType(string testName, string typeName) { string fullTypeName = $"{nameof(ReflectionTest)}+{testName}+{typeName}"; - Type result = Type.GetType(fullTypeName); + return Type.GetType(fullTypeName); + } + + private static Type GetTestType(string testName, string typeName) + { + Type result = SecretGetType(testName, typeName); if (result == null) - throw new Exception($"'{fullTypeName}' could not be located"); + throw new Exception($"'{testName}.{typeName}' could not be located"); return result; } From a0b426dc781be2f3e38bb13856d15e2fa595a589 Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Sun, 12 Jun 2022 21:03:42 -0700 Subject: [PATCH 073/337] [NativeAOT] Fixes resource warning on a HW app (#70356) --- .../nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets index a6b599cd1bdca6..cd57a1ba8b358a 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets @@ -46,7 +46,6 @@ The .NET Foundation licenses this file to you under the MIT license. - false true false From 4f812579dcecc52e2ffcfeb2e3facaef941d6100 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Sun, 12 Jun 2022 21:43:40 -0700 Subject: [PATCH 074/337] Revert "Unpin locals (#70264)" (#70627) This reverts commit b1c227546ee2ff7f387b1ccc4a3e2f1f1606e4c0. --- src/coreclr/jit/compiler.h | 2 - src/coreclr/jit/gentree.h | 5 --- src/coreclr/jit/lclvars.cpp | 80 ++++++++++++++----------------------- 3 files changed, 30 insertions(+), 57 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 909c22906c8921..c838b9e9c7268f 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -614,8 +614,6 @@ class LclVarDsc unsigned char lvSingleDefDisqualifyReason = 'H'; #endif - unsigned char lvAllDefsAreNoGc : 1; // For pinned locals: true if all defs of this local are no-gc - #if FEATURE_MULTIREG_ARGS regNumber lvRegNumForSlot(unsigned slotNum) { diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index 5728b9e43fc890..6ef9cb3032e0af 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -1109,11 +1109,6 @@ struct GenTree return true; } - bool IsNotGcDef() const - { - return IsIntegralConst(0) || IsLocalAddrExpr(); - } - // LIR flags // These helper methods, along with the flag values they manipulate, are defined in lir.h // diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index d51104d1b93e4a..cc12c8a3837dad 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -4181,57 +4181,49 @@ void Compiler::lvaMarkLclRefs(GenTree* tree, BasicBlock* block, Statement* stmt, /* Is this an assignment to a local variable? */ - if (op1->gtOper == GT_LCL_VAR) + if (op1->gtOper == GT_LCL_VAR && op2->gtType != TYP_BOOL) { - LclVarDsc* varDsc = lvaGetDesc(op1->AsLclVarCommon()); + /* Only simple assignments allowed for booleans */ - if (varDsc->lvPinned && varDsc->lvAllDefsAreNoGc) + if (tree->gtOper != GT_ASG) { - if (!op2->IsNotGcDef()) - { - varDsc->lvAllDefsAreNoGc = false; - } + goto NOT_BOOL; } - if (op2->gtType != TYP_BOOL) - { - /* Only simple assignments allowed for booleans */ + /* Is the RHS clearly a boolean value? */ - if (tree->gtOper != GT_ASG) - { - goto NOT_BOOL; - } + switch (op2->gtOper) + { + unsigned lclNum; - /* Is the RHS clearly a boolean value? */ + case GT_CNS_INT: - switch (op2->gtOper) - { - case GT_CNS_INT: + if (op2->AsIntCon()->gtIconVal == 0) + { + break; + } + if (op2->AsIntCon()->gtIconVal == 1) + { + break; + } - if (op2->AsIntCon()->gtIconVal == 0) - { - break; - } - if (op2->AsIntCon()->gtIconVal == 1) - { - break; - } + // Not 0 or 1, fall through .... + FALLTHROUGH; - // Not 0 or 1, fall through .... - FALLTHROUGH; + default: - default: + if (op2->OperIsCompare()) + { + break; + } - if (op2->OperIsCompare()) - { - break; - } + NOT_BOOL: - NOT_BOOL: + lclNum = op1->AsLclVarCommon()->GetLclNum(); + noway_assert(lclNum < lvaCount); - varDsc->lvIsBoolean = false; - break; - } + lvaTable[lclNum].lvIsBoolean = false; + break; } } } @@ -4286,8 +4278,7 @@ void Compiler::lvaMarkLclRefs(GenTree* tree, BasicBlock* block, Statement* stmt, { if (lvaVarAddrExposed(lclNum)) { - varDsc->lvIsBoolean = false; - varDsc->lvAllDefsAreNoGc = false; + varDsc->lvIsBoolean = false; } if (tree->gtOper == GT_LCL_FLD) @@ -4712,8 +4703,6 @@ void Compiler::lvaComputeRefCounts(bool isRecompute, bool setSlotNumbers) varDsc->setLvRefCnt(0); varDsc->setLvRefCntWtd(BB_ZERO_WEIGHT); - varDsc->lvAllDefsAreNoGc = true; - // Special case for some varargs params ... these must // remain unreferenced. const bool isSpecialVarargsParam = varDsc->lvIsParam && raIsVarargsStackArg(lclNum); @@ -4761,8 +4750,6 @@ void Compiler::lvaComputeRefCounts(bool isRecompute, bool setSlotNumbers) { varDsc->lvSingleDef = varDsc->lvIsParam; varDsc->lvSingleDefRegCandidate = varDsc->lvIsParam; - - varDsc->lvAllDefsAreNoGc = true; } } @@ -4881,13 +4868,6 @@ void Compiler::lvaComputeRefCounts(bool isRecompute, bool setSlotNumbers) varDsc->lvImplicitlyReferenced = 1; } } - - if (varDsc->lvPinned && varDsc->lvAllDefsAreNoGc) - { - varDsc->lvPinned = 0; - - JITDUMP("V%02u was unpinned as all def candidates were local.\n", lclNum); - } } } From a103efd28d46af39fc22a77458a11d204226e8d4 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Mon, 13 Jun 2022 09:03:47 +0200 Subject: [PATCH 075/337] Revert "? true : false" removal (#70631) --- .../src/System/Collections/Generic/ArraySortHelper.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs index bc62fc90b08eb6..966a1b0ba4358b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/ArraySortHelper.cs @@ -576,7 +576,7 @@ private static bool LessThan(ref T left, ref T right) if (typeof(T) == typeof(float)) return (float)(object)left < (float)(object)right; if (typeof(T) == typeof(double)) return (double)(object)left < (double)(object)right; if (typeof(T) == typeof(Half)) return (Half)(object)left < (Half)(object)right; - return left.CompareTo(right) < 0; + return left.CompareTo(right) < 0 ? true : false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] // compiles to a single comparison or method call @@ -595,7 +595,7 @@ private static bool GreaterThan(ref T left, ref T right) if (typeof(T) == typeof(float)) return (float)(object)left > (float)(object)right; if (typeof(T) == typeof(double)) return (double)(object)left > (double)(object)right; if (typeof(T) == typeof(Half)) return (Half)(object)left > (Half)(object)right; - return left.CompareTo(right) > 0; + return left.CompareTo(right) > 0 ? true : false; } } From 5c559f14ff23a34eb5585bc8112a73a579648b87 Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Mon, 13 Jun 2022 11:13:09 +0200 Subject: [PATCH 076/337] Add fake server test for Negotiate authentication. (#70396) * Add fake server test for Negotiate authentication. Fix incorrect computation of IsCompleted in managed NTLM implementation. * Fix tests on Windows (raw NTLM disguised as Negotiate) * Get the Negotiate test passing on Linux with all the MIC checks --- .../System/Net/NTAuthentication.Managed.cs | 6 +- .../UnitTests/Fakes/FakeNegotiateServer.cs | 278 ++++++++++++++++++ .../tests/UnitTests/Fakes/FakeNtlmServer.cs | 22 +- .../tests/UnitTests/NTAuthenticationTests.cs | 45 +++ .../System.Net.Security.Unit.Tests.csproj | 1 + 5 files changed, 345 insertions(+), 7 deletions(-) create mode 100644 src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeNegotiateServer.cs diff --git a/src/libraries/Common/src/System/Net/NTAuthentication.Managed.cs b/src/libraries/Common/src/System/Net/NTAuthentication.Managed.cs index 335550d9f9c4f5..6209eb56917f32 100644 --- a/src/libraries/Common/src/System/Net/NTAuthentication.Managed.cs +++ b/src/libraries/Common/src/System/Net/NTAuthentication.Managed.cs @@ -316,7 +316,7 @@ internal void CloseContext() { Debug.Assert(decodedIncomingBlob != null); - if (_isSpNego) + if (!_isSpNego) { IsCompleted = true; } @@ -918,12 +918,12 @@ private unsafe byte[] ProcessSpNegoChallenge(byte[] challenge) { using (writer.PushSequence()) { - using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenInit.MechToken))) + using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.ResponseToken))) { writer.WriteOctetString(response); } - using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenInit.MechListMIC))) + using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.MechListMIC))) { writer.WriteOctetString(GetMIC(_spnegoMechList)); } diff --git a/src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeNegotiateServer.cs b/src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeNegotiateServer.cs new file mode 100644 index 00000000000000..91149e7779fe97 --- /dev/null +++ b/src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeNegotiateServer.cs @@ -0,0 +1,278 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; +using System.Buffers.Binary; +using System.Text; +using System.Net; +using System.Security.Cryptography; +using System.Net.Security; +using System.Formats.Asn1; +using Xunit; + +namespace System.Net.Security +{ + internal class FakeNegotiateServer + { + FakeNtlmServer _ntlmServer; + byte[]? _spnegoMechList = null; + bool _ntlmPassthrough = false; + + private enum NegotiationToken + { + NegTokenInit = 0, + NegTokenResp = 1 + } + + private enum NegTokenInit + { + MechTypes = 0, + ReqFlags = 1, + MechToken = 2, + MechListMIC = 3 + } + + private enum NegTokenResp + { + NegState = 0, + SupportedMech = 1, + ResponseToken = 2, + MechListMIC = 3 + } + + private enum NegState + { + AcceptCompleted = 0, + AcceptIncomplete = 1, + Reject = 2, + RequestMic = 3 + } + + private const string SpnegoOid = "1.3.6.1.5.5.2"; + private const string NtlmOid = "1.3.6.1.4.1.311.2.2.10"; + private static ReadOnlySpan NtlmHeader => "NTLMSSP\0"u8; + + // Behavior modifiers + public bool RequestMIC { get; set; } = true; + + // Negotiation results + public bool IsAuthenticated { get; private set; } + + public FakeNegotiateServer(FakeNtlmServer ntlmServer) + { + _ntlmServer = ntlmServer; + } + + public byte[]? GetOutgoingBlob(byte[]? incomingBlob) + { + if (_spnegoMechList == null && incomingBlob.AsSpan().StartsWith(NtlmHeader)) + { + _ntlmPassthrough = true; + // Windows often sends pure NTLM instead of proper Negotiate, handle that as passthrough + byte[]? outgoingBlob = _ntlmServer.GetOutgoingBlob(incomingBlob); + IsAuthenticated = _ntlmServer.IsAuthenticated; + return outgoingBlob; + } + + Assert.False(_ntlmPassthrough); + + AsnReader reader = new AsnReader(incomingBlob, AsnEncodingRules.DER); + if (_spnegoMechList == null) + { + AsnReader initialContextTokenReader = reader.ReadSequence(new Asn1Tag(TagClass.Application, 0)); + + string spNegoOid = initialContextTokenReader.ReadObjectIdentifier(); + Assert.Equal(SpnegoOid, spNegoOid); + + AsnReader negTokenInitReader = initialContextTokenReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegotiationToken.NegTokenInit)).ReadSequence(); + AsnReader mechTypesOuterReader = negTokenInitReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenInit.MechTypes)); + _spnegoMechList = mechTypesOuterReader.PeekEncodedValue().ToArray(); + + bool hasNtlm = false; + bool isNtlmPreferred = false; + bool first = true; + AsnReader mechTypesReader = mechTypesOuterReader.ReadSequence(); + while (mechTypesReader.HasData) + { + string mechType = mechTypesReader.ReadObjectIdentifier(); + if (mechType == NtlmOid) + { + hasNtlm = true; + isNtlmPreferred = first; + } + first = false; + } + + // Skip context flags, if present + if (negTokenInitReader.HasData && negTokenInitReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenInit.ReqFlags))) + { + negTokenInitReader.ReadSequence(); + } + + byte[]? mechToken = null; + if (negTokenInitReader.HasData && negTokenInitReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenInit.MechToken))) + { + AsnReader mechTokenReader = negTokenInitReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenInit.MechToken)); + mechToken = mechTokenReader.ReadOctetString(); + Assert.False(mechTokenReader.HasData); + } + + byte[]? mechListMIC = null; + if (negTokenInitReader.HasData && negTokenInitReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenInit.MechListMIC))) + { + AsnReader mechListMICReader = negTokenInitReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenInit.MechListMIC)); + mechListMIC = mechListMICReader.ReadOctetString(); + Assert.False(mechListMICReader.HasData); + } + + Assert.True(hasNtlm); + + // If the preferred mechanism was NTLM then proceed with the given token + byte[]? outgoingBlob = null; + if (isNtlmPreferred && mechToken != null) + { + Assert.Null(mechListMIC); + outgoingBlob = _ntlmServer.GetOutgoingBlob(mechToken); + } + + // Generate reply + AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); + using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegotiationToken.NegTokenResp))) + { + using (writer.PushSequence()) + { + using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.NegState))) + { + if (RequestMIC) + { + writer.WriteEnumeratedValue(NegState.RequestMic); + } + else + { + writer.WriteEnumeratedValue(NegState.AcceptIncomplete); + } + } + + using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.SupportedMech))) + { + writer.WriteObjectIdentifier(NtlmOid); + } + + if (outgoingBlob != null) + { + using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.ResponseToken))) + { + writer.WriteOctetString(outgoingBlob); + } + } + } + } + + return writer.Encode(); + } + else + { + AsnReader negTokenRespReader = reader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegotiationToken.NegTokenResp)).ReadSequence(); + + Assert.True(negTokenRespReader.HasData); + NegState? clientState; + if (negTokenRespReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.NegState))) + { + AsnReader valueReader = negTokenRespReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.NegState)); + clientState = valueReader.ReadEnumeratedValue(); + Assert.False(valueReader.HasData); + + Assert.NotEqual(NegState.Reject, clientState); + Assert.NotEqual(NegState.RequestMic, clientState); + } + + // Client should not send mechanism + Assert.False(negTokenRespReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.SupportedMech))); + + byte[]? mechToken = null; + if (negTokenRespReader.HasData && negTokenRespReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.ResponseToken))) + { + AsnReader mechTokenReader = negTokenRespReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.ResponseToken)); + mechToken = mechTokenReader.ReadOctetString(); + Assert.False(mechTokenReader.HasData); + } + + byte[]? mechListMIC = null; + if (negTokenRespReader.HasData && negTokenRespReader.PeekTag().HasSameClassAndValue(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.MechListMIC))) + { + AsnReader mechListMICReader = negTokenRespReader.ReadSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.MechListMIC)); + mechListMIC = mechListMICReader.ReadOctetString(); + Assert.False(mechListMICReader.HasData); + } + + Assert.NotNull(mechToken); + byte[]? outgoingBlob = _ntlmServer.GetOutgoingBlob(mechToken); + + if (_ntlmServer.IsAuthenticated) + { + if (RequestMIC) + { + Assert.NotNull(mechListMIC); + } + + // Validate mechListMIC, if present + if (mechListMIC is not null) + { + _ntlmServer.VerifyMIC(_spnegoMechList, mechListMIC, 0); + } + } + else + { + Assert.Null(mechListMIC); + } + + // Generate reply + AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); + using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegotiationToken.NegTokenResp))) + { + using (writer.PushSequence()) + { + using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.NegState))) + { + if (_ntlmServer.IsAuthenticated) + { + writer.WriteEnumeratedValue(NegState.AcceptCompleted); + } + else if (outgoingBlob != null) + { + writer.WriteEnumeratedValue(NegState.AcceptIncomplete); + } + else + { + writer.WriteEnumeratedValue(NegState.Reject); + } + } + + if (outgoingBlob != null) + { + using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.ResponseToken))) + { + writer.WriteOctetString(outgoingBlob); + } + } + + if (mechListMIC != null) + { + using (writer.PushSequence(new Asn1Tag(TagClass.ContextSpecific, (int)NegTokenResp.MechListMIC))) + { + Span mic = stackalloc byte[16]; + _ntlmServer.GetMIC(_spnegoMechList, mic, 0); + writer.WriteOctetString(mic); + } + } + } + } + + IsAuthenticated = _ntlmServer.IsAuthenticated; + + return writer.Encode(); + } + } + } +} diff --git a/src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeNtlmServer.cs b/src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeNtlmServer.cs index 780ff0fbe10ca3..e4cfba2e5442c9 100644 --- a/src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeNtlmServer.cs +++ b/src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeNtlmServer.cs @@ -36,11 +36,12 @@ public FakeNtlmServer(NetworkCredential expectedCredential) public byte[] Version { get; set; } = new byte[] { 0x06, 0x00, 0x70, 0x17, 0x00, 0x00, 0x00, 0x0f }; // 6.0.6000 / 15 public bool TargetIsServer { get; set; } = false; public bool PreferUnicode { get; set; } = true; + public bool ForceNegotiateVersion { get; set; } = true; // Negotiation results - public bool IsAuthenticated { get; set; } - public bool IsMICPresent { get; set; } - public string? ClientSpecifiedSpn { get; set; } + public bool IsAuthenticated { get; private set; } + public bool IsMICPresent { get; private set; } + public string? ClientSpecifiedSpn { get; private set; } private NetworkCredential _expectedCredential; @@ -53,6 +54,7 @@ public FakeNtlmServer(NetworkCredential expectedCredential) private byte[]? _serverSigningKey; internal RC4? _clientSeal; internal RC4? _serverSeal; + private Flags _negotiatedFlags; private MessageType _expectedMessageType = MessageType.Negotiate; @@ -212,6 +214,10 @@ private byte[] GenerateChallenge(Flags flags) { flags &= ~Flags.NegotiateOEM; } + if (ForceNegotiateVersion) + { + flags |= Flags.NegotiateVersion; + } // Remove any unsupported flags here flags &= Flags.AllSupported; @@ -379,6 +385,7 @@ private void ValidateAuthentication(byte[] incomingBlob) _serverSigningKey = DeriveKey(exportedSessionKey, ServerSigningKeyMagic); _clientSeal = new RC4(DeriveKey(exportedSessionKey, ClientSealingKeyMagic)); _serverSeal = new RC4(DeriveKey(exportedSessionKey, ServerSealingKeyMagic)); + _negotiatedFlags = flags; CryptographicOperations.ZeroMemory(exportedSessionKey); } @@ -397,7 +404,14 @@ private void CalculateSignature( hmac.AppendData(message); Span hmacResult = stackalloc byte[hmac.HashLengthInBytes]; hmac.GetHashAndReset(hmacResult); - seal.Transform(hmacResult.Slice(0, 8), signature.Slice(4, 8)); + if (_negotiatedFlags.HasFlag(Flags.NegotiateKeyExchange)) + { + seal.Transform(hmacResult.Slice(0, 8), signature.Slice(4, 8)); + } + else + { + hmacResult.Slice(0, 8).CopyTo(signature.Slice(4, 8)); + } } } diff --git a/src/libraries/System.Net.Security/tests/UnitTests/NTAuthenticationTests.cs b/src/libraries/System.Net.Security/tests/UnitTests/NTAuthenticationTests.cs index 6380764deb6d93..43cced820c7cf0 100644 --- a/src/libraries/System.Net.Security/tests/UnitTests/NTAuthenticationTests.cs +++ b/src/libraries/System.Net.Security/tests/UnitTests/NTAuthenticationTests.cs @@ -153,5 +153,50 @@ private void DoNtlmExchange(FakeNtlmServer fakeNtlmServer, NTAuthentication ntAu byte[]? empty = fakeNtlmServer.GetOutgoingBlob(authenticateBlob); Assert.Null(empty); } + + [ConditionalTheory(nameof(IsNtlmInstalled))] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, false)] + public void NegotiateCorrectExchangeTest(bool requestMIC, bool requestConfidentiality) + { + // Older versions of gss-ntlmssp on Linux generate MIC at incorrect offset unless ForceNegotiateVersion is specified + FakeNtlmServer fakeNtlmServer = new FakeNtlmServer(s_testCredentialRight) { ForceNegotiateVersion = true }; + FakeNegotiateServer fakeNegotiateServer = new FakeNegotiateServer(fakeNtlmServer) { RequestMIC = requestMIC }; + NTAuthentication ntAuth = new NTAuthentication( + isServer: false, "Negotiate", s_testCredentialRight, "HTTP/foo", + ContextFlagsPal.Connection | ContextFlagsPal.InitIntegrity | + (requestConfidentiality ? ContextFlagsPal.Confidentiality : 0), null); + + byte[]? clientBlob = null; + byte[]? serverBlob = null; + do + { + clientBlob = ntAuth.GetOutgoingBlob(serverBlob, throwOnError: false, out SecurityStatusPal status); + if (clientBlob != null) + { + Assert.False(fakeNegotiateServer.IsAuthenticated); + // Send the client blob to the fake server + serverBlob = fakeNegotiateServer.GetOutgoingBlob(clientBlob); + } + + if (status.ErrorCode == SecurityStatusPalErrorCode.OK) + { + Assert.True(ntAuth.IsCompleted); + Assert.True(fakeNegotiateServer.IsAuthenticated); + Assert.True(fakeNtlmServer.IsAuthenticated); + } + else if (status.ErrorCode == SecurityStatusPalErrorCode.ContinueNeeded) + { + Assert.NotNull(clientBlob); + Assert.NotNull(serverBlob); + } + else + { + Assert.Fail(status.ErrorCode.ToString()); + } + } + while (!ntAuth.IsCompleted); + } } } diff --git a/src/libraries/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj b/src/libraries/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj index c05249734180c4..55df154298e536 100644 --- a/src/libraries/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj +++ b/src/libraries/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj @@ -31,6 +31,7 @@ + From 7b1fd25ffd29264204e05cd40ce3daabe12a2977 Mon Sep 17 00:00:00 2001 From: Wraith Date: Mon, 13 Jun 2022 14:01:42 +0100 Subject: [PATCH 077/337] Add xarch `blsmsk` (#66561) --- src/coreclr/jit/instrsxarch.h | 4 +- src/coreclr/jit/lower.h | 1 + src/coreclr/jit/lowerxarch.cpp | 124 ++++++++++++++++++--- src/tests/JIT/Intrinsics/BMI1Intrinsics.cs | 40 +++---- 4 files changed, 134 insertions(+), 35 deletions(-) diff --git a/src/coreclr/jit/instrsxarch.h b/src/coreclr/jit/instrsxarch.h index 0a8527a6393fe5..e766df67304d8b 100644 --- a/src/coreclr/jit/instrsxarch.h +++ b/src/coreclr/jit/instrsxarch.h @@ -594,8 +594,8 @@ INST3(LAST_AVXVNNI_INSTRUCTION, "LAST_AVXVNNI_INSTRUCTION", IUM_WR, BAD_CODE, BA // BMI1 INST3(FIRST_BMI_INSTRUCTION, "FIRST_BMI_INSTRUCTION", IUM_WR, BAD_CODE, BAD_CODE, BAD_CODE, INS_FLAGS_None) INST3(andn, "andn", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF2), Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Undefined_PF | Resets_CF | INS_Flags_IsDstDstSrcAVXInstruction) // Logical AND NOT -INST3(blsi, "blsi", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF3), Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_Flags_IsDstDstSrcAVXInstruction) // Extract Lowest Set Isolated Bit -INST3(blsmsk, "blsmsk", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF3), INS_Flags_IsDstDstSrcAVXInstruction) // Get Mask Up to Lowest Set Bit +INST3(blsi, "blsi", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF3), Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_Flags_IsDstDstSrcAVXInstruction) // Extract Lowest Set Isolated Bit +INST3(blsmsk, "blsmsk", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF3), Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Undefined_PF | Resets_CF | INS_Flags_IsDstDstSrcAVXInstruction) // Get Mask Up to Lowest Set Bit INST3(blsr, "blsr", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF3), Resets_OF | Writes_SF | Writes_ZF | Undefined_AF | Undefined_PF | Writes_CF | INS_Flags_IsDstDstSrcAVXInstruction) // Reset Lowest Set Bit INST3(bextr, "bextr", IUM_WR, BAD_CODE, BAD_CODE, SSE38(0xF7), INS_Flags_IsDstDstSrcAVXInstruction) // Bit Field Extract diff --git a/src/coreclr/jit/lower.h b/src/coreclr/jit/lower.h index d54cc70347971c..08eeb581433367 100644 --- a/src/coreclr/jit/lower.h +++ b/src/coreclr/jit/lower.h @@ -351,6 +351,7 @@ class Lowering final : public Phase GenTree* TryLowerAndOpToResetLowestSetBit(GenTreeOp* andNode); GenTree* TryLowerAndOpToExtractLowestSetBit(GenTreeOp* andNode); GenTree* TryLowerAndOpToAndNot(GenTreeOp* andNode); + GenTree* TryLowerXorOpToGetMaskUpToLowestSetBit(GenTreeOp* xorNode); void LowerBswapOp(GenTreeOp* node); #elif defined(TARGET_ARM64) bool IsValidConstForMovImm(GenTreeHWIntrinsic* node); diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp index 46990d9f6dbc64..f0004d7113cc1c 100644 --- a/src/coreclr/jit/lowerxarch.cpp +++ b/src/coreclr/jit/lowerxarch.cpp @@ -174,24 +174,35 @@ GenTree* Lowering::LowerMul(GenTreeOp* mul) GenTree* Lowering::LowerBinaryArithmetic(GenTreeOp* binOp) { #ifdef FEATURE_HW_INTRINSICS - if (comp->opts.OptimizationEnabled() && binOp->OperIs(GT_AND) && varTypeIsIntegral(binOp)) + if (comp->opts.OptimizationEnabled() && varTypeIsIntegral(binOp)) { - GenTree* replacementNode = TryLowerAndOpToAndNot(binOp); - if (replacementNode != nullptr) + if (binOp->OperIs(GT_AND)) { - return replacementNode->gtNext; - } + GenTree* replacementNode = TryLowerAndOpToAndNot(binOp); + if (replacementNode != nullptr) + { + return replacementNode->gtNext; + } - replacementNode = TryLowerAndOpToResetLowestSetBit(binOp); - if (replacementNode != nullptr) - { - return replacementNode->gtNext; - } + replacementNode = TryLowerAndOpToResetLowestSetBit(binOp); + if (replacementNode != nullptr) + { + return replacementNode->gtNext; + } - replacementNode = TryLowerAndOpToExtractLowestSetBit(binOp); - if (replacementNode != nullptr) + replacementNode = TryLowerAndOpToExtractLowestSetBit(binOp); + if (replacementNode != nullptr) + { + return replacementNode->gtNext; + } + } + else if (binOp->OperIs(GT_XOR)) { - return replacementNode->gtNext; + GenTree* replacementNode = TryLowerXorOpToGetMaskUpToLowestSetBit(binOp); + if (replacementNode != nullptr) + { + return replacementNode->gtNext; + } } } #endif @@ -4056,6 +4067,93 @@ GenTree* Lowering::TryLowerAndOpToAndNot(GenTreeOp* andNode) return andnNode; } +//---------------------------------------------------------------------------------------------- +// Lowering::TryLowerXorOpToGetMaskUpToLowestSetBit: Lowers a tree XOR(X, ADD(X, -1)) to +// HWIntrinsic::GetMaskUpToLowestSetBit +// +// Arguments: +// xorNode - GT_XOR node of integral type +// +// Return Value: +// Returns the replacement node if one is created else nullptr indicating no replacement +// +// Notes: +// Performs containment checks on the replacement node if one is created +GenTree* Lowering::TryLowerXorOpToGetMaskUpToLowestSetBit(GenTreeOp* xorNode) +{ + assert(xorNode->OperIs(GT_XOR) && varTypeIsIntegral(xorNode)); + + GenTree* op1 = xorNode->gtGetOp1(); + if (!op1->OperIs(GT_LCL_VAR) || comp->lvaGetDesc(op1->AsLclVar())->IsAddressExposed()) + { + return nullptr; + } + + GenTree* op2 = xorNode->gtGetOp2(); + if (!op2->OperIs(GT_ADD)) + { + return nullptr; + } + + GenTree* addOp2 = op2->gtGetOp2(); + if (!addOp2->IsIntegralConst(-1)) + { + return nullptr; + } + + GenTree* addOp1 = op2->gtGetOp1(); + if (!addOp1->OperIs(GT_LCL_VAR) || (addOp1->AsLclVar()->GetLclNum() != op1->AsLclVar()->GetLclNum())) + { + return nullptr; + } + + // Subsequent nodes may rely on CPU flags set by these nodes in which case we cannot remove them + if (((addOp2->gtFlags & GTF_SET_FLAGS) != 0) || ((op2->gtFlags & GTF_SET_FLAGS) != 0) || + ((xorNode->gtFlags & GTF_SET_FLAGS) != 0)) + { + return nullptr; + } + + NamedIntrinsic intrinsic; + if (xorNode->TypeIs(TYP_LONG) && comp->compOpportunisticallyDependsOn(InstructionSet_BMI1_X64)) + { + intrinsic = NamedIntrinsic::NI_BMI1_X64_GetMaskUpToLowestSetBit; + } + else if (comp->compOpportunisticallyDependsOn(InstructionSet_BMI1)) + { + intrinsic = NamedIntrinsic::NI_BMI1_GetMaskUpToLowestSetBit; + } + else + { + return nullptr; + } + + LIR::Use use; + if (!BlockRange().TryGetUse(xorNode, &use)) + { + return nullptr; + } + + GenTreeHWIntrinsic* blsmskNode = comp->gtNewScalarHWIntrinsicNode(xorNode->TypeGet(), op1, intrinsic); + + JITDUMP("Lower: optimize XOR(X, ADD(X, -1)))\n"); + DISPNODE(xorNode); + JITDUMP("to:\n"); + DISPNODE(blsmskNode); + + use.ReplaceWith(blsmskNode); + + BlockRange().InsertBefore(xorNode, blsmskNode); + BlockRange().Remove(xorNode); + BlockRange().Remove(op2); + BlockRange().Remove(addOp1); + BlockRange().Remove(addOp2); + + ContainCheckHWIntrinsic(blsmskNode); + + return blsmskNode; +} + //---------------------------------------------------------------------------------------------- // Lowering::LowerBswapOp: Tries to contain GT_BSWAP node when possible // diff --git a/src/tests/JIT/Intrinsics/BMI1Intrinsics.cs b/src/tests/JIT/Intrinsics/BMI1Intrinsics.cs index 67bfa1553d436b..6bcdfd4eaa7b5d 100644 --- a/src/tests/JIT/Intrinsics/BMI1Intrinsics.cs +++ b/src/tests/JIT/Intrinsics/BMI1Intrinsics.cs @@ -12,15 +12,15 @@ static int Main(string[] args) // bmi1 expression are folded to to hwintrinsics that return identical results var values = new (uint input1, uint input2, uint andnExpected, uint blsiExpected, uint blsrExpected, uint blmskExpected)[] { - (0, 0, 0, 0 ,0 ,0), - (1, 0, 1, 1 ,0 ,0xfffffffe), - (uint.MaxValue / 2, 0, 0x7fffffff, 0x1 ,0x7ffffffe ,0xfffffffe), - ((uint.MaxValue / 2) - 1, 0, 0x7FFFFFFE, 2 ,0x7FFFFFFC ,0xFFFFFFFC), - ((uint.MaxValue / 2) + 1, 0, 0x80000000, 0x80000000 ,0 ,0), - (uint.MaxValue - 1, 0, 0xFFFFFFFE, 2 ,0xFFFFFFFC ,0xFFFFFFFC), - (uint.MaxValue , 0, 0xFFFFFFFF, 1 ,0xFFFFFFFE ,0xFFFFFFFE), - (0xAAAAAAAA,0xAAAAAAAA,0,2,0xAAAAAAA8,0xFFFFFFFC), - (0xAAAAAAAA,0x55555555,0xAAAAAAAA,2,0xAAAAAAA8,0xFFFFFFFC), + (0, 0, 0, 0 ,0 ,0xFFFFFFFF), + (1, 0, 1, 1 ,0 ,1), + (uint.MaxValue / 2, 0, 0x7fffffff, 0x1 ,0x7ffffffe ,1), + ((uint.MaxValue / 2) - 1, 0, 0x7FFFFFFE, 2 ,0x7FFFFFFC ,3), + ((uint.MaxValue / 2) + 1, 0, 0x80000000, 0x80000000 ,0 ,0xFFFFFFFF), + (uint.MaxValue - 1, 0, 0xFFFFFFFE, 2 ,0xFFFFFFFC ,3), + (uint.MaxValue , 0, 0xFFFFFFFF, 1 ,0xFFFFFFFE ,1), + (0xAAAAAAAA,0xAAAAAAAA,0,2,0xAAAAAAA8,3), + (0xAAAAAAAA,0x55555555,0xAAAAAAAA,2,0xAAAAAAA8,3), }; foreach (var value in values) @@ -33,15 +33,15 @@ static int Main(string[] args) var values2 = new (ulong input1, ulong input2, ulong andnExpected, ulong blsiExpected, ulong blsrExpected, ulong blmskExpected)[] { - (0, 0, 0, 0, 0, 0), - (1, 0, 1, 1, 0,0xFFFFFFFF_FFFFFFFE), - (ulong.MaxValue / 2, 0,0x7FFFFFFF_FFFFFFFF, 1,0x7FFFFFFF_FFFFFFFE,0xFFFFFFFF_FFFFFFFE), - ((ulong.MaxValue / 2) - 1, 0,0x7FFFFFFF_FFFFFFFE, 2,0x7FFFFFFF_FFFFFFFC,0xFFFFFFFF_FFFFFFFC), - ((ulong.MaxValue / 2) + 1, 0,0x80000000_00000000,0x80000000_00000000, 0, 0), - (ulong.MaxValue - 1, 0,0xFFFFFFFF_FFFFFFFE, 2,0xFFFFFFFF_FFFFFFFC,0xFFFFFFFF_FFFFFFFC), - (ulong.MaxValue, 0,0xFFFFFFFF_FFFFFFFF, 1,0xFFFFFFFF_FFFFFFFE,0xFFFFFFFF_FFFFFFFE), - (0xAAAAAAAA_AAAAAAAA,0xAAAAAAAA_AAAAAAAA, 0, 2,0xAAAAAAAA_AAAAAAA8,0xFFFFFFFF_FFFFFFFC), - (0xAAAAAAAA_AAAAAAAA,0x55555555_55555555,0xAAAAAAAA_AAAAAAAA, 2,0xAAAAAAAA_AAAAAAA8,0xFFFFFFFF_FFFFFFFC), + (0, 0, 0, 0, 0,0xFFFFFFFF_FFFFFFFF), + (1, 0, 1, 1, 0, 1), + (ulong.MaxValue / 2, 0,0x7FFFFFFF_FFFFFFFF, 1,0x7FFFFFFF_FFFFFFFE, 1), + ((ulong.MaxValue / 2) - 1, 0,0x7FFFFFFF_FFFFFFFE, 2,0x7FFFFFFF_FFFFFFFC, 3), + ((ulong.MaxValue / 2) + 1, 0,0x80000000_00000000,0x80000000_00000000, 0,0xFFFFFFFF_FFFFFFFF), + (ulong.MaxValue - 1, 0,0xFFFFFFFF_FFFFFFFE, 2,0xFFFFFFFF_FFFFFFFC, 3), + (ulong.MaxValue, 0,0xFFFFFFFF_FFFFFFFF, 1,0xFFFFFFFF_FFFFFFFE, 1), + (0xAAAAAAAA_AAAAAAAA,0xAAAAAAAA_AAAAAAAA, 0, 2,0xAAAAAAAA_AAAAAAA8, 3), + (0xAAAAAAAA_AAAAAAAA,0x55555555_55555555,0xAAAAAAAA_AAAAAAAA, 2,0xAAAAAAAA_AAAAAAA8, 3), }; foreach (var value in values2) @@ -74,10 +74,10 @@ static int Main(string[] args) private static ulong ResetLowestSetBit_64bit(ulong x) => x & (x - 1); // bmi1 blsr [MethodImpl(MethodImplOptions.NoInlining)] - private static uint GetMaskUpToLowestSetBit_32bit(uint x) => (uint)(x ^ (-x)); // bmi1 blmsk + private static uint GetMaskUpToLowestSetBit_32bit(uint x) => x ^ (x - 1); // bmi1 blsmsk [MethodImpl(MethodImplOptions.NoInlining)] - private static ulong GetMaskUpToLowestSetBit_64bit(ulong x) => x ^ (ulong)(-(long)x); // bmi1 blmsk + private static ulong GetMaskUpToLowestSetBit_64bit(ulong x) => x ^ (x - 1); // bmi1 blsmsk [MethodImpl(MethodImplOptions.NoInlining)] private static void Test(uint input, uint output, uint expected, string callerName) From a362a0d93cb9087410a5b2d5285f3268a280e397 Mon Sep 17 00:00:00 2001 From: Aaron Robinson Date: Mon, 13 Jun 2022 07:00:27 -0700 Subject: [PATCH 078/337] Remove unused code and use Win SDK COM headers instead of checked in versions. (#70638) * Remove headers for COM provided by Win SDK * Remove unused sourceline type (h/cpp) Remove dataimage.h and put #define in cpp that was using the value. --- src/coreclr/inc/contxt.h | 3471 ---------------------- src/coreclr/vm/CMakeLists.txt | 2 - src/coreclr/vm/comcache.cpp | 4 +- src/coreclr/vm/comcache.h | 6 +- src/coreclr/vm/ctxtcall.h | 409 --- src/coreclr/vm/dataimage.h | 19 - src/coreclr/vm/olecontexthelpers.cpp | 4 +- src/coreclr/vm/olecontexthelpers.h | 4 +- src/coreclr/vm/peimagelayout.cpp | 10 +- src/coreclr/vm/sourceline.cpp | 328 -- src/coreclr/vm/sourceline.h | 43 - src/coreclr/vm/stackcontents.h | 124 - src/coreclr/vm/stdinterfaces.cpp | 2 +- src/coreclr/vm/stdinterfaces_wrapper.cpp | 2 +- 14 files changed, 17 insertions(+), 4411 deletions(-) delete mode 100644 src/coreclr/inc/contxt.h delete mode 100644 src/coreclr/vm/ctxtcall.h delete mode 100644 src/coreclr/vm/dataimage.h delete mode 100644 src/coreclr/vm/sourceline.cpp delete mode 100644 src/coreclr/vm/sourceline.h delete mode 100644 src/coreclr/vm/stackcontents.h diff --git a/src/coreclr/inc/contxt.h b/src/coreclr/inc/contxt.h deleted file mode 100644 index 1611e7616f5d3c..00000000000000 --- a/src/coreclr/inc/contxt.h +++ /dev/null @@ -1,3471 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/* this ALWAYS GENERATED file contains the definitions for the interfaces */ - - -/* File created by MIDL compiler version 5.01.0164 */ -/* at Mon May 01 14:39:38 2000 - */ -/* Compiler settings for contxt.idl: - Os (OptLev=s), W1, Zp8, env=Win32, ms_ext, c_ext - error checks: allocation ref bounds_check enum stub_data -*/ -//@@MIDL_FILE_HEADING( ) - - -/* verify that the version is high enough to compile this file*/ -#ifndef __REQUIRED_RPCNDR_H_VERSION__ -#define __REQUIRED_RPCNDR_H_VERSION__ 440 -#endif - -#include "rpc.h" -#include "rpcndr.h" - -#ifndef __RPCNDR_H_VERSION__ -#error this stub requires an updated version of -#endif // __RPCNDR_H_VERSION__ - -#ifndef COM_NO_WINDOWS_H -#include "windows.h" -#include "ole2.h" -#endif /*COM_NO_WINDOWS_H*/ - -#ifndef __contxt_h__ -#define __contxt_h__ - -#ifdef __cplusplus -extern "C"{ -#endif - -/* Forward Declarations */ - -#ifndef __IEnumContextProps_FWD_DEFINED__ -#define __IEnumContextProps_FWD_DEFINED__ -typedef interface IEnumContextProps IEnumContextProps; -#endif /* __IEnumContextProps_FWD_DEFINED__ */ - - -#ifndef __IContext_FWD_DEFINED__ -#define __IContext_FWD_DEFINED__ -typedef interface IContext IContext; -#endif /* __IContext_FWD_DEFINED__ */ - - -#ifndef __IContextMarshaler_FWD_DEFINED__ -#define __IContextMarshaler_FWD_DEFINED__ -typedef interface IContextMarshaler IContextMarshaler; -#endif /* __IContextMarshaler_FWD_DEFINED__ */ - - -#ifndef __IObjContext_FWD_DEFINED__ -#define __IObjContext_FWD_DEFINED__ -typedef interface IObjContext IObjContext; -#endif /* __IObjContext_FWD_DEFINED__ */ - - -#ifndef __IGetContextId_FWD_DEFINED__ -#define __IGetContextId_FWD_DEFINED__ -typedef interface IGetContextId IGetContextId; -#endif /* __IGetContextId_FWD_DEFINED__ */ - - -#ifndef __IAggregator_FWD_DEFINED__ -#define __IAggregator_FWD_DEFINED__ -typedef interface IAggregator IAggregator; -#endif /* __IAggregator_FWD_DEFINED__ */ - - -#ifndef __ICall_FWD_DEFINED__ -#define __ICall_FWD_DEFINED__ -typedef interface ICall ICall; -#endif /* __ICall_FWD_DEFINED__ */ - - -#ifndef __IRpcCall_FWD_DEFINED__ -#define __IRpcCall_FWD_DEFINED__ -typedef interface IRpcCall IRpcCall; -#endif /* __IRpcCall_FWD_DEFINED__ */ - - -#ifndef __ICallInfo_FWD_DEFINED__ -#define __ICallInfo_FWD_DEFINED__ -typedef interface ICallInfo ICallInfo; -#endif /* __ICallInfo_FWD_DEFINED__ */ - - -#ifndef __IPolicy_FWD_DEFINED__ -#define __IPolicy_FWD_DEFINED__ -typedef interface IPolicy IPolicy; -#endif /* __IPolicy_FWD_DEFINED__ */ - - -#ifndef __IPolicyAsync_FWD_DEFINED__ -#define __IPolicyAsync_FWD_DEFINED__ -typedef interface IPolicyAsync IPolicyAsync; -#endif /* __IPolicyAsync_FWD_DEFINED__ */ - - -#ifndef __IPolicySet_FWD_DEFINED__ -#define __IPolicySet_FWD_DEFINED__ -typedef interface IPolicySet IPolicySet; -#endif /* __IPolicySet_FWD_DEFINED__ */ - - -#ifndef __IComObjIdentity_FWD_DEFINED__ -#define __IComObjIdentity_FWD_DEFINED__ -typedef interface IComObjIdentity IComObjIdentity; -#endif /* __IComObjIdentity_FWD_DEFINED__ */ - - -#ifndef __IPolicyMaker_FWD_DEFINED__ -#define __IPolicyMaker_FWD_DEFINED__ -typedef interface IPolicyMaker IPolicyMaker; -#endif /* __IPolicyMaker_FWD_DEFINED__ */ - - -#ifndef __IExceptionNotification_FWD_DEFINED__ -#define __IExceptionNotification_FWD_DEFINED__ -typedef interface IExceptionNotification IExceptionNotification; -#endif /* __IExceptionNotification_FWD_DEFINED__ */ - - -#ifndef __IMarshalEnvoy_FWD_DEFINED__ -#define __IMarshalEnvoy_FWD_DEFINED__ -typedef interface IMarshalEnvoy IMarshalEnvoy; -#endif /* __IMarshalEnvoy_FWD_DEFINED__ */ - - -#ifndef __IWrapperInfo_FWD_DEFINED__ -#define __IWrapperInfo_FWD_DEFINED__ -typedef interface IWrapperInfo IWrapperInfo; -#endif /* __IWrapperInfo_FWD_DEFINED__ */ - - -#ifndef __IComThreadingInfo_FWD_DEFINED__ -#define __IComThreadingInfo_FWD_DEFINED__ -typedef interface IComThreadingInfo IComThreadingInfo; -#endif /* __IComThreadingInfo_FWD_DEFINED__ */ - - -#ifndef __IComDispatchInfo_FWD_DEFINED__ -#define __IComDispatchInfo_FWD_DEFINED__ -typedef interface IComDispatchInfo IComDispatchInfo; -#endif /* __IComDispatchInfo_FWD_DEFINED__ */ - - -/* header files for imported files */ -#include "wtypes.h" -#include "objidl.h" - -void __RPC_FAR * __RPC_USER MIDL_user_allocate(size_t); -void __RPC_USER MIDL_user_free( void __RPC_FAR * ); - -/* interface __MIDL_itf_contxt_0000 */ -/* [local] */ - -enum tagCONTEXTEVENT - { CONTEXTEVENT_NONE = 0, - CONTEXTEVENT_CALL = 0x1, - CONTEXTEVENT_ENTER = 0x2, - CONTEXTEVENT_LEAVE = 0x4, - CONTEXTEVENT_RETURN = 0x8, - CONTEXTEVENT_CALLFILLBUFFER = 0x10, - CONTEXTEVENT_ENTERWITHBUFFER = 0x20, - CONTEXTEVENT_LEAVEFILLBUFFER = 0x40, - CONTEXTEVENT_RETURNWITHBUFFER = 0x80, - CONTEXTEVENT_BEGINCALL = 0x100, - CONTEXTEVENT_BEGINENTER = 0x200, - CONTEXTEVENT_BEGINLEAVE = 0x400, - CONTEXTEVENT_BEGINRETURN = 0x800, - CONTEXTEVENT_FINISHCALL = 0x1000, - CONTEXTEVENT_FINISHENTER = 0x2000, - CONTEXTEVENT_FINISHLEAVE = 0x4000, - CONTEXTEVENT_FINISHRETURN = 0x8000, - CONTEXTEVENT_BEGINCALLFILLBUFFER = 0x10000, - CONTEXTEVENT_BEGINENTERWITHBUFFER = 0x20000, - CONTEXTEVENT_FINISHLEAVEFILLBUFFER = 0x40000, - CONTEXTEVENT_FINISHRETURNWITHBUFFER = 0x80000, - CONTEXTEVENT_LEAVEEXCEPTION = 0x100000, - CONTEXTEVENT_LEAVEEXCEPTIONFILLBUFFER = 0x200000, - CONTEXTEVENT_RETURNEXCEPTION = 0x400000, - CONTEXTEVENT_RETURNEXCEPTIONWITHBUFFER = 0x800000, - CONTEXTEVENT_ADDREFPOLICY = 0x10000000, - CONTEXTEVENT_RELEASEPOLICY = 0x20000000 - }; -typedef DWORD ContextEvent; - - -enum tagCPFLAGS - { CPFLAG_NONE = 0, - CPFLAG_PROPAGATE = 0x1, - CPFLAG_EXPOSE = 0x2, - CPFLAG_ENVOY = 0x4, - CPFLAG_MONITORSTUB = 0x8, - CPFLAG_MONITORPROXY = 0x10, - CPFLAG_DONTCOMPARE = 0x20 - }; -typedef DWORD CPFLAGS; - -extern RPC_IF_HANDLE __MIDL_itf_contxt_0000_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_contxt_0000_v0_0_s_ifspec; - -#ifndef __IEnumContextProps_INTERFACE_DEFINED__ -#define __IEnumContextProps_INTERFACE_DEFINED__ - -/* interface IEnumContextProps */ -/* [unique][uuid][object] */ - -typedef /* [unique] */ IEnumContextProps __RPC_FAR *LPENUMCONTEXTPROPS; - - -EXTERN_C const IID IID_IEnumContextProps; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("000001c1-0000-0000-C000-000000000046") - IEnumContextProps : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE Next( - /* [in] */ ULONG celt, - /* [length_is][size_is][out] */ ContextProperty __RPC_FAR *pContextProperties, - /* [out] */ ULONG __RPC_FAR *pceltFetched) = 0; - - virtual HRESULT STDMETHODCALLTYPE Skip( - /* [in] */ ULONG celt) = 0; - - virtual HRESULT STDMETHODCALLTYPE Reset( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE Clone( - /* [out] */ IEnumContextProps __RPC_FAR *__RPC_FAR *ppEnumContextProps) = 0; - - virtual HRESULT STDMETHODCALLTYPE Count( - /* [out] */ ULONG __RPC_FAR *pcelt) = 0; - - }; - -#else /* C style interface */ - - typedef struct IEnumContextPropsVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( - IEnumContextProps __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( - IEnumContextProps __RPC_FAR * This); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( - IEnumContextProps __RPC_FAR * This); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Next )( - IEnumContextProps __RPC_FAR * This, - /* [in] */ ULONG celt, - /* [length_is][size_is][out] */ ContextProperty __RPC_FAR *pContextProperties, - /* [out] */ ULONG __RPC_FAR *pceltFetched); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Skip )( - IEnumContextProps __RPC_FAR * This, - /* [in] */ ULONG celt); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Reset )( - IEnumContextProps __RPC_FAR * This); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Clone )( - IEnumContextProps __RPC_FAR * This, - /* [out] */ IEnumContextProps __RPC_FAR *__RPC_FAR *ppEnumContextProps); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Count )( - IEnumContextProps __RPC_FAR * This, - /* [out] */ ULONG __RPC_FAR *pcelt); - - END_INTERFACE - } IEnumContextPropsVtbl; - - interface IEnumContextProps - { - CONST_VTBL struct IEnumContextPropsVtbl __RPC_FAR *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IEnumContextProps_QueryInterface(This,riid,ppvObject) \ - (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) - -#define IEnumContextProps_AddRef(This) \ - (This)->lpVtbl -> AddRef(This) - -#define IEnumContextProps_Release(This) \ - (This)->lpVtbl -> Release(This) - - -#define IEnumContextProps_Next(This,celt,pContextProperties,pceltFetched) \ - (This)->lpVtbl -> Next(This,celt,pContextProperties,pceltFetched) - -#define IEnumContextProps_Skip(This,celt) \ - (This)->lpVtbl -> Skip(This,celt) - -#define IEnumContextProps_Reset(This) \ - (This)->lpVtbl -> Reset(This) - -#define IEnumContextProps_Clone(This,ppEnumContextProps) \ - (This)->lpVtbl -> Clone(This,ppEnumContextProps) - -#define IEnumContextProps_Count(This,pcelt) \ - (This)->lpVtbl -> Count(This,pcelt) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - -HRESULT STDMETHODCALLTYPE IEnumContextProps_Next_Proxy( - IEnumContextProps __RPC_FAR * This, - /* [in] */ ULONG celt, - /* [length_is][size_is][out] */ ContextProperty __RPC_FAR *pContextProperties, - /* [out] */ ULONG __RPC_FAR *pceltFetched); - - -void __RPC_STUB IEnumContextProps_Next_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IEnumContextProps_Skip_Proxy( - IEnumContextProps __RPC_FAR * This, - /* [in] */ ULONG celt); - - -void __RPC_STUB IEnumContextProps_Skip_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IEnumContextProps_Reset_Proxy( - IEnumContextProps __RPC_FAR * This); - - -void __RPC_STUB IEnumContextProps_Reset_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IEnumContextProps_Clone_Proxy( - IEnumContextProps __RPC_FAR * This, - /* [out] */ IEnumContextProps __RPC_FAR *__RPC_FAR *ppEnumContextProps); - - -void __RPC_STUB IEnumContextProps_Clone_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IEnumContextProps_Count_Proxy( - IEnumContextProps __RPC_FAR * This, - /* [out] */ ULONG __RPC_FAR *pcelt); - - -void __RPC_STUB IEnumContextProps_Count_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - - -#endif /* __IEnumContextProps_INTERFACE_DEFINED__ */ - - -#ifndef __IContext_INTERFACE_DEFINED__ -#define __IContext_INTERFACE_DEFINED__ - -/* interface IContext */ -/* [unique][uuid][object][local] */ - - -EXTERN_C const IID IID_IContext; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("000001c0-0000-0000-C000-000000000046") - IContext : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE SetProperty( - /* [in] */ REFGUID rpolicyId, - /* [in] */ CPFLAGS flags, - /* [in] */ IUnknown __RPC_FAR *pUnk) = 0; - - virtual HRESULT STDMETHODCALLTYPE RemoveProperty( - /* [in] */ REFGUID rPolicyId) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetProperty( - /* [in] */ REFGUID rGuid, - /* [out] */ CPFLAGS __RPC_FAR *pFlags, - /* [out] */ IUnknown __RPC_FAR *__RPC_FAR *ppUnk) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnumContextProps( - /* [out] */ IEnumContextProps __RPC_FAR *__RPC_FAR *ppEnumContextProps) = 0; - - }; - -#else /* C style interface */ - - typedef struct IContextVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( - IContext __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( - IContext __RPC_FAR * This); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( - IContext __RPC_FAR * This); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *SetProperty )( - IContext __RPC_FAR * This, - /* [in] */ REFGUID rpolicyId, - /* [in] */ CPFLAGS flags, - /* [in] */ IUnknown __RPC_FAR *pUnk); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *RemoveProperty )( - IContext __RPC_FAR * This, - /* [in] */ REFGUID rPolicyId); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetProperty )( - IContext __RPC_FAR * This, - /* [in] */ REFGUID rGuid, - /* [out] */ CPFLAGS __RPC_FAR *pFlags, - /* [out] */ IUnknown __RPC_FAR *__RPC_FAR *ppUnk); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *EnumContextProps )( - IContext __RPC_FAR * This, - /* [out] */ IEnumContextProps __RPC_FAR *__RPC_FAR *ppEnumContextProps); - - END_INTERFACE - } IContextVtbl; - - interface IContext - { - CONST_VTBL struct IContextVtbl __RPC_FAR *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IContext_QueryInterface(This,riid,ppvObject) \ - (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) - -#define IContext_AddRef(This) \ - (This)->lpVtbl -> AddRef(This) - -#define IContext_Release(This) \ - (This)->lpVtbl -> Release(This) - - -#define IContext_SetProperty(This,rpolicyId,flags,pUnk) \ - (This)->lpVtbl -> SetProperty(This,rpolicyId,flags,pUnk) - -#define IContext_RemoveProperty(This,rPolicyId) \ - (This)->lpVtbl -> RemoveProperty(This,rPolicyId) - -#define IContext_GetProperty(This,rGuid,pFlags,ppUnk) \ - (This)->lpVtbl -> GetProperty(This,rGuid,pFlags,ppUnk) - -#define IContext_EnumContextProps(This,ppEnumContextProps) \ - (This)->lpVtbl -> EnumContextProps(This,ppEnumContextProps) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - -HRESULT STDMETHODCALLTYPE IContext_SetProperty_Proxy( - IContext __RPC_FAR * This, - /* [in] */ REFGUID rpolicyId, - /* [in] */ CPFLAGS flags, - /* [in] */ IUnknown __RPC_FAR *pUnk); - - -void __RPC_STUB IContext_SetProperty_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IContext_RemoveProperty_Proxy( - IContext __RPC_FAR * This, - /* [in] */ REFGUID rPolicyId); - - -void __RPC_STUB IContext_RemoveProperty_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IContext_GetProperty_Proxy( - IContext __RPC_FAR * This, - /* [in] */ REFGUID rGuid, - /* [out] */ CPFLAGS __RPC_FAR *pFlags, - /* [out] */ IUnknown __RPC_FAR *__RPC_FAR *ppUnk); - - -void __RPC_STUB IContext_GetProperty_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IContext_EnumContextProps_Proxy( - IContext __RPC_FAR * This, - /* [out] */ IEnumContextProps __RPC_FAR *__RPC_FAR *ppEnumContextProps); - - -void __RPC_STUB IContext_EnumContextProps_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - - -#endif /* __IContext_INTERFACE_DEFINED__ */ - - -#ifndef __IContextMarshaler_INTERFACE_DEFINED__ -#define __IContextMarshaler_INTERFACE_DEFINED__ - -/* interface IContextMarshaler */ -/* [uuid][object][local] */ - -typedef /* [unique] */ IContextMarshaler __RPC_FAR *LPCTXMARSHALER; - - -EXTERN_C const IID IID_IContextMarshaler; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("000001D8-0000-0000-C000-000000000046") - IContextMarshaler : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE GetMarshalSizeMax( - /* [in] */ REFIID riid, - /* [unique][in] */ void __RPC_FAR *pv, - /* [in] */ DWORD dwDestContext, - /* [unique][in] */ void __RPC_FAR *pvDestContext, - /* [in] */ DWORD mshlflags, - /* [out] */ DWORD __RPC_FAR *pSize) = 0; - - virtual HRESULT STDMETHODCALLTYPE MarshalInterface( - /* [unique][in] */ IStream __RPC_FAR *pStm, - /* [in] */ REFIID riid, - /* [unique][in] */ void __RPC_FAR *pv, - /* [in] */ DWORD dwDestContext, - /* [unique][in] */ void __RPC_FAR *pvDestContext, - /* [in] */ DWORD mshlflags) = 0; - - }; - -#else /* C style interface */ - - typedef struct IContextMarshalerVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( - IContextMarshaler __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( - IContextMarshaler __RPC_FAR * This); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( - IContextMarshaler __RPC_FAR * This); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetMarshalSizeMax )( - IContextMarshaler __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [unique][in] */ void __RPC_FAR *pv, - /* [in] */ DWORD dwDestContext, - /* [unique][in] */ void __RPC_FAR *pvDestContext, - /* [in] */ DWORD mshlflags, - /* [out] */ DWORD __RPC_FAR *pSize); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *MarshalInterface )( - IContextMarshaler __RPC_FAR * This, - /* [unique][in] */ IStream __RPC_FAR *pStm, - /* [in] */ REFIID riid, - /* [unique][in] */ void __RPC_FAR *pv, - /* [in] */ DWORD dwDestContext, - /* [unique][in] */ void __RPC_FAR *pvDestContext, - /* [in] */ DWORD mshlflags); - - END_INTERFACE - } IContextMarshalerVtbl; - - interface IContextMarshaler - { - CONST_VTBL struct IContextMarshalerVtbl __RPC_FAR *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IContextMarshaler_QueryInterface(This,riid,ppvObject) \ - (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) - -#define IContextMarshaler_AddRef(This) \ - (This)->lpVtbl -> AddRef(This) - -#define IContextMarshaler_Release(This) \ - (This)->lpVtbl -> Release(This) - - -#define IContextMarshaler_GetMarshalSizeMax(This,riid,pv,dwDestContext,pvDestContext,mshlflags,pSize) \ - (This)->lpVtbl -> GetMarshalSizeMax(This,riid,pv,dwDestContext,pvDestContext,mshlflags,pSize) - -#define IContextMarshaler_MarshalInterface(This,pStm,riid,pv,dwDestContext,pvDestContext,mshlflags) \ - (This)->lpVtbl -> MarshalInterface(This,pStm,riid,pv,dwDestContext,pvDestContext,mshlflags) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - -HRESULT STDMETHODCALLTYPE IContextMarshaler_GetMarshalSizeMax_Proxy( - IContextMarshaler __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [unique][in] */ void __RPC_FAR *pv, - /* [in] */ DWORD dwDestContext, - /* [unique][in] */ void __RPC_FAR *pvDestContext, - /* [in] */ DWORD mshlflags, - /* [out] */ DWORD __RPC_FAR *pSize); - - -void __RPC_STUB IContextMarshaler_GetMarshalSizeMax_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IContextMarshaler_MarshalInterface_Proxy( - IContextMarshaler __RPC_FAR * This, - /* [unique][in] */ IStream __RPC_FAR *pStm, - /* [in] */ REFIID riid, - /* [unique][in] */ void __RPC_FAR *pv, - /* [in] */ DWORD dwDestContext, - /* [unique][in] */ void __RPC_FAR *pvDestContext, - /* [in] */ DWORD mshlflags); - - -void __RPC_STUB IContextMarshaler_MarshalInterface_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - - -#endif /* __IContextMarshaler_INTERFACE_DEFINED__ */ - - -// Placing the following definition here rather than with the IObjContext stuff -// below is a temporary workaround to get around build problems where the system -// objidl.h now has a IObjContext section but has not made much public (all the -// interface methods are marked as reserved and the following typedef does not -// exist). Once the system objidl.h is updated again we can remove the entire -// section. -#ifndef __PFNCTXCALLBACK_HACK -#define __PFNCTXCALLBACK_HACK -typedef /* [ref] */ HRESULT ( __stdcall __RPC_FAR *PFNCTXCALLBACK )( - void __RPC_FAR *pParam); -#endif - -#ifndef __IObjContext_INTERFACE_DEFINED__ -#define __IObjContext_INTERFACE_DEFINED__ - -/* interface IObjContext */ -/* [unique][uuid][object][local] */ - - -EXTERN_C const IID IID_IObjContext; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("000001c6-0000-0000-C000-000000000046") - IObjContext : public IContext - { - public: - virtual HRESULT STDMETHODCALLTYPE Freeze( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE DoCallback( - /* [in] */ PFNCTXCALLBACK pfnCallback, - /* [in] */ void __RPC_FAR *pParam, - /* [in] */ REFIID riid, - /* [in] */ unsigned int iMethod) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetContextMarshaler( - /* [in] */ IContextMarshaler __RPC_FAR *pICM) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetContextMarshaler( - /* [out] */ IContextMarshaler __RPC_FAR *__RPC_FAR *pICM) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetContextFlags( - /* [in] */ DWORD dwFlags) = 0; - - virtual HRESULT STDMETHODCALLTYPE ClearContextFlags( - /* [in] */ DWORD dwFlags) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetContextFlags( - /* [out] */ DWORD __RPC_FAR *pdwFlags) = 0; - - }; - -#else /* C style interface */ - - typedef struct IObjContextVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( - IObjContext __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( - IObjContext __RPC_FAR * This); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( - IObjContext __RPC_FAR * This); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *SetProperty )( - IObjContext __RPC_FAR * This, - /* [in] */ REFGUID rpolicyId, - /* [in] */ CPFLAGS flags, - /* [in] */ IUnknown __RPC_FAR *pUnk); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *RemoveProperty )( - IObjContext __RPC_FAR * This, - /* [in] */ REFGUID rPolicyId); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetProperty )( - IObjContext __RPC_FAR * This, - /* [in] */ REFGUID rGuid, - /* [out] */ CPFLAGS __RPC_FAR *pFlags, - /* [out] */ IUnknown __RPC_FAR *__RPC_FAR *ppUnk); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *EnumContextProps )( - IObjContext __RPC_FAR * This, - /* [out] */ IEnumContextProps __RPC_FAR *__RPC_FAR *ppEnumContextProps); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Freeze )( - IObjContext __RPC_FAR * This); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *DoCallback )( - IObjContext __RPC_FAR * This, - /* [in] */ PFNCTXCALLBACK pfnCallback, - /* [in] */ void __RPC_FAR *pParam, - /* [in] */ REFIID riid, - /* [in] */ unsigned int iMethod); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *SetContextMarshaler )( - IObjContext __RPC_FAR * This, - /* [in] */ IContextMarshaler __RPC_FAR *pICM); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetContextMarshaler )( - IObjContext __RPC_FAR * This, - /* [out] */ IContextMarshaler __RPC_FAR *__RPC_FAR *pICM); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *SetContextFlags )( - IObjContext __RPC_FAR * This, - /* [in] */ DWORD dwFlags); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *ClearContextFlags )( - IObjContext __RPC_FAR * This, - /* [in] */ DWORD dwFlags); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetContextFlags )( - IObjContext __RPC_FAR * This, - /* [out] */ DWORD __RPC_FAR *pdwFlags); - - END_INTERFACE - } IObjContextVtbl; - - interface IObjContext - { - CONST_VTBL struct IObjContextVtbl __RPC_FAR *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IObjContext_QueryInterface(This,riid,ppvObject) \ - (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) - -#define IObjContext_AddRef(This) \ - (This)->lpVtbl -> AddRef(This) - -#define IObjContext_Release(This) \ - (This)->lpVtbl -> Release(This) - - -#define IObjContext_SetProperty(This,rpolicyId,flags,pUnk) \ - (This)->lpVtbl -> SetProperty(This,rpolicyId,flags,pUnk) - -#define IObjContext_RemoveProperty(This,rPolicyId) \ - (This)->lpVtbl -> RemoveProperty(This,rPolicyId) - -#define IObjContext_GetProperty(This,rGuid,pFlags,ppUnk) \ - (This)->lpVtbl -> GetProperty(This,rGuid,pFlags,ppUnk) - -#define IObjContext_EnumContextProps(This,ppEnumContextProps) \ - (This)->lpVtbl -> EnumContextProps(This,ppEnumContextProps) - - -#define IObjContext_Freeze(This) \ - (This)->lpVtbl -> Freeze(This) - -#define IObjContext_DoCallback(This,pfnCallback,pParam,riid,iMethod) \ - (This)->lpVtbl -> DoCallback(This,pfnCallback,pParam,riid,iMethod) - -#define IObjContext_SetContextMarshaler(This,pICM) \ - (This)->lpVtbl -> SetContextMarshaler(This,pICM) - -#define IObjContext_GetContextMarshaler(This,pICM) \ - (This)->lpVtbl -> GetContextMarshaler(This,pICM) - -#define IObjContext_SetContextFlags(This,dwFlags) \ - (This)->lpVtbl -> SetContextFlags(This,dwFlags) - -#define IObjContext_ClearContextFlags(This,dwFlags) \ - (This)->lpVtbl -> ClearContextFlags(This,dwFlags) - -#define IObjContext_GetContextFlags(This,pdwFlags) \ - (This)->lpVtbl -> GetContextFlags(This,pdwFlags) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - -HRESULT STDMETHODCALLTYPE IObjContext_Freeze_Proxy( - IObjContext __RPC_FAR * This); - - -void __RPC_STUB IObjContext_Freeze_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IObjContext_DoCallback_Proxy( - IObjContext __RPC_FAR * This, - /* [in] */ PFNCTXCALLBACK pfnCallback, - /* [in] */ void __RPC_FAR *pParam, - /* [in] */ REFIID riid, - /* [in] */ unsigned int iMethod); - - -void __RPC_STUB IObjContext_DoCallback_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IObjContext_SetContextMarshaler_Proxy( - IObjContext __RPC_FAR * This, - /* [in] */ IContextMarshaler __RPC_FAR *pICM); - - -void __RPC_STUB IObjContext_SetContextMarshaler_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IObjContext_GetContextMarshaler_Proxy( - IObjContext __RPC_FAR * This, - /* [out] */ IContextMarshaler __RPC_FAR *__RPC_FAR *pICM); - - -void __RPC_STUB IObjContext_GetContextMarshaler_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IObjContext_SetContextFlags_Proxy( - IObjContext __RPC_FAR * This, - /* [in] */ DWORD dwFlags); - - -void __RPC_STUB IObjContext_SetContextFlags_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IObjContext_ClearContextFlags_Proxy( - IObjContext __RPC_FAR * This, - /* [in] */ DWORD dwFlags); - - -void __RPC_STUB IObjContext_ClearContextFlags_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IObjContext_GetContextFlags_Proxy( - IObjContext __RPC_FAR * This, - /* [out] */ DWORD __RPC_FAR *pdwFlags); - - -void __RPC_STUB IObjContext_GetContextFlags_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - - -#endif /* __IObjContext_INTERFACE_DEFINED__ */ - - -#ifndef __IGetContextId_INTERFACE_DEFINED__ -#define __IGetContextId_INTERFACE_DEFINED__ - -/* interface IGetContextId */ -/* [unique][uuid][object][local] */ - - -EXTERN_C const IID IID_IGetContextId; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("000001dd-0000-0000-C000-000000000046") - IGetContextId : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE GetContextId( - /* [out] */ GUID __RPC_FAR *pguidCtxtId) = 0; - - }; - -#else /* C style interface */ - - typedef struct IGetContextIdVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( - IGetContextId __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( - IGetContextId __RPC_FAR * This); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( - IGetContextId __RPC_FAR * This); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetContextId )( - IGetContextId __RPC_FAR * This, - /* [out] */ GUID __RPC_FAR *pguidCtxtId); - - END_INTERFACE - } IGetContextIdVtbl; - - interface IGetContextId - { - CONST_VTBL struct IGetContextIdVtbl __RPC_FAR *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IGetContextId_QueryInterface(This,riid,ppvObject) \ - (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) - -#define IGetContextId_AddRef(This) \ - (This)->lpVtbl -> AddRef(This) - -#define IGetContextId_Release(This) \ - (This)->lpVtbl -> Release(This) - - -#define IGetContextId_GetContextId(This,pguidCtxtId) \ - (This)->lpVtbl -> GetContextId(This,pguidCtxtId) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - -HRESULT STDMETHODCALLTYPE IGetContextId_GetContextId_Proxy( - IGetContextId __RPC_FAR * This, - /* [out] */ GUID __RPC_FAR *pguidCtxtId); - - -void __RPC_STUB IGetContextId_GetContextId_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - - -#endif /* __IGetContextId_INTERFACE_DEFINED__ */ - - -#ifndef __IAggregator_INTERFACE_DEFINED__ -#define __IAggregator_INTERFACE_DEFINED__ - -/* interface IAggregator */ -/* [unique][uuid][object][local] */ - -typedef /* [unique] */ IAggregator __RPC_FAR *IAGGREGATOR; - - -EXTERN_C const IID IID_IAggregator; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("000001d8-0000-0000-C000-000000000046") - IAggregator : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE Aggregate( - /* [in] */ IUnknown __RPC_FAR *pInnerUnk) = 0; - - }; - -#else /* C style interface */ - - typedef struct IAggregatorVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( - IAggregator __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( - IAggregator __RPC_FAR * This); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( - IAggregator __RPC_FAR * This); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Aggregate )( - IAggregator __RPC_FAR * This, - /* [in] */ IUnknown __RPC_FAR *pInnerUnk); - - END_INTERFACE - } IAggregatorVtbl; - - interface IAggregator - { - CONST_VTBL struct IAggregatorVtbl __RPC_FAR *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IAggregator_QueryInterface(This,riid,ppvObject) \ - (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) - -#define IAggregator_AddRef(This) \ - (This)->lpVtbl -> AddRef(This) - -#define IAggregator_Release(This) \ - (This)->lpVtbl -> Release(This) - - -#define IAggregator_Aggregate(This,pInnerUnk) \ - (This)->lpVtbl -> Aggregate(This,pInnerUnk) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - -HRESULT STDMETHODCALLTYPE IAggregator_Aggregate_Proxy( - IAggregator __RPC_FAR * This, - /* [in] */ IUnknown __RPC_FAR *pInnerUnk); - - -void __RPC_STUB IAggregator_Aggregate_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - - -#endif /* __IAggregator_INTERFACE_DEFINED__ */ - - -#ifndef __ICall_INTERFACE_DEFINED__ -#define __ICall_INTERFACE_DEFINED__ - -/* interface ICall */ -/* [unique][uuid][object][local] */ - -typedef /* [unique] */ ICall __RPC_FAR *LPCALL; - - -EXTERN_C const IID IID_ICall; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("000001d6-0000-0000-C000-000000000046") - ICall : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE GetCallInfo( - /* [out] */ const void __RPC_FAR *__RPC_FAR *ppIdentity, - /* [out] */ IID __RPC_FAR *piid, - /* [out] */ DWORD __RPC_FAR *pdwMethod, - /* [out] */ HRESULT __RPC_FAR *phr) = 0; - - virtual HRESULT STDMETHODCALLTYPE Nullify( - /* [in] */ HRESULT hr) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetServerHR( - /* [out] */ HRESULT __RPC_FAR *phr) = 0; - - }; - -#else /* C style interface */ - - typedef struct ICallVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( - ICall __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( - ICall __RPC_FAR * This); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( - ICall __RPC_FAR * This); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetCallInfo )( - ICall __RPC_FAR * This, - /* [out] */ const void __RPC_FAR *__RPC_FAR *ppIdentity, - /* [out] */ IID __RPC_FAR *piid, - /* [out] */ DWORD __RPC_FAR *pdwMethod, - /* [out] */ HRESULT __RPC_FAR *phr); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Nullify )( - ICall __RPC_FAR * This, - /* [in] */ HRESULT hr); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetServerHR )( - ICall __RPC_FAR * This, - /* [out] */ HRESULT __RPC_FAR *phr); - - END_INTERFACE - } ICallVtbl; - - interface ICall - { - CONST_VTBL struct ICallVtbl __RPC_FAR *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define ICall_QueryInterface(This,riid,ppvObject) \ - (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) - -#define ICall_AddRef(This) \ - (This)->lpVtbl -> AddRef(This) - -#define ICall_Release(This) \ - (This)->lpVtbl -> Release(This) - - -#define ICall_GetCallInfo(This,ppIdentity,piid,pdwMethod,phr) \ - (This)->lpVtbl -> GetCallInfo(This,ppIdentity,piid,pdwMethod,phr) - -#define ICall_Nullify(This,hr) \ - (This)->lpVtbl -> Nullify(This,hr) - -#define ICall_GetServerHR(This,phr) \ - (This)->lpVtbl -> GetServerHR(This,phr) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - -HRESULT STDMETHODCALLTYPE ICall_GetCallInfo_Proxy( - ICall __RPC_FAR * This, - /* [out] */ const void __RPC_FAR *__RPC_FAR *ppIdentity, - /* [out] */ IID __RPC_FAR *piid, - /* [out] */ DWORD __RPC_FAR *pdwMethod, - /* [out] */ HRESULT __RPC_FAR *phr); - - -void __RPC_STUB ICall_GetCallInfo_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE ICall_Nullify_Proxy( - ICall __RPC_FAR * This, - /* [in] */ HRESULT hr); - - -void __RPC_STUB ICall_Nullify_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE ICall_GetServerHR_Proxy( - ICall __RPC_FAR * This, - /* [out] */ HRESULT __RPC_FAR *phr); - - -void __RPC_STUB ICall_GetServerHR_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - - -#endif /* __ICall_INTERFACE_DEFINED__ */ - - -#ifndef __IRpcCall_INTERFACE_DEFINED__ -#define __IRpcCall_INTERFACE_DEFINED__ - -/* interface IRpcCall */ -/* [unique][uuid][object][local] */ - -typedef /* [unique] */ IRpcCall __RPC_FAR *LPRPCCALL; - - -EXTERN_C const IID IID_IRpcCall; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("000001c5-0000-0000-C000-000000000046") - IRpcCall : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE GetRpcOleMessage( - /* [out] */ RPCOLEMESSAGE __RPC_FAR *__RPC_FAR *ppMessage) = 0; - - }; - -#else /* C style interface */ - - typedef struct IRpcCallVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( - IRpcCall __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( - IRpcCall __RPC_FAR * This); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( - IRpcCall __RPC_FAR * This); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetRpcOleMessage )( - IRpcCall __RPC_FAR * This, - /* [out] */ RPCOLEMESSAGE __RPC_FAR *__RPC_FAR *ppMessage); - - END_INTERFACE - } IRpcCallVtbl; - - interface IRpcCall - { - CONST_VTBL struct IRpcCallVtbl __RPC_FAR *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IRpcCall_QueryInterface(This,riid,ppvObject) \ - (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) - -#define IRpcCall_AddRef(This) \ - (This)->lpVtbl -> AddRef(This) - -#define IRpcCall_Release(This) \ - (This)->lpVtbl -> Release(This) - - -#define IRpcCall_GetRpcOleMessage(This,ppMessage) \ - (This)->lpVtbl -> GetRpcOleMessage(This,ppMessage) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - -HRESULT STDMETHODCALLTYPE IRpcCall_GetRpcOleMessage_Proxy( - IRpcCall __RPC_FAR * This, - /* [out] */ RPCOLEMESSAGE __RPC_FAR *__RPC_FAR *ppMessage); - - -void __RPC_STUB IRpcCall_GetRpcOleMessage_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - - -#endif /* __IRpcCall_INTERFACE_DEFINED__ */ - - -/* interface __MIDL_itf_contxt_0083 */ -/* [local] */ - -typedef -enum _CALLSOURCE - { CALLSOURCE_CROSSAPT = 0, - CALLSOURCE_CROSSCTX = 1 - } CALLSOURCE; - - - -extern RPC_IF_HANDLE __MIDL_itf_contxt_0083_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_contxt_0083_v0_0_s_ifspec; - -#ifndef __ICallInfo_INTERFACE_DEFINED__ -#define __ICallInfo_INTERFACE_DEFINED__ - -/* interface ICallInfo */ -/* [unique][uuid][object][local] */ - - -EXTERN_C const IID IID_ICallInfo; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("000001dc-0000-0000-C000-000000000046") - ICallInfo : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE GetCallSource( - /* [out] */ CALLSOURCE __RPC_FAR *pCallSource) = 0; - - }; - -#else /* C style interface */ - - typedef struct ICallInfoVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( - ICallInfo __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( - ICallInfo __RPC_FAR * This); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( - ICallInfo __RPC_FAR * This); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetCallSource )( - ICallInfo __RPC_FAR * This, - /* [out] */ CALLSOURCE __RPC_FAR *pCallSource); - - END_INTERFACE - } ICallInfoVtbl; - - interface ICallInfo - { - CONST_VTBL struct ICallInfoVtbl __RPC_FAR *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define ICallInfo_QueryInterface(This,riid,ppvObject) \ - (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) - -#define ICallInfo_AddRef(This) \ - (This)->lpVtbl -> AddRef(This) - -#define ICallInfo_Release(This) \ - (This)->lpVtbl -> Release(This) - - -#define ICallInfo_GetCallSource(This,pCallSource) \ - (This)->lpVtbl -> GetCallSource(This,pCallSource) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - -HRESULT STDMETHODCALLTYPE ICallInfo_GetCallSource_Proxy( - ICallInfo __RPC_FAR * This, - /* [out] */ CALLSOURCE __RPC_FAR *pCallSource); - - -void __RPC_STUB ICallInfo_GetCallSource_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - - -#endif /* __ICallInfo_INTERFACE_DEFINED__ */ - - -#ifndef __IPolicy_INTERFACE_DEFINED__ -#define __IPolicy_INTERFACE_DEFINED__ - -/* interface IPolicy */ -/* [unique][uuid][object][local] */ - - -EXTERN_C const IID IID_IPolicy; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("000001c2-0000-0000-C000-000000000046") - IPolicy : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE Call( - /* [in] */ ICall __RPC_FAR *pCall) = 0; - - virtual HRESULT STDMETHODCALLTYPE Enter( - /* [in] */ ICall __RPC_FAR *pCall) = 0; - - virtual HRESULT STDMETHODCALLTYPE Leave( - /* [in] */ ICall __RPC_FAR *pCall) = 0; - - virtual HRESULT STDMETHODCALLTYPE Return( - /* [in] */ ICall __RPC_FAR *pCall) = 0; - - virtual HRESULT STDMETHODCALLTYPE CallGetSize( - /* [in] */ ICall __RPC_FAR *pCall, - /* [out] */ ULONG __RPC_FAR *pcb) = 0; - - virtual HRESULT STDMETHODCALLTYPE CallFillBuffer( - /* [in] */ ICall __RPC_FAR *pCall, - /* [in] */ void __RPC_FAR *pvBuf, - /* [out] */ ULONG __RPC_FAR *pcb) = 0; - - virtual HRESULT STDMETHODCALLTYPE EnterWithBuffer( - /* [in] */ ICall __RPC_FAR *pCall, - /* [in] */ void __RPC_FAR *pvBuf, - /* [in] */ ULONG cb) = 0; - - virtual HRESULT STDMETHODCALLTYPE LeaveGetSize( - /* [in] */ ICall __RPC_FAR *pCall, - /* [out] */ ULONG __RPC_FAR *pcb) = 0; - - virtual HRESULT STDMETHODCALLTYPE LeaveFillBuffer( - /* [in] */ ICall __RPC_FAR *pCall, - /* [in] */ void __RPC_FAR *pvBuf, - /* [out] */ ULONG __RPC_FAR *pcb) = 0; - - virtual HRESULT STDMETHODCALLTYPE ReturnWithBuffer( - /* [in] */ ICall __RPC_FAR *pCall, - /* [in] */ void __RPC_FAR *pvBuf, - /* [in] */ ULONG cb) = 0; - - virtual ULONG STDMETHODCALLTYPE AddRefPolicy( void) = 0; - - virtual ULONG STDMETHODCALLTYPE ReleasePolicy( void) = 0; - - }; - -#else /* C style interface */ - - typedef struct IPolicyVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( - IPolicy __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( - IPolicy __RPC_FAR * This); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( - IPolicy __RPC_FAR * This); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Call )( - IPolicy __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Enter )( - IPolicy __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Leave )( - IPolicy __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Return )( - IPolicy __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *CallGetSize )( - IPolicy __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall, - /* [out] */ ULONG __RPC_FAR *pcb); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *CallFillBuffer )( - IPolicy __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall, - /* [in] */ void __RPC_FAR *pvBuf, - /* [out] */ ULONG __RPC_FAR *pcb); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *EnterWithBuffer )( - IPolicy __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall, - /* [in] */ void __RPC_FAR *pvBuf, - /* [in] */ ULONG cb); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *LeaveGetSize )( - IPolicy __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall, - /* [out] */ ULONG __RPC_FAR *pcb); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *LeaveFillBuffer )( - IPolicy __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall, - /* [in] */ void __RPC_FAR *pvBuf, - /* [out] */ ULONG __RPC_FAR *pcb); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *ReturnWithBuffer )( - IPolicy __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall, - /* [in] */ void __RPC_FAR *pvBuf, - /* [in] */ ULONG cb); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRefPolicy )( - IPolicy __RPC_FAR * This); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *ReleasePolicy )( - IPolicy __RPC_FAR * This); - - END_INTERFACE - } IPolicyVtbl; - - interface IPolicy - { - CONST_VTBL struct IPolicyVtbl __RPC_FAR *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IPolicy_QueryInterface(This,riid,ppvObject) \ - (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) - -#define IPolicy_AddRef(This) \ - (This)->lpVtbl -> AddRef(This) - -#define IPolicy_Release(This) \ - (This)->lpVtbl -> Release(This) - - -#define IPolicy_Call(This,pCall) \ - (This)->lpVtbl -> Call(This,pCall) - -#define IPolicy_Enter(This,pCall) \ - (This)->lpVtbl -> Enter(This,pCall) - -#define IPolicy_Leave(This,pCall) \ - (This)->lpVtbl -> Leave(This,pCall) - -#define IPolicy_Return(This,pCall) \ - (This)->lpVtbl -> Return(This,pCall) - -#define IPolicy_CallGetSize(This,pCall,pcb) \ - (This)->lpVtbl -> CallGetSize(This,pCall,pcb) - -#define IPolicy_CallFillBuffer(This,pCall,pvBuf,pcb) \ - (This)->lpVtbl -> CallFillBuffer(This,pCall,pvBuf,pcb) - -#define IPolicy_EnterWithBuffer(This,pCall,pvBuf,cb) \ - (This)->lpVtbl -> EnterWithBuffer(This,pCall,pvBuf,cb) - -#define IPolicy_LeaveGetSize(This,pCall,pcb) \ - (This)->lpVtbl -> LeaveGetSize(This,pCall,pcb) - -#define IPolicy_LeaveFillBuffer(This,pCall,pvBuf,pcb) \ - (This)->lpVtbl -> LeaveFillBuffer(This,pCall,pvBuf,pcb) - -#define IPolicy_ReturnWithBuffer(This,pCall,pvBuf,cb) \ - (This)->lpVtbl -> ReturnWithBuffer(This,pCall,pvBuf,cb) - -#define IPolicy_AddRefPolicy(This) \ - (This)->lpVtbl -> AddRefPolicy(This) - -#define IPolicy_ReleasePolicy(This) \ - (This)->lpVtbl -> ReleasePolicy(This) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - -HRESULT STDMETHODCALLTYPE IPolicy_Call_Proxy( - IPolicy __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall); - - -void __RPC_STUB IPolicy_Call_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicy_Enter_Proxy( - IPolicy __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall); - - -void __RPC_STUB IPolicy_Enter_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicy_Leave_Proxy( - IPolicy __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall); - - -void __RPC_STUB IPolicy_Leave_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicy_Return_Proxy( - IPolicy __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall); - - -void __RPC_STUB IPolicy_Return_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicy_CallGetSize_Proxy( - IPolicy __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall, - /* [out] */ ULONG __RPC_FAR *pcb); - - -void __RPC_STUB IPolicy_CallGetSize_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicy_CallFillBuffer_Proxy( - IPolicy __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall, - /* [in] */ void __RPC_FAR *pvBuf, - /* [out] */ ULONG __RPC_FAR *pcb); - - -void __RPC_STUB IPolicy_CallFillBuffer_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicy_EnterWithBuffer_Proxy( - IPolicy __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall, - /* [in] */ void __RPC_FAR *pvBuf, - /* [in] */ ULONG cb); - - -void __RPC_STUB IPolicy_EnterWithBuffer_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicy_LeaveGetSize_Proxy( - IPolicy __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall, - /* [out] */ ULONG __RPC_FAR *pcb); - - -void __RPC_STUB IPolicy_LeaveGetSize_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicy_LeaveFillBuffer_Proxy( - IPolicy __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall, - /* [in] */ void __RPC_FAR *pvBuf, - /* [out] */ ULONG __RPC_FAR *pcb); - - -void __RPC_STUB IPolicy_LeaveFillBuffer_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicy_ReturnWithBuffer_Proxy( - IPolicy __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall, - /* [in] */ void __RPC_FAR *pvBuf, - /* [in] */ ULONG cb); - - -void __RPC_STUB IPolicy_ReturnWithBuffer_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -ULONG STDMETHODCALLTYPE IPolicy_AddRefPolicy_Proxy( - IPolicy __RPC_FAR * This); - - -void __RPC_STUB IPolicy_AddRefPolicy_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -ULONG STDMETHODCALLTYPE IPolicy_ReleasePolicy_Proxy( - IPolicy __RPC_FAR * This); - - -void __RPC_STUB IPolicy_ReleasePolicy_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - - -#endif /* __IPolicy_INTERFACE_DEFINED__ */ - - -#ifndef __IPolicyAsync_INTERFACE_DEFINED__ -#define __IPolicyAsync_INTERFACE_DEFINED__ - -/* interface IPolicyAsync */ -/* [unique][uuid][object][local] */ - - -EXTERN_C const IID IID_IPolicyAsync; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("000001cd-0000-0000-C000-000000000046") - IPolicyAsync : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE BeginCallGetSize( - /* [in] */ ICall __RPC_FAR *pCall, - /* [out] */ ULONG __RPC_FAR *pcb) = 0; - - virtual HRESULT STDMETHODCALLTYPE BeginCall( - /* [in] */ ICall __RPC_FAR *pCall) = 0; - - virtual HRESULT STDMETHODCALLTYPE BeginCallFillBuffer( - /* [in] */ ICall __RPC_FAR *pCall, - /* [in] */ void __RPC_FAR *pvBuf, - /* [out] */ ULONG __RPC_FAR *pcb) = 0; - - virtual HRESULT STDMETHODCALLTYPE BeginEnter( - /* [in] */ ICall __RPC_FAR *pCall) = 0; - - virtual HRESULT STDMETHODCALLTYPE BeginEnterWithBuffer( - /* [in] */ ICall __RPC_FAR *pCall, - /* [in] */ void __RPC_FAR *pvBuf, - /* [in] */ ULONG cb) = 0; - - virtual HRESULT STDMETHODCALLTYPE BeginLeave( - /* [in] */ ICall __RPC_FAR *pCall) = 0; - - virtual HRESULT STDMETHODCALLTYPE BeginReturn( - /* [in] */ ICall __RPC_FAR *pCall) = 0; - - virtual HRESULT STDMETHODCALLTYPE FinishCall( - /* [in] */ ICall __RPC_FAR *pCall) = 0; - - virtual HRESULT STDMETHODCALLTYPE FinishEnter( - /* [in] */ ICall __RPC_FAR *pCall) = 0; - - virtual HRESULT STDMETHODCALLTYPE FinishLeaveGetSize( - /* [in] */ ICall __RPC_FAR *pCall, - /* [out] */ ULONG __RPC_FAR *pcb) = 0; - - virtual HRESULT STDMETHODCALLTYPE FinishLeave( - /* [in] */ ICall __RPC_FAR *pCall) = 0; - - virtual HRESULT STDMETHODCALLTYPE FinishLeaveFillBuffer( - /* [in] */ ICall __RPC_FAR *pCall, - /* [in] */ void __RPC_FAR *pvBuf, - /* [out] */ ULONG __RPC_FAR *pcb) = 0; - - virtual HRESULT STDMETHODCALLTYPE FinishReturn( - /* [in] */ ICall __RPC_FAR *pCall) = 0; - - virtual HRESULT STDMETHODCALLTYPE FinishReturnWithBuffer( - /* [in] */ ICall __RPC_FAR *pCall, - /* [in] */ void __RPC_FAR *pvBuf, - /* [in] */ ULONG cb) = 0; - - }; - -#else /* C style interface */ - - typedef struct IPolicyAsyncVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( - IPolicyAsync __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( - IPolicyAsync __RPC_FAR * This); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( - IPolicyAsync __RPC_FAR * This); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *BeginCallGetSize )( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall, - /* [out] */ ULONG __RPC_FAR *pcb); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *BeginCall )( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *BeginCallFillBuffer )( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall, - /* [in] */ void __RPC_FAR *pvBuf, - /* [out] */ ULONG __RPC_FAR *pcb); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *BeginEnter )( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *BeginEnterWithBuffer )( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall, - /* [in] */ void __RPC_FAR *pvBuf, - /* [in] */ ULONG cb); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *BeginLeave )( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *BeginReturn )( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *FinishCall )( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *FinishEnter )( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *FinishLeaveGetSize )( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall, - /* [out] */ ULONG __RPC_FAR *pcb); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *FinishLeave )( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *FinishLeaveFillBuffer )( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall, - /* [in] */ void __RPC_FAR *pvBuf, - /* [out] */ ULONG __RPC_FAR *pcb); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *FinishReturn )( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *FinishReturnWithBuffer )( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall, - /* [in] */ void __RPC_FAR *pvBuf, - /* [in] */ ULONG cb); - - END_INTERFACE - } IPolicyAsyncVtbl; - - interface IPolicyAsync - { - CONST_VTBL struct IPolicyAsyncVtbl __RPC_FAR *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IPolicyAsync_QueryInterface(This,riid,ppvObject) \ - (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) - -#define IPolicyAsync_AddRef(This) \ - (This)->lpVtbl -> AddRef(This) - -#define IPolicyAsync_Release(This) \ - (This)->lpVtbl -> Release(This) - - -#define IPolicyAsync_BeginCallGetSize(This,pCall,pcb) \ - (This)->lpVtbl -> BeginCallGetSize(This,pCall,pcb) - -#define IPolicyAsync_BeginCall(This,pCall) \ - (This)->lpVtbl -> BeginCall(This,pCall) - -#define IPolicyAsync_BeginCallFillBuffer(This,pCall,pvBuf,pcb) \ - (This)->lpVtbl -> BeginCallFillBuffer(This,pCall,pvBuf,pcb) - -#define IPolicyAsync_BeginEnter(This,pCall) \ - (This)->lpVtbl -> BeginEnter(This,pCall) - -#define IPolicyAsync_BeginEnterWithBuffer(This,pCall,pvBuf,cb) \ - (This)->lpVtbl -> BeginEnterWithBuffer(This,pCall,pvBuf,cb) - -#define IPolicyAsync_BeginLeave(This,pCall) \ - (This)->lpVtbl -> BeginLeave(This,pCall) - -#define IPolicyAsync_BeginReturn(This,pCall) \ - (This)->lpVtbl -> BeginReturn(This,pCall) - -#define IPolicyAsync_FinishCall(This,pCall) \ - (This)->lpVtbl -> FinishCall(This,pCall) - -#define IPolicyAsync_FinishEnter(This,pCall) \ - (This)->lpVtbl -> FinishEnter(This,pCall) - -#define IPolicyAsync_FinishLeaveGetSize(This,pCall,pcb) \ - (This)->lpVtbl -> FinishLeaveGetSize(This,pCall,pcb) - -#define IPolicyAsync_FinishLeave(This,pCall) \ - (This)->lpVtbl -> FinishLeave(This,pCall) - -#define IPolicyAsync_FinishLeaveFillBuffer(This,pCall,pvBuf,pcb) \ - (This)->lpVtbl -> FinishLeaveFillBuffer(This,pCall,pvBuf,pcb) - -#define IPolicyAsync_FinishReturn(This,pCall) \ - (This)->lpVtbl -> FinishReturn(This,pCall) - -#define IPolicyAsync_FinishReturnWithBuffer(This,pCall,pvBuf,cb) \ - (This)->lpVtbl -> FinishReturnWithBuffer(This,pCall,pvBuf,cb) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - -HRESULT STDMETHODCALLTYPE IPolicyAsync_BeginCallGetSize_Proxy( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall, - /* [out] */ ULONG __RPC_FAR *pcb); - - -void __RPC_STUB IPolicyAsync_BeginCallGetSize_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicyAsync_BeginCall_Proxy( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall); - - -void __RPC_STUB IPolicyAsync_BeginCall_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicyAsync_BeginCallFillBuffer_Proxy( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall, - /* [in] */ void __RPC_FAR *pvBuf, - /* [out] */ ULONG __RPC_FAR *pcb); - - -void __RPC_STUB IPolicyAsync_BeginCallFillBuffer_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicyAsync_BeginEnter_Proxy( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall); - - -void __RPC_STUB IPolicyAsync_BeginEnter_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicyAsync_BeginEnterWithBuffer_Proxy( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall, - /* [in] */ void __RPC_FAR *pvBuf, - /* [in] */ ULONG cb); - - -void __RPC_STUB IPolicyAsync_BeginEnterWithBuffer_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicyAsync_BeginLeave_Proxy( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall); - - -void __RPC_STUB IPolicyAsync_BeginLeave_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicyAsync_BeginReturn_Proxy( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall); - - -void __RPC_STUB IPolicyAsync_BeginReturn_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicyAsync_FinishCall_Proxy( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall); - - -void __RPC_STUB IPolicyAsync_FinishCall_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicyAsync_FinishEnter_Proxy( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall); - - -void __RPC_STUB IPolicyAsync_FinishEnter_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicyAsync_FinishLeaveGetSize_Proxy( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall, - /* [out] */ ULONG __RPC_FAR *pcb); - - -void __RPC_STUB IPolicyAsync_FinishLeaveGetSize_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicyAsync_FinishLeave_Proxy( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall); - - -void __RPC_STUB IPolicyAsync_FinishLeave_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicyAsync_FinishLeaveFillBuffer_Proxy( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall, - /* [in] */ void __RPC_FAR *pvBuf, - /* [out] */ ULONG __RPC_FAR *pcb); - - -void __RPC_STUB IPolicyAsync_FinishLeaveFillBuffer_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicyAsync_FinishReturn_Proxy( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall); - - -void __RPC_STUB IPolicyAsync_FinishReturn_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicyAsync_FinishReturnWithBuffer_Proxy( - IPolicyAsync __RPC_FAR * This, - /* [in] */ ICall __RPC_FAR *pCall, - /* [in] */ void __RPC_FAR *pvBuf, - /* [in] */ ULONG cb); - - -void __RPC_STUB IPolicyAsync_FinishReturnWithBuffer_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - - -#endif /* __IPolicyAsync_INTERFACE_DEFINED__ */ - - -#ifndef __IPolicySet_INTERFACE_DEFINED__ -#define __IPolicySet_INTERFACE_DEFINED__ - -/* interface IPolicySet */ -/* [unique][uuid][object][local] */ - - -EXTERN_C const IID IID_IPolicySet; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("000001c3-0000-0000-C000-000000000046") - IPolicySet : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE AddPolicy( - /* [in] */ ContextEvent ctxEvent, - /* [in] */ REFGUID rguid, - /* [in] */ IPolicy __RPC_FAR *pPolicy) = 0; - - }; - -#else /* C style interface */ - - typedef struct IPolicySetVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( - IPolicySet __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( - IPolicySet __RPC_FAR * This); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( - IPolicySet __RPC_FAR * This); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *AddPolicy )( - IPolicySet __RPC_FAR * This, - /* [in] */ ContextEvent ctxEvent, - /* [in] */ REFGUID rguid, - /* [in] */ IPolicy __RPC_FAR *pPolicy); - - END_INTERFACE - } IPolicySetVtbl; - - interface IPolicySet - { - CONST_VTBL struct IPolicySetVtbl __RPC_FAR *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IPolicySet_QueryInterface(This,riid,ppvObject) \ - (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) - -#define IPolicySet_AddRef(This) \ - (This)->lpVtbl -> AddRef(This) - -#define IPolicySet_Release(This) \ - (This)->lpVtbl -> Release(This) - - -#define IPolicySet_AddPolicy(This,ctxEvent,rguid,pPolicy) \ - (This)->lpVtbl -> AddPolicy(This,ctxEvent,rguid,pPolicy) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - -HRESULT STDMETHODCALLTYPE IPolicySet_AddPolicy_Proxy( - IPolicySet __RPC_FAR * This, - /* [in] */ ContextEvent ctxEvent, - /* [in] */ REFGUID rguid, - /* [in] */ IPolicy __RPC_FAR *pPolicy); - - -void __RPC_STUB IPolicySet_AddPolicy_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - - -#endif /* __IPolicySet_INTERFACE_DEFINED__ */ - - -#ifndef __IComObjIdentity_INTERFACE_DEFINED__ -#define __IComObjIdentity_INTERFACE_DEFINED__ - -/* interface IComObjIdentity */ -/* [unique][uuid][object][local] */ - - -EXTERN_C const IID IID_IComObjIdentity; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("000001d7-0000-0000-C000-000000000046") - IComObjIdentity : public IUnknown - { - public: - virtual BOOL STDMETHODCALLTYPE IsServer( void) = 0; - - virtual BOOL STDMETHODCALLTYPE IsDeactivated( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetIdentity( - /* [out] */ IUnknown __RPC_FAR *__RPC_FAR *ppUnk) = 0; - - }; - -#else /* C style interface */ - - typedef struct IComObjIdentityVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( - IComObjIdentity __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( - IComObjIdentity __RPC_FAR * This); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( - IComObjIdentity __RPC_FAR * This); - - BOOL ( STDMETHODCALLTYPE __RPC_FAR *IsServer )( - IComObjIdentity __RPC_FAR * This); - - BOOL ( STDMETHODCALLTYPE __RPC_FAR *IsDeactivated )( - IComObjIdentity __RPC_FAR * This); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetIdentity )( - IComObjIdentity __RPC_FAR * This, - /* [out] */ IUnknown __RPC_FAR *__RPC_FAR *ppUnk); - - END_INTERFACE - } IComObjIdentityVtbl; - - interface IComObjIdentity - { - CONST_VTBL struct IComObjIdentityVtbl __RPC_FAR *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IComObjIdentity_QueryInterface(This,riid,ppvObject) \ - (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) - -#define IComObjIdentity_AddRef(This) \ - (This)->lpVtbl -> AddRef(This) - -#define IComObjIdentity_Release(This) \ - (This)->lpVtbl -> Release(This) - - -#define IComObjIdentity_IsServer(This) \ - (This)->lpVtbl -> IsServer(This) - -#define IComObjIdentity_IsDeactivated(This) \ - (This)->lpVtbl -> IsDeactivated(This) - -#define IComObjIdentity_GetIdentity(This,ppUnk) \ - (This)->lpVtbl -> GetIdentity(This,ppUnk) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - -BOOL STDMETHODCALLTYPE IComObjIdentity_IsServer_Proxy( - IComObjIdentity __RPC_FAR * This); - - -void __RPC_STUB IComObjIdentity_IsServer_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -BOOL STDMETHODCALLTYPE IComObjIdentity_IsDeactivated_Proxy( - IComObjIdentity __RPC_FAR * This); - - -void __RPC_STUB IComObjIdentity_IsDeactivated_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IComObjIdentity_GetIdentity_Proxy( - IComObjIdentity __RPC_FAR * This, - /* [out] */ IUnknown __RPC_FAR *__RPC_FAR *ppUnk); - - -void __RPC_STUB IComObjIdentity_GetIdentity_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - - -#endif /* __IComObjIdentity_INTERFACE_DEFINED__ */ - - -#ifndef __IPolicyMaker_INTERFACE_DEFINED__ -#define __IPolicyMaker_INTERFACE_DEFINED__ - -/* interface IPolicyMaker */ -/* [unique][uuid][object][local] */ - - -EXTERN_C const IID IID_IPolicyMaker; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("000001c4-0000-0000-C000-000000000046") - IPolicyMaker : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE AddClientPoliciesToSet( - /* [in] */ IPolicySet __RPC_FAR *pPS, - /* [in] */ IContext __RPC_FAR *pClientContext, - /* [in] */ IContext __RPC_FAR *pServerContext) = 0; - - virtual HRESULT STDMETHODCALLTYPE AddEnvoyPoliciesToSet( - /* [in] */ IPolicySet __RPC_FAR *pPS, - /* [in] */ IContext __RPC_FAR *pClientContext, - /* [in] */ IContext __RPC_FAR *pServerContext) = 0; - - virtual HRESULT STDMETHODCALLTYPE AddServerPoliciesToSet( - /* [in] */ IPolicySet __RPC_FAR *pPS, - /* [in] */ IContext __RPC_FAR *pClientContext, - /* [in] */ IContext __RPC_FAR *pServerContext) = 0; - - virtual HRESULT STDMETHODCALLTYPE Freeze( - /* [in] */ IObjContext __RPC_FAR *pObjContext) = 0; - - virtual HRESULT STDMETHODCALLTYPE CreateStub( - /* [in] */ IComObjIdentity __RPC_FAR *pID) = 0; - - virtual HRESULT STDMETHODCALLTYPE DestroyStub( - /* [in] */ IComObjIdentity __RPC_FAR *pID) = 0; - - virtual HRESULT STDMETHODCALLTYPE CreateProxy( - /* [in] */ IComObjIdentity __RPC_FAR *pID) = 0; - - virtual HRESULT STDMETHODCALLTYPE DestroyProxy( - /* [in] */ IComObjIdentity __RPC_FAR *pID) = 0; - - }; - -#else /* C style interface */ - - typedef struct IPolicyMakerVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( - IPolicyMaker __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( - IPolicyMaker __RPC_FAR * This); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( - IPolicyMaker __RPC_FAR * This); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *AddClientPoliciesToSet )( - IPolicyMaker __RPC_FAR * This, - /* [in] */ IPolicySet __RPC_FAR *pPS, - /* [in] */ IContext __RPC_FAR *pClientContext, - /* [in] */ IContext __RPC_FAR *pServerContext); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *AddEnvoyPoliciesToSet )( - IPolicyMaker __RPC_FAR * This, - /* [in] */ IPolicySet __RPC_FAR *pPS, - /* [in] */ IContext __RPC_FAR *pClientContext, - /* [in] */ IContext __RPC_FAR *pServerContext); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *AddServerPoliciesToSet )( - IPolicyMaker __RPC_FAR * This, - /* [in] */ IPolicySet __RPC_FAR *pPS, - /* [in] */ IContext __RPC_FAR *pClientContext, - /* [in] */ IContext __RPC_FAR *pServerContext); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Freeze )( - IPolicyMaker __RPC_FAR * This, - /* [in] */ IObjContext __RPC_FAR *pObjContext); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *CreateStub )( - IPolicyMaker __RPC_FAR * This, - /* [in] */ IComObjIdentity __RPC_FAR *pID); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *DestroyStub )( - IPolicyMaker __RPC_FAR * This, - /* [in] */ IComObjIdentity __RPC_FAR *pID); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *CreateProxy )( - IPolicyMaker __RPC_FAR * This, - /* [in] */ IComObjIdentity __RPC_FAR *pID); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *DestroyProxy )( - IPolicyMaker __RPC_FAR * This, - /* [in] */ IComObjIdentity __RPC_FAR *pID); - - END_INTERFACE - } IPolicyMakerVtbl; - - interface IPolicyMaker - { - CONST_VTBL struct IPolicyMakerVtbl __RPC_FAR *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IPolicyMaker_QueryInterface(This,riid,ppvObject) \ - (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) - -#define IPolicyMaker_AddRef(This) \ - (This)->lpVtbl -> AddRef(This) - -#define IPolicyMaker_Release(This) \ - (This)->lpVtbl -> Release(This) - - -#define IPolicyMaker_AddClientPoliciesToSet(This,pPS,pClientContext,pServerContext) \ - (This)->lpVtbl -> AddClientPoliciesToSet(This,pPS,pClientContext,pServerContext) - -#define IPolicyMaker_AddEnvoyPoliciesToSet(This,pPS,pClientContext,pServerContext) \ - (This)->lpVtbl -> AddEnvoyPoliciesToSet(This,pPS,pClientContext,pServerContext) - -#define IPolicyMaker_AddServerPoliciesToSet(This,pPS,pClientContext,pServerContext) \ - (This)->lpVtbl -> AddServerPoliciesToSet(This,pPS,pClientContext,pServerContext) - -#define IPolicyMaker_Freeze(This,pObjContext) \ - (This)->lpVtbl -> Freeze(This,pObjContext) - -#define IPolicyMaker_CreateStub(This,pID) \ - (This)->lpVtbl -> CreateStub(This,pID) - -#define IPolicyMaker_DestroyStub(This,pID) \ - (This)->lpVtbl -> DestroyStub(This,pID) - -#define IPolicyMaker_CreateProxy(This,pID) \ - (This)->lpVtbl -> CreateProxy(This,pID) - -#define IPolicyMaker_DestroyProxy(This,pID) \ - (This)->lpVtbl -> DestroyProxy(This,pID) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - -HRESULT STDMETHODCALLTYPE IPolicyMaker_AddClientPoliciesToSet_Proxy( - IPolicyMaker __RPC_FAR * This, - /* [in] */ IPolicySet __RPC_FAR *pPS, - /* [in] */ IContext __RPC_FAR *pClientContext, - /* [in] */ IContext __RPC_FAR *pServerContext); - - -void __RPC_STUB IPolicyMaker_AddClientPoliciesToSet_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicyMaker_AddEnvoyPoliciesToSet_Proxy( - IPolicyMaker __RPC_FAR * This, - /* [in] */ IPolicySet __RPC_FAR *pPS, - /* [in] */ IContext __RPC_FAR *pClientContext, - /* [in] */ IContext __RPC_FAR *pServerContext); - - -void __RPC_STUB IPolicyMaker_AddEnvoyPoliciesToSet_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicyMaker_AddServerPoliciesToSet_Proxy( - IPolicyMaker __RPC_FAR * This, - /* [in] */ IPolicySet __RPC_FAR *pPS, - /* [in] */ IContext __RPC_FAR *pClientContext, - /* [in] */ IContext __RPC_FAR *pServerContext); - - -void __RPC_STUB IPolicyMaker_AddServerPoliciesToSet_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicyMaker_Freeze_Proxy( - IPolicyMaker __RPC_FAR * This, - /* [in] */ IObjContext __RPC_FAR *pObjContext); - - -void __RPC_STUB IPolicyMaker_Freeze_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicyMaker_CreateStub_Proxy( - IPolicyMaker __RPC_FAR * This, - /* [in] */ IComObjIdentity __RPC_FAR *pID); - - -void __RPC_STUB IPolicyMaker_CreateStub_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicyMaker_DestroyStub_Proxy( - IPolicyMaker __RPC_FAR * This, - /* [in] */ IComObjIdentity __RPC_FAR *pID); - - -void __RPC_STUB IPolicyMaker_DestroyStub_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicyMaker_CreateProxy_Proxy( - IPolicyMaker __RPC_FAR * This, - /* [in] */ IComObjIdentity __RPC_FAR *pID); - - -void __RPC_STUB IPolicyMaker_CreateProxy_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IPolicyMaker_DestroyProxy_Proxy( - IPolicyMaker __RPC_FAR * This, - /* [in] */ IComObjIdentity __RPC_FAR *pID); - - -void __RPC_STUB IPolicyMaker_DestroyProxy_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - - -#endif /* __IPolicyMaker_INTERFACE_DEFINED__ */ - - -#ifndef __IExceptionNotification_INTERFACE_DEFINED__ -#define __IExceptionNotification_INTERFACE_DEFINED__ - -/* interface IExceptionNotification */ -/* [unique][uuid][object][local] */ - - -EXTERN_C const IID IID_IExceptionNotification; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("000001db-0000-0000-C000-000000000046") - IExceptionNotification : public IUnknown - { - public: - virtual void STDMETHODCALLTYPE ServerException( - /* [in] */ void __RPC_FAR *pExcepPtrs) = 0; - - }; - -#else /* C style interface */ - - typedef struct IExceptionNotificationVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( - IExceptionNotification __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( - IExceptionNotification __RPC_FAR * This); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( - IExceptionNotification __RPC_FAR * This); - - void ( STDMETHODCALLTYPE __RPC_FAR *ServerException )( - IExceptionNotification __RPC_FAR * This, - /* [in] */ void __RPC_FAR *pExcepPtrs); - - END_INTERFACE - } IExceptionNotificationVtbl; - - interface IExceptionNotification - { - CONST_VTBL struct IExceptionNotificationVtbl __RPC_FAR *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IExceptionNotification_QueryInterface(This,riid,ppvObject) \ - (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) - -#define IExceptionNotification_AddRef(This) \ - (This)->lpVtbl -> AddRef(This) - -#define IExceptionNotification_Release(This) \ - (This)->lpVtbl -> Release(This) - - -#define IExceptionNotification_ServerException(This,pExcepPtrs) \ - (This)->lpVtbl -> ServerException(This,pExcepPtrs) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - -void STDMETHODCALLTYPE IExceptionNotification_ServerException_Proxy( - IExceptionNotification __RPC_FAR * This, - /* [in] */ void __RPC_FAR *pExcepPtrs); - - -void __RPC_STUB IExceptionNotification_ServerException_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - - -#endif /* __IExceptionNotification_INTERFACE_DEFINED__ */ - - -#ifndef __IMarshalEnvoy_INTERFACE_DEFINED__ -#define __IMarshalEnvoy_INTERFACE_DEFINED__ - -/* interface IMarshalEnvoy */ -/* [unique][uuid][object][local] */ - - -EXTERN_C const IID IID_IMarshalEnvoy; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("000001c8-0000-0000-C000-000000000046") - IMarshalEnvoy : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE GetEnvoyUnmarshalClass( - /* [in] */ DWORD dwDestContext, - /* [out] */ CLSID __RPC_FAR *pClsid) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetEnvoySizeMax( - /* [in] */ DWORD dwDestContext, - /* [out] */ DWORD __RPC_FAR *pcb) = 0; - - virtual HRESULT STDMETHODCALLTYPE MarshalEnvoy( - /* [in] */ IStream __RPC_FAR *pStream, - /* [in] */ DWORD dwDestContext) = 0; - - virtual HRESULT STDMETHODCALLTYPE UnmarshalEnvoy( - /* [in] */ IStream __RPC_FAR *pStream, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppunk) = 0; - - }; - -#else /* C style interface */ - - typedef struct IMarshalEnvoyVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( - IMarshalEnvoy __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( - IMarshalEnvoy __RPC_FAR * This); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( - IMarshalEnvoy __RPC_FAR * This); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetEnvoyUnmarshalClass )( - IMarshalEnvoy __RPC_FAR * This, - /* [in] */ DWORD dwDestContext, - /* [out] */ CLSID __RPC_FAR *pClsid); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetEnvoySizeMax )( - IMarshalEnvoy __RPC_FAR * This, - /* [in] */ DWORD dwDestContext, - /* [out] */ DWORD __RPC_FAR *pcb); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *MarshalEnvoy )( - IMarshalEnvoy __RPC_FAR * This, - /* [in] */ IStream __RPC_FAR *pStream, - /* [in] */ DWORD dwDestContext); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *UnmarshalEnvoy )( - IMarshalEnvoy __RPC_FAR * This, - /* [in] */ IStream __RPC_FAR *pStream, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppunk); - - END_INTERFACE - } IMarshalEnvoyVtbl; - - interface IMarshalEnvoy - { - CONST_VTBL struct IMarshalEnvoyVtbl __RPC_FAR *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IMarshalEnvoy_QueryInterface(This,riid,ppvObject) \ - (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) - -#define IMarshalEnvoy_AddRef(This) \ - (This)->lpVtbl -> AddRef(This) - -#define IMarshalEnvoy_Release(This) \ - (This)->lpVtbl -> Release(This) - - -#define IMarshalEnvoy_GetEnvoyUnmarshalClass(This,dwDestContext,pClsid) \ - (This)->lpVtbl -> GetEnvoyUnmarshalClass(This,dwDestContext,pClsid) - -#define IMarshalEnvoy_GetEnvoySizeMax(This,dwDestContext,pcb) \ - (This)->lpVtbl -> GetEnvoySizeMax(This,dwDestContext,pcb) - -#define IMarshalEnvoy_MarshalEnvoy(This,pStream,dwDestContext) \ - (This)->lpVtbl -> MarshalEnvoy(This,pStream,dwDestContext) - -#define IMarshalEnvoy_UnmarshalEnvoy(This,pStream,riid,ppunk) \ - (This)->lpVtbl -> UnmarshalEnvoy(This,pStream,riid,ppunk) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - -HRESULT STDMETHODCALLTYPE IMarshalEnvoy_GetEnvoyUnmarshalClass_Proxy( - IMarshalEnvoy __RPC_FAR * This, - /* [in] */ DWORD dwDestContext, - /* [out] */ CLSID __RPC_FAR *pClsid); - - -void __RPC_STUB IMarshalEnvoy_GetEnvoyUnmarshalClass_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IMarshalEnvoy_GetEnvoySizeMax_Proxy( - IMarshalEnvoy __RPC_FAR * This, - /* [in] */ DWORD dwDestContext, - /* [out] */ DWORD __RPC_FAR *pcb); - - -void __RPC_STUB IMarshalEnvoy_GetEnvoySizeMax_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IMarshalEnvoy_MarshalEnvoy_Proxy( - IMarshalEnvoy __RPC_FAR * This, - /* [in] */ IStream __RPC_FAR *pStream, - /* [in] */ DWORD dwDestContext); - - -void __RPC_STUB IMarshalEnvoy_MarshalEnvoy_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IMarshalEnvoy_UnmarshalEnvoy_Proxy( - IMarshalEnvoy __RPC_FAR * This, - /* [in] */ IStream __RPC_FAR *pStream, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppunk); - - -void __RPC_STUB IMarshalEnvoy_UnmarshalEnvoy_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - - -#endif /* __IMarshalEnvoy_INTERFACE_DEFINED__ */ - - -#ifndef __IWrapperInfo_INTERFACE_DEFINED__ -#define __IWrapperInfo_INTERFACE_DEFINED__ - -/* interface IWrapperInfo */ -/* [unique][uuid][object][local] */ - - -EXTERN_C const IID IID_IWrapperInfo; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("5052f924-7ab8-11d3-b93f-00c04f990176") - IWrapperInfo : public IUnknown - { - public: - virtual void STDMETHODCALLTYPE SetMapping( - void __RPC_FAR *pv) = 0; - - virtual void __RPC_FAR *STDMETHODCALLTYPE GetMapping( void) = 0; - - virtual IObjContext __RPC_FAR *STDMETHODCALLTYPE GetServerObjectContext( void) = 0; - - virtual IUnknown __RPC_FAR *STDMETHODCALLTYPE GetServerObject( void) = 0; - - }; - -#else /* C style interface */ - - typedef struct IWrapperInfoVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( - IWrapperInfo __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( - IWrapperInfo __RPC_FAR * This); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( - IWrapperInfo __RPC_FAR * This); - - void ( STDMETHODCALLTYPE __RPC_FAR *SetMapping )( - IWrapperInfo __RPC_FAR * This, - void __RPC_FAR *pv); - - void __RPC_FAR *( STDMETHODCALLTYPE __RPC_FAR *GetMapping )( - IWrapperInfo __RPC_FAR * This); - - IObjContext __RPC_FAR *( STDMETHODCALLTYPE __RPC_FAR *GetServerObjectContext )( - IWrapperInfo __RPC_FAR * This); - - IUnknown __RPC_FAR *( STDMETHODCALLTYPE __RPC_FAR *GetServerObject )( - IWrapperInfo __RPC_FAR * This); - - END_INTERFACE - } IWrapperInfoVtbl; - - interface IWrapperInfo - { - CONST_VTBL struct IWrapperInfoVtbl __RPC_FAR *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IWrapperInfo_QueryInterface(This,riid,ppvObject) \ - (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) - -#define IWrapperInfo_AddRef(This) \ - (This)->lpVtbl -> AddRef(This) - -#define IWrapperInfo_Release(This) \ - (This)->lpVtbl -> Release(This) - - -#define IWrapperInfo_SetMapping(This,pv) \ - (This)->lpVtbl -> SetMapping(This,pv) - -#define IWrapperInfo_GetMapping(This) \ - (This)->lpVtbl -> GetMapping(This) - -#define IWrapperInfo_GetServerObjectContext(This) \ - (This)->lpVtbl -> GetServerObjectContext(This) - -#define IWrapperInfo_GetServerObject(This) \ - (This)->lpVtbl -> GetServerObject(This) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - -void STDMETHODCALLTYPE IWrapperInfo_SetMapping_Proxy( - IWrapperInfo __RPC_FAR * This, - void __RPC_FAR *pv); - - -void __RPC_STUB IWrapperInfo_SetMapping_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -void __RPC_FAR *STDMETHODCALLTYPE IWrapperInfo_GetMapping_Proxy( - IWrapperInfo __RPC_FAR * This); - - -void __RPC_STUB IWrapperInfo_GetMapping_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -IObjContext __RPC_FAR *STDMETHODCALLTYPE IWrapperInfo_GetServerObjectContext_Proxy( - IWrapperInfo __RPC_FAR * This); - - -void __RPC_STUB IWrapperInfo_GetServerObjectContext_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -IUnknown __RPC_FAR *STDMETHODCALLTYPE IWrapperInfo_GetServerObject_Proxy( - IWrapperInfo __RPC_FAR * This); - - -void __RPC_STUB IWrapperInfo_GetServerObject_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - - -#endif /* __IWrapperInfo_INTERFACE_DEFINED__ */ - - -/* interface __MIDL_itf_contxt_0092 */ -/* [local] */ - - -typedef DWORD APARTMENTID; - - - -extern RPC_IF_HANDLE __MIDL_itf_contxt_0092_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_contxt_0092_v0_0_s_ifspec; - -#ifndef __IComThreadingInfo_INTERFACE_DEFINED__ -#define __IComThreadingInfo_INTERFACE_DEFINED__ - -/* interface IComThreadingInfo */ -/* [unique][uuid][object][local] */ - - -EXTERN_C const IID IID_IComThreadingInfo; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("000001ce-0000-0000-C000-000000000046") - IComThreadingInfo : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE GetCurrentApartmentType( - /* [out] */ APTTYPE __RPC_FAR *pAptType) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCurrentThreadType( - /* [out] */ THDTYPE __RPC_FAR *pThreadType) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetCurrentLogicalThreadId( - /* [out] */ GUID __RPC_FAR *pguidLogicalThreadId) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetCurrentLogicalThreadId( - /* [in] */ REFGUID rguid) = 0; - - }; - -#else /* C style interface */ - - typedef struct IComThreadingInfoVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( - IComThreadingInfo __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( - IComThreadingInfo __RPC_FAR * This); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( - IComThreadingInfo __RPC_FAR * This); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetCurrentApartmentType )( - IComThreadingInfo __RPC_FAR * This, - /* [out] */ APTTYPE __RPC_FAR *pAptType); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetCurrentThreadType )( - IComThreadingInfo __RPC_FAR * This, - /* [out] */ THDTYPE __RPC_FAR *pThreadType); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetCurrentLogicalThreadId )( - IComThreadingInfo __RPC_FAR * This, - /* [out] */ GUID __RPC_FAR *pguidLogicalThreadId); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *SetCurrentLogicalThreadId )( - IComThreadingInfo __RPC_FAR * This, - /* [in] */ REFGUID rguid); - - END_INTERFACE - } IComThreadingInfoVtbl; - - interface IComThreadingInfo - { - CONST_VTBL struct IComThreadingInfoVtbl __RPC_FAR *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IComThreadingInfo_QueryInterface(This,riid,ppvObject) \ - (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) - -#define IComThreadingInfo_AddRef(This) \ - (This)->lpVtbl -> AddRef(This) - -#define IComThreadingInfo_Release(This) \ - (This)->lpVtbl -> Release(This) - - -#define IComThreadingInfo_GetCurrentApartmentType(This,pAptType) \ - (This)->lpVtbl -> GetCurrentApartmentType(This,pAptType) - -#define IComThreadingInfo_GetCurrentThreadType(This,pThreadType) \ - (This)->lpVtbl -> GetCurrentThreadType(This,pThreadType) - -#define IComThreadingInfo_GetCurrentLogicalThreadId(This,pguidLogicalThreadId) \ - (This)->lpVtbl -> GetCurrentLogicalThreadId(This,pguidLogicalThreadId) - -#define IComThreadingInfo_SetCurrentLogicalThreadId(This,rguid) \ - (This)->lpVtbl -> SetCurrentLogicalThreadId(This,rguid) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - -HRESULT STDMETHODCALLTYPE IComThreadingInfo_GetCurrentApartmentType_Proxy( - IComThreadingInfo __RPC_FAR * This, - /* [out] */ APTTYPE __RPC_FAR *pAptType); - - -void __RPC_STUB IComThreadingInfo_GetCurrentApartmentType_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IComThreadingInfo_GetCurrentThreadType_Proxy( - IComThreadingInfo __RPC_FAR * This, - /* [out] */ THDTYPE __RPC_FAR *pThreadType); - - -void __RPC_STUB IComThreadingInfo_GetCurrentThreadType_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IComThreadingInfo_GetCurrentLogicalThreadId_Proxy( - IComThreadingInfo __RPC_FAR * This, - /* [out] */ GUID __RPC_FAR *pguidLogicalThreadId); - - -void __RPC_STUB IComThreadingInfo_GetCurrentLogicalThreadId_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IComThreadingInfo_SetCurrentLogicalThreadId_Proxy( - IComThreadingInfo __RPC_FAR * This, - /* [in] */ REFGUID rguid); - - -void __RPC_STUB IComThreadingInfo_SetCurrentLogicalThreadId_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - - -#endif /* __IComThreadingInfo_INTERFACE_DEFINED__ */ - - -#ifndef __IComDispatchInfo_INTERFACE_DEFINED__ -#define __IComDispatchInfo_INTERFACE_DEFINED__ - -/* interface IComDispatchInfo */ -/* [unique][uuid][object][local] */ - - -EXTERN_C const IID IID_IComDispatchInfo; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("000001d9-0000-0000-C000-000000000046") - IComDispatchInfo : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE EnableComInits( - /* [out] */ void __RPC_FAR *__RPC_FAR *ppvCookie) = 0; - - virtual HRESULT STDMETHODCALLTYPE DisableComInits( - /* [in] */ void __RPC_FAR *pvCookie) = 0; - - }; - -#else /* C style interface */ - - typedef struct IComDispatchInfoVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( - IComDispatchInfo __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( - IComDispatchInfo __RPC_FAR * This); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( - IComDispatchInfo __RPC_FAR * This); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *EnableComInits )( - IComDispatchInfo __RPC_FAR * This, - /* [out] */ void __RPC_FAR *__RPC_FAR *ppvCookie); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *DisableComInits )( - IComDispatchInfo __RPC_FAR * This, - /* [in] */ void __RPC_FAR *pvCookie); - - END_INTERFACE - } IComDispatchInfoVtbl; - - interface IComDispatchInfo - { - CONST_VTBL struct IComDispatchInfoVtbl __RPC_FAR *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IComDispatchInfo_QueryInterface(This,riid,ppvObject) \ - (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) - -#define IComDispatchInfo_AddRef(This) \ - (This)->lpVtbl -> AddRef(This) - -#define IComDispatchInfo_Release(This) \ - (This)->lpVtbl -> Release(This) - - -#define IComDispatchInfo_EnableComInits(This,ppvCookie) \ - (This)->lpVtbl -> EnableComInits(This,ppvCookie) - -#define IComDispatchInfo_DisableComInits(This,pvCookie) \ - (This)->lpVtbl -> DisableComInits(This,pvCookie) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - -HRESULT STDMETHODCALLTYPE IComDispatchInfo_EnableComInits_Proxy( - IComDispatchInfo __RPC_FAR * This, - /* [out] */ void __RPC_FAR *__RPC_FAR *ppvCookie); - - -void __RPC_STUB IComDispatchInfo_EnableComInits_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IComDispatchInfo_DisableComInits_Proxy( - IComDispatchInfo __RPC_FAR * This, - /* [in] */ void __RPC_FAR *pvCookie); - - -void __RPC_STUB IComDispatchInfo_DisableComInits_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - - -#endif /* __IComDispatchInfo_INTERFACE_DEFINED__ */ - - -/* interface __MIDL_itf_contxt_0094 */ -/* [local] */ - -typedef DWORD HActivator; - -STDAPI CoCreateObjectInContext(IUnknown *pUnk, IObjContext *pObjectCtx, REFIID riid, void **ppv); -STDAPI CoGetApartmentID(APTTYPE dAptType, HActivator* pAptID); -STDAPI CoDeactivateObject(IUnknown *pUnk, IUnknown **ppCookie); -STDAPI CoReactivateObject(IUnknown *pUnk, IUnknown *pCookie); -#define MSHLFLAGS_NO_IEC 0x8 // don't use IExternalConnextion -#define MSHLFLAGS_NO_IMARSHAL 0x10 // don't use IMarshal -#define CONTEXTFLAGS_FROZEN 0x01 // Frozen context -#define CONTEXTFLAGS_ALLOWUNAUTH 0x02 // Allow unauthenticated calls -#define CONTEXTFLAGS_ENVOYCONTEXT 0x04 // Envoy context -#define CONTEXTFLAGS_DEFAULTCONTEXT 0x08 // Default context -#define CONTEXTFLAGS_STATICCONTEXT 0x10 // Static context -#define CONTEXTFLAGS_INPROPTABLE 0x20 // Is in property table -#define CONTEXTFLAGS_INDESTRUCTOR 0x40 // Is in destructor -#define CONTEXTFLAGS_URTPROPPRESENT 0x80 // CLR property added - - -extern RPC_IF_HANDLE __MIDL_itf_contxt_0094_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_contxt_0094_v0_0_s_ifspec; - -/* Additional Prototypes for ALL interfaces */ - -/* end of Additional Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/coreclr/vm/CMakeLists.txt b/src/coreclr/vm/CMakeLists.txt index 8c0b03342d016c..6983f21238b236 100644 --- a/src/coreclr/vm/CMakeLists.txt +++ b/src/coreclr/vm/CMakeLists.txt @@ -364,7 +364,6 @@ set(VM_SOURCES_WKS runtimehandles.cpp safehandle.cpp simplerwlock.cpp - sourceline.cpp stackingallocator.cpp stringliteralmap.cpp stubcache.cpp @@ -465,7 +464,6 @@ set(VM_HEADERS_WKS reflectioninvocation.h runtimehandles.h simplerwlock.hpp - sourceline.h stackingallocator.h stringliteralmap.h stubcache.h diff --git a/src/coreclr/vm/comcache.cpp b/src/coreclr/vm/comcache.cpp index 57eb3ced7863da..6454b439541044 100644 --- a/src/coreclr/vm/comcache.cpp +++ b/src/coreclr/vm/comcache.cpp @@ -8,9 +8,7 @@ #include #include "comcache.h" #include "runtimecallablewrapper.h" -#include "mtx.h" -#include "contxt.h" -#include "ctxtcall.h" +#include #include "win32threadpool.h" #ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT diff --git a/src/coreclr/vm/comcache.h b/src/coreclr/vm/comcache.h index 9010eafa50e9cc..f122f4028686fa 100644 --- a/src/coreclr/vm/comcache.h +++ b/src/coreclr/vm/comcache.h @@ -14,8 +14,10 @@ #error FEATURE_COMINTEROP is required for this file #endif // FEATURE_COMINTEROP -#include "contxt.h" -#include "ctxtcall.h" +// COM context callback +typedef HRESULT ( __stdcall __RPC_FAR *PFNCTXCALLBACK)(void __RPC_FAR *pParam); + +#include //================================================================ // Forward declarations. diff --git a/src/coreclr/vm/ctxtcall.h b/src/coreclr/vm/ctxtcall.h deleted file mode 100644 index 9e1de54a9a6e14..00000000000000 --- a/src/coreclr/vm/ctxtcall.h +++ /dev/null @@ -1,409 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - - -#pragma warning( disable: 4049 ) /* more than 64k source lines */ - -/* this ALWAYS GENERATED file contains the definitions for the interfaces */ - - -/* File created by MIDL compiler version 5.03.0279 */ -/* at Wed Dec 06 11:12:56 2000 - */ -/* Compiler settings for ctxtcall.idl: - Oicf (OptLev=i2), W1, Zp8, env=Win32 (32b run), ms_ext, c_ext, robust - error checks: allocation ref bounds_check enum stub_data - VC __declspec() decoration level: - __declspec(uuid()), __declspec(selectany), __declspec(novtable) - DECLSPEC_UUID(), MIDL_INTERFACE() -*/ -//@@MIDL_FILE_HEADING( ) - - -/* verify that the version is high enough to compile this file*/ -#ifndef __REQUIRED_RPCNDR_H_VERSION__ -#define __REQUIRED_RPCNDR_H_VERSION__ 475 -#endif - -#include "rpc.h" -#include "rpcndr.h" - -#ifndef __RPCNDR_H_VERSION__ -#error this stub requires an updated version of -#endif // __RPCNDR_H_VERSION__ - -#ifndef COM_NO_WINDOWS_H -#include "windows.h" -#include "ole2.h" -#endif /*COM_NO_WINDOWS_H*/ - -#ifndef __ctxtcall_h__ -#define __ctxtcall_h__ - -/* Forward Declarations */ - -#ifndef __IContextCallback_FWD_DEFINED__ -#define __IContextCallback_FWD_DEFINED__ -typedef interface IContextCallback IContextCallback; -#endif /* __IContextCallback_FWD_DEFINED__ */ - - -#ifndef __ITeardownNotification_FWD_DEFINED__ -#define __ITeardownNotification_FWD_DEFINED__ -typedef interface ITeardownNotification ITeardownNotification; -#endif /* __ITeardownNotification_FWD_DEFINED__ */ - - -#ifndef __IComApartmentState_FWD_DEFINED__ -#define __IComApartmentState_FWD_DEFINED__ -typedef interface IComApartmentState IComApartmentState; -#endif /* __IComApartmentState_FWD_DEFINED__ */ - - -/* header files for imported files */ -#include "wtypes.h" -#include "objidl.h" - -#ifdef __cplusplus -extern "C"{ -#endif - -void __RPC_FAR * __RPC_USER MIDL_user_allocate(size_t); -void __RPC_USER MIDL_user_free( void __RPC_FAR * ); - -/* interface __MIDL_itf_ctxtcall_0000 */ -/* [local] */ - -typedef struct tagComCallData - { - DWORD dwDispid; - DWORD dwReserved; - void __RPC_FAR *pUserDefined; - } ComCallData; - - - -extern RPC_IF_HANDLE __MIDL_itf_ctxtcall_0000_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_ctxtcall_0000_v0_0_s_ifspec; - -#ifndef __IContextCallback_INTERFACE_DEFINED__ -#define __IContextCallback_INTERFACE_DEFINED__ - -/* interface IContextCallback */ -/* [unique][uuid][object][local] */ - -typedef /* [ref] */ HRESULT ( __stdcall __RPC_FAR *PFNCONTEXTCALL )( - ComCallData __RPC_FAR *pParam); - - -EXTERN_C const IID IID_IContextCallback; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("000001da-0000-0000-C000-000000000046") - IContextCallback : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE ContextCallback( - /* [in] */ PFNCONTEXTCALL pfnCallback, - /* [in] */ ComCallData __RPC_FAR *pParam, - /* [in] */ REFIID riid, - /* [in] */ int iMethod, - /* [in] */ IUnknown __RPC_FAR *pUnk) = 0; - - }; - -#else /* C style interface */ - - typedef struct IContextCallbackVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( - IContextCallback __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( - IContextCallback __RPC_FAR * This); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( - IContextCallback __RPC_FAR * This); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *ContextCallback )( - IContextCallback __RPC_FAR * This, - /* [in] */ PFNCONTEXTCALL pfnCallback, - /* [in] */ ComCallData __RPC_FAR *pParam, - /* [in] */ REFIID riid, - /* [in] */ int iMethod, - /* [in] */ IUnknown __RPC_FAR *pUnk); - - END_INTERFACE - } IContextCallbackVtbl; - - interface IContextCallback - { - CONST_VTBL struct IContextCallbackVtbl __RPC_FAR *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IContextCallback_QueryInterface(This,riid,ppvObject) \ - (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) - -#define IContextCallback_AddRef(This) \ - (This)->lpVtbl -> AddRef(This) - -#define IContextCallback_Release(This) \ - (This)->lpVtbl -> Release(This) - - -#define IContextCallback_ContextCallback(This,pfnCallback,pParam,riid,iMethod,pUnk) \ - (This)->lpVtbl -> ContextCallback(This,pfnCallback,pParam,riid,iMethod,pUnk) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - -HRESULT STDMETHODCALLTYPE IContextCallback_ContextCallback_Proxy( - IContextCallback __RPC_FAR * This, - /* [in] */ PFNCONTEXTCALL pfnCallback, - /* [in] */ ComCallData __RPC_FAR *pParam, - /* [in] */ REFIID riid, - /* [in] */ int iMethod, - /* [in] */ IUnknown __RPC_FAR *pUnk); - - -void __RPC_STUB IContextCallback_ContextCallback_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - - -#endif /* __IContextCallback_INTERFACE_DEFINED__ */ - - -#ifndef __ITeardownNotification_INTERFACE_DEFINED__ -#define __ITeardownNotification_INTERFACE_DEFINED__ - -/* interface ITeardownNotification */ -/* [unique][object][local][uuid] */ - - -EXTERN_C const IID IID_ITeardownNotification; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("a85e0fb6-8bf4-4614-b164-7b43ef43f5be") - ITeardownNotification : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE TeardownHint( void) = 0; - - }; - -#else /* C style interface */ - - typedef struct ITeardownNotificationVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( - ITeardownNotification __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( - ITeardownNotification __RPC_FAR * This); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( - ITeardownNotification __RPC_FAR * This); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *TeardownHint )( - ITeardownNotification __RPC_FAR * This); - - END_INTERFACE - } ITeardownNotificationVtbl; - - interface ITeardownNotification - { - CONST_VTBL struct ITeardownNotificationVtbl __RPC_FAR *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define ITeardownNotification_QueryInterface(This,riid,ppvObject) \ - (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) - -#define ITeardownNotification_AddRef(This) \ - (This)->lpVtbl -> AddRef(This) - -#define ITeardownNotification_Release(This) \ - (This)->lpVtbl -> Release(This) - - -#define ITeardownNotification_TeardownHint(This) \ - (This)->lpVtbl -> TeardownHint(This) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - -HRESULT STDMETHODCALLTYPE ITeardownNotification_TeardownHint_Proxy( - ITeardownNotification __RPC_FAR * This); - - -void __RPC_STUB ITeardownNotification_TeardownHint_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - - -#endif /* __ITeardownNotification_INTERFACE_DEFINED__ */ - - -#ifndef __IComApartmentState_INTERFACE_DEFINED__ -#define __IComApartmentState_INTERFACE_DEFINED__ - -/* interface IComApartmentState */ -/* [object][local][uuid] */ - - -EXTERN_C const IID IID_IComApartmentState; - -#if defined(__cplusplus) && !defined(CINTERFACE) - - MIDL_INTERFACE("7e220139-8dde-47ef-b181-08be603efd75") - IComApartmentState : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE RegisterForTeardownHint( - /* [in] */ ITeardownNotification __RPC_FAR *pT, - /* [in] */ DWORD dwFlags, - /* [out] */ ULONG_PTR __RPC_FAR *pCookie) = 0; - - virtual HRESULT STDMETHODCALLTYPE UnregisterForTeardownHint( - /* [in] */ ULONG_PTR cookie) = 0; - - }; - -#else /* C style interface */ - - typedef struct IComApartmentStateVtbl - { - BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( - IComApartmentState __RPC_FAR * This, - /* [in] */ REFIID riid, - /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( - IComApartmentState __RPC_FAR * This); - - ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( - IComApartmentState __RPC_FAR * This); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *RegisterForTeardownHint )( - IComApartmentState __RPC_FAR * This, - /* [in] */ ITeardownNotification __RPC_FAR *pT, - /* [in] */ DWORD dwFlags, - /* [out] */ ULONG_PTR __RPC_FAR *pCookie); - - HRESULT ( STDMETHODCALLTYPE __RPC_FAR *UnregisterForTeardownHint )( - IComApartmentState __RPC_FAR * This, - /* [in] */ ULONG_PTR cookie); - - END_INTERFACE - } IComApartmentStateVtbl; - - interface IComApartmentState - { - CONST_VTBL struct IComApartmentStateVtbl __RPC_FAR *lpVtbl; - }; - - - -#ifdef COBJMACROS - - -#define IComApartmentState_QueryInterface(This,riid,ppvObject) \ - (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) - -#define IComApartmentState_AddRef(This) \ - (This)->lpVtbl -> AddRef(This) - -#define IComApartmentState_Release(This) \ - (This)->lpVtbl -> Release(This) - - -#define IComApartmentState_RegisterForTeardownHint(This,pT,dwFlags,pCookie) \ - (This)->lpVtbl -> RegisterForTeardownHint(This,pT,dwFlags,pCookie) - -#define IComApartmentState_UnregisterForTeardownHint(This,cookie) \ - (This)->lpVtbl -> UnregisterForTeardownHint(This,cookie) - -#endif /* COBJMACROS */ - - -#endif /* C style interface */ - - - -HRESULT STDMETHODCALLTYPE IComApartmentState_RegisterForTeardownHint_Proxy( - IComApartmentState __RPC_FAR * This, - /* [in] */ ITeardownNotification __RPC_FAR *pT, - /* [in] */ DWORD dwFlags, - /* [out] */ ULONG_PTR __RPC_FAR *pCookie); - - -void __RPC_STUB IComApartmentState_RegisterForTeardownHint_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - -HRESULT STDMETHODCALLTYPE IComApartmentState_UnregisterForTeardownHint_Proxy( - IComApartmentState __RPC_FAR * This, - /* [in] */ ULONG_PTR cookie); - - -void __RPC_STUB IComApartmentState_UnregisterForTeardownHint_Stub( - IRpcStubBuffer *This, - IRpcChannelBuffer *_pRpcChannelBuffer, - PRPC_MESSAGE _pRpcMessage, - DWORD *_pdwStubPhase); - - - -#endif /* __IComApartmentState_INTERFACE_DEFINED__ */ - - -/* Additional Prototypes for ALL interfaces */ - -/* end of Additional Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif - - diff --git a/src/coreclr/vm/dataimage.h b/src/coreclr/vm/dataimage.h deleted file mode 100644 index 8f447acc211d5f..00000000000000 --- a/src/coreclr/vm/dataimage.h +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - - - -#ifndef _DATAIMAGE_H_ -#define _DATAIMAGE_H_ - -// IMAGE_REL_BASED_PTR is architecture specific reloc of virtual address -#ifdef TARGET_64BIT -#define IMAGE_REL_BASED_PTR IMAGE_REL_BASED_DIR64 -#else // !TARGET_64BIT -#define IMAGE_REL_BASED_PTR IMAGE_REL_BASED_HIGHLOW -#endif // !TARGET_64BIT - -// Special NGEN-specific relocation type for relative pointer (used to make NGen relocation section smaller) -#define IMAGE_REL_BASED_RELPTR 0x7D - -#endif // _DATAIMAGE_H_ diff --git a/src/coreclr/vm/olecontexthelpers.cpp b/src/coreclr/vm/olecontexthelpers.cpp index 21471238a71612..32f202bdb39283 100644 --- a/src/coreclr/vm/olecontexthelpers.cpp +++ b/src/coreclr/vm/olecontexthelpers.cpp @@ -6,10 +6,8 @@ #ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT -#include "mtx.h" +#include "olecontexthelpers.h" #include "oletls.h" -#include "contxt.h" -#include "ctxtcall.h" HRESULT GetCurrentObjCtx(IUnknown **ppObjCtx) { diff --git a/src/coreclr/vm/olecontexthelpers.h b/src/coreclr/vm/olecontexthelpers.h index 2722fd9542fba2..680afd5cac269b 100644 --- a/src/coreclr/vm/olecontexthelpers.h +++ b/src/coreclr/vm/olecontexthelpers.h @@ -13,9 +13,7 @@ #error FEATURE_COMINTEROP_APARTMENT_SUPPORT #endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT -#include "contxt.h" -#include "mtx.h" -#include "ctxtcall.h" +#include //================================================================ // OLE32 Context helpers. diff --git a/src/coreclr/vm/peimagelayout.cpp b/src/coreclr/vm/peimagelayout.cpp index d2e2482d002e21..2cf519425da2a9 100644 --- a/src/coreclr/vm/peimagelayout.cpp +++ b/src/coreclr/vm/peimagelayout.cpp @@ -7,7 +7,6 @@ #include "common.h" #include "peimagelayout.h" #include "peimagelayout.inl" -#include "dataimage.h" #if defined(TARGET_WINDOWS) #include "amsi.h" @@ -81,7 +80,7 @@ PEImageLayout* PEImageLayout::LoadConverted(PEImage* pOwner) // TODO: enable on OSX eventually // right now we have binaries that will trigger this in a singlefile bundle. -#ifdef TARGET_LINUX +#ifdef TARGET_LINUX // we should not see R2R files here on Unix. // ConvertedImageLayout may be able to handle them, but the fact that we were unable to // load directly implies that MAPMapPEFile could not consume what crossgen produced. @@ -170,6 +169,13 @@ DWORD SectionCharacteristicsToPageProtection(UINT characteristics) } #endif // TARGET_UNIX +// IMAGE_REL_BASED_PTR is architecture specific reloc of virtual address +#ifdef TARGET_64BIT +#define IMAGE_REL_BASED_PTR IMAGE_REL_BASED_DIR64 +#else // !TARGET_64BIT +#define IMAGE_REL_BASED_PTR IMAGE_REL_BASED_HIGHLOW +#endif // !TARGET_64BIT + //To force base relocation on Vista (which uses ASLR), unmask IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE //(0x40) for OptionalHeader.DllCharacteristics void PEImageLayout::ApplyBaseRelocations(bool relocationMustWriteCopy) diff --git a/src/coreclr/vm/sourceline.cpp b/src/coreclr/vm/sourceline.cpp deleted file mode 100644 index 305358484aee0e..00000000000000 --- a/src/coreclr/vm/sourceline.cpp +++ /dev/null @@ -1,328 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - - - -#include "common.h" - -#include "sourceline.h" - -////////////////////////////////////////////////////////////////// - -#ifdef ENABLE_DIAGNOSTIC_SYMBOL_READING - -class CCallback : public IDiaLoadCallback -{ - int m_nRefCount; -public: - CCallback() { - CONTRACTL - { - MODE_ANY; - GC_NOTRIGGER; - NOTHROW; - }CONTRACTL_END; - - m_nRefCount = 0; - } - - //IUnknown - ULONG STDMETHODCALLTYPE AddRef() { - LIMITED_METHOD_CONTRACT; - m_nRefCount++; - return m_nRefCount; - } - - ULONG STDMETHODCALLTYPE Release() { - CONTRACTL - { - THROWS; - GC_NOTRIGGER; - MODE_ANY; - } CONTRACTL_END; - - if ( (--m_nRefCount) == 0 ) - delete this; - - return m_nRefCount; - } - - HRESULT STDMETHODCALLTYPE QueryInterface( REFIID rid, void **ppUnk ) { - WRAPPER_NO_CONTRACT; - if ( ppUnk == NULL ) { - return E_INVALIDARG; - } - if (rid == __uuidof( IDiaLoadCallback ) ) - *ppUnk = (IDiaLoadCallback *)this; - else if (rid == __uuidof( IDiaLoadCallback ) ) - *ppUnk = (IDiaLoadCallback *)this; - else if (rid == __uuidof( IUnknown ) ) - *ppUnk = (IUnknown *)this; - else - *ppUnk = NULL; - - if ( *ppUnk != NULL ) { - AddRef(); - return S_OK; - } - - return E_NOINTERFACE; - } - - HRESULT STDMETHODCALLTYPE NotifyDebugDir( - BOOL fExecutable, - DWORD cbData, - BYTE data[]) // really a const struct _IMAGE_DEBUG_DIRECTORY * - { - LIMITED_METHOD_CONTRACT; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE NotifyOpenDBG( - LPCOLESTR dbgPath, - HRESULT resultCode) - { - LIMITED_METHOD_CONTRACT; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE NotifyOpenPDB( - LPCOLESTR pdbPath, - HRESULT resultCode) - { - LIMITED_METHOD_CONTRACT; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE RestrictRegistryAccess() // return hr != S_OK to prevent querying the registry for symbol search paths - { - LIMITED_METHOD_CONTRACT; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE RestrictSymbolServerAccess() // return hr != S_OK to prevent accessing a symbol server - { - LIMITED_METHOD_CONTRACT; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE RestrictOriginalPathAccess() // return hr != S_OK to prevent querying the registry for symbol search paths - { - LIMITED_METHOD_CONTRACT; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE RestrictReferencePathAccess() // return hr != S_OK to prevent accessing a symbol server - { - LIMITED_METHOD_CONTRACT; - return S_OK; - } - - HRESULT STDMETHODCALLTYPE RestrictDBGAccess() - { - LIMITED_METHOD_CONTRACT; - return S_OK; - } -}; - -////////////////////////////////////////////////////////////////// - -bool SourceLine::LoadDataFromPdb( _In_z_ LPWSTR wszFilename ) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_ANY; - } CONTRACTL_END; - - HRESULT hResult; - -// CComPtr(IDiaDataSource) pDataSource; - - hResult = CoInitialize(NULL); - - if (FAILED(hResult)){ - return FALSE; - } - - // Obtain Access To The Provider - hResult = CoCreateInstance(CLSID_DiaSource, - NULL, - CLSCTX_INPROC_SERVER, - IID_IDiaDataSource, - (void **) &pSource_); - - if (FAILED(hResult)){ - return FALSE; - } - - CCallback callback; - callback.AddRef(); - - if ( FAILED( pSource_->loadDataFromPdb( wszFilename ) ) - && FAILED( pSource_->loadDataForExe( wszFilename, W("symsrv*symsrv.dll*\\\\symbols\\\\symbols"), &callback ) ) ) - return FALSE; - if ( FAILED( pSource_->openSession(&pSession_) ) ) - return FALSE; - if ( FAILED( pSession_->get_globalScope(&pGlobal_) ) ) - return FALSE; - - return TRUE; -} - -////////////////////////////////////////////////////////////////// - -SourceLine::SourceLine( _In_z_ LPWSTR pszFileName ) -{ - WRAPPER_NO_CONTRACT; - if (LoadDataFromPdb(pszFileName)) { - initialized_ = true; - } - else{ - initialized_ = false; - } -} - -////////////////////////////////////////////////////////////////// - -HRESULT SourceLine::GetSourceLine( DWORD dwFunctionToken, DWORD dwOffset, _Out_writes_z_(dwFileNameMaxLen) LPWSTR pszFileName, DWORD dwFileNameMaxLen, PDWORD pdwLineNumber ) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_ANY; - } CONTRACTL_END; - - _ASSERTE(initialized_); - - CComPtr(IDiaSymbol) pSymbol; - HRESULT hResult = pSession_->findSymbolByToken(dwFunctionToken, SymTagFunction, &pSymbol); - - if( SUCCEEDED(hResult) && pSymbol != NULL) { - - ULONGLONG length; - pSymbol->get_length(&length); - - DWORD rva; - CComPtr(IDiaEnumLineNumbers) pLines; - - if(SUCCEEDED(pSymbol->get_relativeVirtualAddress(&rva))) { - - DWORD initialOffset; - pSymbol->get_addressOffset(&initialOffset); - - DWORD isect; - pSymbol->get_addressSection(&isect); - - hResult = pSession_->findLinesByAddr(isect, initialOffset+dwOffset, 1, &pLines); - if( SUCCEEDED(hResult) ){ - - CComPtr(IDiaLineNumber) pLine; - - hResult = pLines->Item( 0, &pLine ); - - if(SUCCEEDED(hResult)){ - - pLine->get_lineNumber(pdwLineNumber); - - CComPtr(IDiaSourceFile) pSourceFile; - pLine->get_sourceFile( &pSourceFile ); - - BSTR sourceName; - pSourceFile->get_fileName( &sourceName ); - - wcsncpy_s( pszFileName, dwFileNameMaxLen, sourceName, dwFileNameMaxLen ); - } - } - } - } - - return hResult; -} - -////////////////////////////////////////////////////////////////// - -HRESULT SourceLine::GetLocalName( DWORD dwFunctionToken, DWORD dwSlot, _Out_writes_z_(dwNameMaxLen) LPWSTR pszName, DWORD dwNameMaxLen ) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_ANY; - } CONTRACTL_END; - - CComPtr(IDiaSymbol) pSymbol; - HRESULT hResult = pSession_->findSymbolByToken(dwFunctionToken, SymTagFunction, &pSymbol); - - if( SUCCEEDED(hResult) && pSymbol != NULL ) { - - ULONGLONG length; - pSymbol->get_length(&length); - - DWORD rva; -// CComPtr(IDiaEnumLineNumbers) pLines; - - hResult = pSymbol->get_relativeVirtualAddress(&rva); - - if(SUCCEEDED(hResult)) { - - CComPtr( IDiaSymbol ) pBlock; - hResult = pSession_->findSymbolByRVA( rva, SymTagBlock, &pBlock ); - - if( SUCCEEDED(hResult) && pBlock != NULL ) { - - ULONG celt = 0; - - CComPtr(IDiaSymbol) pLocalSymbol = NULL; - CComPtr( IDiaEnumSymbols ) pEnum; - hResult = pBlock->findChildren( SymTagData, NULL, nsNone, &pEnum ); - - if( SUCCEEDED(hResult) ) { - - // - // Find function local by slot - // - while (SUCCEEDED(hResult = pEnum->Next(1, &pLocalSymbol, &celt)) && celt == 1) { - - DWORD dwThisSlot; - pLocalSymbol->get_slot( &dwThisSlot ); - - if( dwThisSlot == dwSlot ) { - - BSTR name = NULL; - hResult = pLocalSymbol->get_name(&name); - - wcsncpy_s( pszName, dwNameMaxLen, name, _TRUNCATE ); - - return S_OK; - } - - pLocalSymbol = 0; - } - } - } - } - } - - return hResult; -} - -#else // !ENABLE_DIAGNOSTIC_SYMBOL_READING -SourceLine::SourceLine( _In_z_ LPWSTR pszFileName ) -{ - LIMITED_METHOD_CONTRACT; - initialized_ = false; -} - -HRESULT SourceLine::GetSourceLine( DWORD dwFunctionToken, DWORD dwOffset, _Out_writes_z_(dwFileNameMaxLen) LPWSTR pszFileName, DWORD dwFileNameMaxLen, PDWORD pdwLineNumber ) -{ - LIMITED_METHOD_CONTRACT; - return E_NOTIMPL; -} - -HRESULT SourceLine::GetLocalName( DWORD dwFunctionToken, DWORD dwSlot, _Out_writes_z_(dwNameMaxLen) LPWSTR pszName, DWORD dwNameMaxLen ) -{ - LIMITED_METHOD_CONTRACT; - return E_NOTIMPL; -} -#endif // ENABLE_DIAGNOSTIC_SYMBOL_READING - diff --git a/src/coreclr/vm/sourceline.h b/src/coreclr/vm/sourceline.h deleted file mode 100644 index 3c241d4328a00b..00000000000000 --- a/src/coreclr/vm/sourceline.h +++ /dev/null @@ -1,43 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - - - -#ifndef __SOURCELINE_H__ -#define __SOURCELINE_H__ - -#ifdef ENABLE_DIAGNOSTIC_SYMBOL_READING -#include "dia2.h" -#endif // ENABLE_DIAGNOSTIC_SYMBOL_READING - -#define CComPtr(x) x* - -class SourceLine -{ - bool initialized_; - -#ifdef ENABLE_DIAGNOSTIC_SYMBOL_READING - CComPtr(IDiaDataSource) pSource_; - CComPtr(IDiaSymbol) pGlobal_; - CComPtr(IDiaSession) pSession_; - - bool LoadDataFromPdb( _In_z_ LPWSTR wszFilename ); -#endif // ENABLE_DIAGNOSTIC_SYMBOL_READING - -public: - SourceLine( _In_z_ LPWSTR pszFileName ); - - bool IsInitialized() { return initialized_; } - - // - // Given function token (methoddef) and offset, return filename and line number - // - HRESULT GetSourceLine( DWORD dwFunctionToken, DWORD dwOffset, _Out_writes_z_(dwFileNameMaxLen) LPWSTR wszFileName, DWORD dwFileNameMaxLen, PDWORD pdwLineNumber ); - - // - // Given function token (methoddef) and slot, return name of the local variable - // - HRESULT GetLocalName( DWORD dwFunctionToken, DWORD dwSlot, _Out_writes_z_(dwNameMaxLen) LPWSTR wszName, DWORD dwNameMaxLen ); -}; - -#endif // __SOURCELINE_H__ diff --git a/src/coreclr/vm/stackcontents.h b/src/coreclr/vm/stackcontents.h deleted file mode 100644 index fb11aa0bda8c9e..00000000000000 --- a/src/coreclr/vm/stackcontents.h +++ /dev/null @@ -1,124 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#ifndef __STACKCONTENTS_H__ -#define __STACKCONTENTS_H__ - -#ifdef FEATURE_PERFTRACING -#include "common.h" - -class MethodDesc; - -class StackContents -{ -private: - const static unsigned int MAX_STACK_DEPTH = 100; - - // Array of IP values from a stack crawl. - // Top of stack is at index 0. - UINT_PTR m_stackFrames[MAX_STACK_DEPTH]; - -#ifdef _DEBUG - // Parallel array of MethodDesc pointers. - // Used for debug-only stack printing. - MethodDesc *m_methods[MAX_STACK_DEPTH]; -#endif // _DEBUG - - // The next available slot in StackFrames. - unsigned int m_nextAvailableFrame; - -public: - StackContents() - { - LIMITED_METHOD_CONTRACT; - Reset(); - } - - void CopyTo(StackContents *pDest) - { - LIMITED_METHOD_CONTRACT; - _ASSERTE(pDest != NULL); - - memcpy_s(pDest->m_stackFrames, MAX_STACK_DEPTH * sizeof(UINT_PTR), m_stackFrames, sizeof(UINT_PTR) * m_nextAvailableFrame); -#ifdef _DEBUG - memcpy_s(pDest->m_methods, MAX_STACK_DEPTH * sizeof(MethodDesc *), m_methods, sizeof(MethodDesc *) * m_nextAvailableFrame); -#endif - pDest->m_nextAvailableFrame = m_nextAvailableFrame; - } - - void Reset() - { - LIMITED_METHOD_CONTRACT; - m_nextAvailableFrame = 0; - } - - bool IsEmpty() - { - LIMITED_METHOD_CONTRACT; - return (m_nextAvailableFrame == 0); - } - - unsigned int GetLength() - { - LIMITED_METHOD_CONTRACT; - return m_nextAvailableFrame; - } - - UINT_PTR GetIP(unsigned int frameIndex) - { - LIMITED_METHOD_CONTRACT; - _ASSERTE(frameIndex < MAX_STACK_DEPTH); - - if (frameIndex >= MAX_STACK_DEPTH) - { - return 0; - } - - return m_stackFrames[frameIndex]; - } - -#ifdef _DEBUG - MethodDesc *GetMethod(unsigned int frameIndex) - { - LIMITED_METHOD_CONTRACT; - _ASSERTE(frameIndex < MAX_STACK_DEPTH); - - if (frameIndex >= MAX_STACK_DEPTH) - { - return NULL; - } - - return m_methods[frameIndex]; - } -#endif // _DEBUG - - void Append(UINT_PTR controlPC, MethodDesc *pMethod) - { - LIMITED_METHOD_CONTRACT; - - if (m_nextAvailableFrame < MAX_STACK_DEPTH) - { - m_stackFrames[m_nextAvailableFrame] = controlPC; -#ifdef _DEBUG - m_methods[m_nextAvailableFrame] = pMethod; -#endif - m_nextAvailableFrame++; - } - } - - BYTE *GetPointer() const - { - LIMITED_METHOD_CONTRACT; - return (BYTE *)m_stackFrames; - } - - unsigned int GetSize() const - { - LIMITED_METHOD_CONTRACT; - return (m_nextAvailableFrame * sizeof(UINT_PTR)); - } -}; - -#endif // FEATURE_PERFTRACING - -#endif // __STACKCONTENTS_H__ diff --git a/src/coreclr/vm/stdinterfaces.cpp b/src/coreclr/vm/stdinterfaces.cpp index 37a52675a2ad44..a5a70e6ee1c21c 100644 --- a/src/coreclr/vm/stdinterfaces.cpp +++ b/src/coreclr/vm/stdinterfaces.cpp @@ -32,7 +32,7 @@ #include "posterror.h" #include #include -#include "mtx.h" +#include #include "cgencpu.h" #include "interopconverter.h" #include "cominterfacemarshaler.h" diff --git a/src/coreclr/vm/stdinterfaces_wrapper.cpp b/src/coreclr/vm/stdinterfaces_wrapper.cpp index 751870479d9e38..116467b8c7f3df 100644 --- a/src/coreclr/vm/stdinterfaces_wrapper.cpp +++ b/src/coreclr/vm/stdinterfaces_wrapper.cpp @@ -31,7 +31,7 @@ #include "posterror.h" #include #include -#include "mtx.h" +#include #include "cgencpu.h" #include "interopconverter.h" #include "cominterfacemarshaler.h" From 67ee1b30c5b171a246da877fd36ccbfc05958e4f Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Mon, 13 Jun 2022 09:27:15 -0500 Subject: [PATCH 079/337] Enable HMAC on Browser WASM (#70442) * Enable HMAC on Browser WASM This ports the C# implementation of HMAC from https://github.com/microsoft/referencesource/blob/5697c29004a34d80acdaf5742d7e699022c64ecd/mscorlib/system/security/cryptography/hmac.cs, marks the APIs as supported on Browser, and enables HMAC tests on Browser WASM. Contributes to #40074 * Clear the key in Dispose. Use Array.Clear(Array). * PR feedback * Fix tests - remove "HMAC" crypto name since no other platform supports this name. --- .../ref/System.Security.Cryptography.cs | 6 - .../src/System.Security.Cryptography.csproj | 1 + .../Security/Cryptography/CryptoConfig.cs | 17 ++- .../HMACHashProvider.Browser.Managed.cs | 130 ++++++++++++++++++ .../System/Security/Cryptography/HMACSHA1.cs | 1 - .../Security/Cryptography/HMACSHA256.cs | 1 - .../Security/Cryptography/HMACSHA384.cs | 1 - .../Security/Cryptography/HMACSHA512.cs | 1 - .../HashProviderDispenser.Browser.cs | 14 +- .../Security/Cryptography/IncrementalHash.cs | 2 - .../tests/BlockSizeValueTests.cs | 2 +- .../tests/CryptoConfigTests.cs | 24 ++-- .../tests/HmacSha1Tests.cs | 1 - .../tests/HmacSha256Tests.cs | 1 - .../tests/HmacSha384Tests.cs | 1 - .../tests/HmacSha512Tests.cs | 1 - .../tests/HmacTests.cs | 1 - .../tests/IncrementalHashTests.cs | 29 +--- .../tests/InvalidUsageTests.cs | 1 - .../tests/ReusabilityTests.cs | 24 ++-- .../tests/Rfc2202HmacTests.cs | 1 - .../tests/Rfc4231HmacTests.cs | 1 - ...iCompatBaseline.NetCoreAppLatestStable.txt | 20 ++- 23 files changed, 211 insertions(+), 70 deletions(-) create mode 100644 src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACHashProvider.Browser.Managed.cs diff --git a/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs b/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs index 46fdda605813ad..a5388a51c050c9 100644 --- a/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs +++ b/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs @@ -1352,7 +1352,6 @@ public override void Initialize() { } public static bool TryHashData(System.ReadOnlySpan key, System.ReadOnlySpan source, System.Span destination, out int bytesWritten) { throw null; } protected override bool TryHashFinal(System.Span destination, out int bytesWritten) { throw null; } } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public partial class HMACSHA1 : System.Security.Cryptography.HMAC { public const int HashSizeInBits = 160; @@ -1380,7 +1379,6 @@ public override void Initialize() { } public static bool TryHashData(System.ReadOnlySpan key, System.ReadOnlySpan source, System.Span destination, out int bytesWritten) { throw null; } protected override bool TryHashFinal(System.Span destination, out int bytesWritten) { throw null; } } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public partial class HMACSHA256 : System.Security.Cryptography.HMAC { public const int HashSizeInBits = 256; @@ -1405,7 +1403,6 @@ public override void Initialize() { } public static bool TryHashData(System.ReadOnlySpan key, System.ReadOnlySpan source, System.Span destination, out int bytesWritten) { throw null; } protected override bool TryHashFinal(System.Span destination, out int bytesWritten) { throw null; } } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public partial class HMACSHA384 : System.Security.Cryptography.HMAC { public const int HashSizeInBits = 384; @@ -1432,7 +1429,6 @@ public override void Initialize() { } public static bool TryHashData(System.ReadOnlySpan key, System.ReadOnlySpan source, System.Span destination, out int bytesWritten) { throw null; } protected override bool TryHashFinal(System.Span destination, out int bytesWritten) { throw null; } } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public partial class HMACSHA512 : System.Security.Cryptography.HMAC { public const int HashSizeInBits = 512; @@ -1483,9 +1479,7 @@ public void AppendData(byte[] data) { } public void AppendData(byte[] data, int offset, int count) { } public void AppendData(System.ReadOnlySpan data) { } public static System.Security.Cryptography.IncrementalHash CreateHash(System.Security.Cryptography.HashAlgorithmName hashAlgorithm) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public static System.Security.Cryptography.IncrementalHash CreateHMAC(System.Security.Cryptography.HashAlgorithmName hashAlgorithm, byte[] key) { throw null; } - [System.Runtime.Versioning.UnsupportedOSPlatformAttribute("browser")] public static System.Security.Cryptography.IncrementalHash CreateHMAC(System.Security.Cryptography.HashAlgorithmName hashAlgorithm, System.ReadOnlySpan key) { throw null; } public void Dispose() { } public byte[] GetCurrentHash() { throw null; } diff --git a/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj b/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj index 613ed623013534..dfb550ae2ff15c 100644 --- a/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj +++ b/src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj @@ -558,6 +558,7 @@ + diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CryptoConfig.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CryptoConfig.cs index 8bcf3796e0b9a7..b83099020a90b2 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CryptoConfig.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/CryptoConfig.cs @@ -338,7 +338,7 @@ public static void AddAlgorithm(Type algorithm, params string[] names) switch (name) { #pragma warning disable SYSLIB0021 // Obsolete: derived cryptographic types - // hardcode mapping for SHA* algorithm names from https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.cryptoconfig?view=net-5.0#remarks + // hardcode mapping for SHA* and HMAC* algorithm names from https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.cryptoconfig?view=net-5.0#remarks case "SHA": case "SHA1": case "System.Security.Cryptography.SHA1": @@ -356,6 +356,21 @@ public static void AddAlgorithm(Type algorithm, params string[] names) case "System.Security.Cryptography.SHA512": return new SHA512Managed(); #pragma warning restore SYSLIB0021 + + case "System.Security.Cryptography.HMAC": + case "HMACSHA1": + case "System.Security.Cryptography.HMACSHA1": + case "System.Security.Cryptography.KeyedHashAlgorithm": + return new HMACSHA1(); + case "HMACSHA256": + case "System.Security.Cryptography.HMACSHA256": + return new HMACSHA256(); + case "HMACSHA384": + case "System.Security.Cryptography.HMACSHA384": + return new HMACSHA384(); + case "HMACSHA512": + case "System.Security.Cryptography.HMACSHA512": + return new HMACSHA512(); } return null; diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACHashProvider.Browser.Managed.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACHashProvider.Browser.Managed.cs new file mode 100644 index 00000000000000..a1476be591cf90 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACHashProvider.Browser.Managed.cs @@ -0,0 +1,130 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; + +namespace System.Security.Cryptography +{ + // ported from https://github.com/microsoft/referencesource/blob/5697c29004a34d80acdaf5742d7e699022c64ecd/mscorlib/system/security/cryptography/hmac.cs + internal sealed class HMACManagedHashProvider : HashProvider + { + private bool _hashing; + private readonly int _blockSizeValue; + private readonly int _hashSizeValue; + + private readonly byte[] _key; + private readonly HashProvider _hash1; + private readonly HashProvider _hash2; + + public HMACManagedHashProvider(string hashAlgorithmId, ReadOnlySpan key) + { + _hash1 = HashProviderDispenser.CreateHashProvider(hashAlgorithmId); + _hash2 = HashProviderDispenser.CreateHashProvider(hashAlgorithmId); + + (_blockSizeValue, _hashSizeValue) = hashAlgorithmId switch + { + HashAlgorithmNames.SHA1 => (64, 160 / 8), + HashAlgorithmNames.SHA256 => (64, 256 / 8), + HashAlgorithmNames.SHA384 => (128, 384 / 8), + HashAlgorithmNames.SHA512 => (128, 512 / 8), + _ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId)), + }; + + _key = InitializeKey(key); + } + + private byte[] InitializeKey(ReadOnlySpan key) + { + if (key.Length > _blockSizeValue) + { + byte[] result = new byte[_hashSizeValue]; + _hash1.AppendHashData(key); + int written = _hash1.FinalizeHashAndReset(result); + Debug.Assert(written == result.Length); + + return result; + } + + return key.ToArray(); + } + + public override void AppendHashData(ReadOnlySpan data) + { + if (!_hashing) + { + AppendInnerBuffer(); + _hashing = true; + } + + _hash1.AppendHashData(data); + } + + public override int FinalizeHashAndReset(Span destination) + { + int written = GetCurrentHash(destination); + Reset(); + return written; + } + + public override int GetCurrentHash(Span destination) + { + if (!_hashing) + { + AppendInnerBuffer(); + _hashing = true; + } + + // finalize the original hash + Span hashValue1 = stackalloc byte[_hashSizeValue]; + int hash1Written = _hash1.GetCurrentHash(hashValue1); + Debug.Assert(hash1Written == hashValue1.Length); + + // write the outer array + AppendOuterBuffer(); + // write the inner hash and finalize the hash + _hash2.AppendHashData(hashValue1); + return _hash2.FinalizeHashAndReset(destination); + } + + private void AppendInnerBuffer() => AppendPaddingBuffer(0x36, _hash1); + private void AppendOuterBuffer() => AppendPaddingBuffer(0x5C, _hash2); + + private void AppendPaddingBuffer(byte paddingConstant, HashProvider hash) + { + Span paddingBuffer = stackalloc byte[_blockSizeValue]; + paddingBuffer.Fill(paddingConstant); + + for (int i = 0; i < _key.Length; i++) + { + paddingBuffer[i] ^= _key[i]; + } + + hash.AppendHashData(paddingBuffer); + CryptographicOperations.ZeroMemory(paddingBuffer); + } + + public override int HashSizeInBytes => _hashSizeValue; + + public override void Dispose(bool disposing) + { + if (disposing) + { + _hash1.Dispose(); + _hash2.Dispose(); + + CryptographicOperations.ZeroMemory(_key); + } + } + + public override void Reset() + { + if (_hashing) + { + _hash1.Reset(); + _hash2.Reset(); + _hashing = false; + } + } + } +} diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA1.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA1.cs index 80f9a95fb47958..955501b54f44a4 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA1.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA1.cs @@ -16,7 +16,6 @@ namespace System.Security.Cryptography // preexisting contract from the .NET Framework locks all of these into deriving directly from HMAC, it can't be helped. // - [UnsupportedOSPlatform("browser")] public class HMACSHA1 : HMAC { /// diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA256.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA256.cs index 0e1348eefba1e3..2c604c1a823093 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA256.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA256.cs @@ -15,7 +15,6 @@ namespace System.Security.Cryptography // preexisting contract from the .NET Framework locks all of these into deriving directly from HMAC, it can't be helped. // - [UnsupportedOSPlatform("browser")] public class HMACSHA256 : HMAC { /// diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA384.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA384.cs index e7b54ee4868dbb..63e95908b3059a 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA384.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA384.cs @@ -15,7 +15,6 @@ namespace System.Security.Cryptography // preexisting contract from the .NET Framework locks all of these into deriving directly from HMAC, it can't be helped. // - [UnsupportedOSPlatform("browser")] public class HMACSHA384 : HMAC { /// diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA512.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA512.cs index e280573f94fece..7b0a4aad365f18 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA512.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACSHA512.cs @@ -15,7 +15,6 @@ namespace System.Security.Cryptography // preexisting contract from the .NET Framework locks all of these into deriving directly from HMAC, it can't be helped. // - [UnsupportedOSPlatform("browser")] public class HMACSHA512 : HMAC { /// diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Browser.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Browser.cs index 031d28ffea2ef4..e6c394d6220b48 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Browser.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Browser.cs @@ -32,7 +32,9 @@ public static unsafe int MacData( ReadOnlySpan source, Span destination) { - throw new PlatformNotSupportedException(SR.SystemSecurityCryptography_PlatformNotSupported); + HashProvider provider = CreateMacProvider(hashAlgorithmId, key); + provider.AppendHashData(source); + return provider.FinalizeHashAndReset(destination); } public static int HashData(string hashAlgorithmId, ReadOnlySpan source, Span destination) @@ -45,7 +47,15 @@ public static int HashData(string hashAlgorithmId, ReadOnlySpan source, Sp public static unsafe HashProvider CreateMacProvider(string hashAlgorithmId, ReadOnlySpan key) { - throw new PlatformNotSupportedException(SR.SystemSecurityCryptography_PlatformNotSupported); + switch (hashAlgorithmId) + { + case HashAlgorithmNames.SHA1: + case HashAlgorithmNames.SHA256: + case HashAlgorithmNames.SHA384: + case HashAlgorithmNames.SHA512: + return new HMACManagedHashProvider(hashAlgorithmId, key); + } + throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId)); } } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/IncrementalHash.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/IncrementalHash.cs index 8ee41347893ba0..16334ad36976a7 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/IncrementalHash.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/IncrementalHash.cs @@ -345,7 +345,6 @@ public static IncrementalHash CreateHash(HashAlgorithmName hashAlgorithm) /// the empty string. /// /// is not a known hash algorithm. - [UnsupportedOSPlatform("browser")] public static IncrementalHash CreateHMAC(HashAlgorithmName hashAlgorithm, byte[] key) { ArgumentNullException.ThrowIfNull(key); @@ -375,7 +374,6 @@ public static IncrementalHash CreateHMAC(HashAlgorithmName hashAlgorithm, byte[] /// the empty string. /// /// is not a known hash algorithm. - [UnsupportedOSPlatform("browser")] public static IncrementalHash CreateHMAC(HashAlgorithmName hashAlgorithm, ReadOnlySpan key) { ArgumentException.ThrowIfNullOrEmpty(hashAlgorithm.Name, nameof(hashAlgorithm)); diff --git a/src/libraries/System.Security.Cryptography/tests/BlockSizeValueTests.cs b/src/libraries/System.Security.Cryptography/tests/BlockSizeValueTests.cs index 2ea65c6d32951d..c6ada15004ab58 100644 --- a/src/libraries/System.Security.Cryptography/tests/BlockSizeValueTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/BlockSizeValueTests.cs @@ -5,10 +5,10 @@ namespace System.Security.Cryptography.Tests { - [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] public class BlockSizeValueTests { [Fact] + [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] public static void BlockSizeValueTest_HMACMD5() { int hmacBlockSizeValue = new HMACMD5Test().GetBlockSizeValue(); diff --git a/src/libraries/System.Security.Cryptography/tests/CryptoConfigTests.cs b/src/libraries/System.Security.Cryptography/tests/CryptoConfigTests.cs index 3ccc914ffb7825..271dfdf49ce542 100644 --- a/src/libraries/System.Security.Cryptography/tests/CryptoConfigTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/CryptoConfigTests.cs @@ -342,6 +342,18 @@ public static IEnumerable AllValidNames { get { + // Keyed Hash Algorithms - supported on all platforms + yield return new object[] { "System.Security.Cryptography.HMAC", "System.Security.Cryptography.HMACSHA1", true }; + yield return new object[] { "System.Security.Cryptography.KeyedHashAlgorithm", "System.Security.Cryptography.HMACSHA1", true }; + yield return new object[] { "HMACSHA1", "System.Security.Cryptography.HMACSHA1", true }; + yield return new object[] { "System.Security.Cryptography.HMACSHA1", null, true }; + yield return new object[] { "HMACSHA256", "System.Security.Cryptography.HMACSHA256", true }; + yield return new object[] { "System.Security.Cryptography.HMACSHA256", null, true }; + yield return new object[] { "HMACSHA384", "System.Security.Cryptography.HMACSHA384", true }; + yield return new object[] { "System.Security.Cryptography.HMACSHA384", null, true }; + yield return new object[] { "HMACSHA512", "System.Security.Cryptography.HMACSHA512", true }; + yield return new object[] { "System.Security.Cryptography.HMACSHA512", null, true }; + if (PlatformDetection.IsBrowser) { // Hash functions @@ -381,19 +393,9 @@ public static IEnumerable AllValidNames yield return new object[] { "SHA-512", typeof(SHA512Managed).FullName, true }; yield return new object[] { "System.Security.Cryptography.SHA512", typeof(SHA512Managed).FullName, true }; - // Keyed Hash Algorithms - yield return new object[] { "System.Security.Cryptography.HMAC", "System.Security.Cryptography.HMACSHA1", true }; - yield return new object[] { "System.Security.Cryptography.KeyedHashAlgorithm", "System.Security.Cryptography.HMACSHA1", true }; + // Keyed Hash Algorithms - not supported on Browser yield return new object[] { "HMACMD5", "System.Security.Cryptography.HMACMD5", true }; yield return new object[] { "System.Security.Cryptography.HMACMD5", null, true }; - yield return new object[] { "HMACSHA1", "System.Security.Cryptography.HMACSHA1", true }; - yield return new object[] { "System.Security.Cryptography.HMACSHA1", null, true }; - yield return new object[] { "HMACSHA256", "System.Security.Cryptography.HMACSHA256", true }; - yield return new object[] { "System.Security.Cryptography.HMACSHA256", null, true }; - yield return new object[] { "HMACSHA384", "System.Security.Cryptography.HMACSHA384", true }; - yield return new object[] { "System.Security.Cryptography.HMACSHA384", null, true }; - yield return new object[] { "HMACSHA512", "System.Security.Cryptography.HMACSHA512", true }; - yield return new object[] { "System.Security.Cryptography.HMACSHA512", null, true }; // Asymmetric algorithms yield return new object[] { "RSA", "System.Security.Cryptography.RSACryptoServiceProvider", true }; diff --git a/src/libraries/System.Security.Cryptography/tests/HmacSha1Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacSha1Tests.cs index d618b7122a32d3..4ae956c90f7a28 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacSha1Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacSha1Tests.cs @@ -9,7 +9,6 @@ namespace System.Security.Cryptography.Tests { - [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] public class HmacSha1Tests : Rfc2202HmacTests { private static readonly byte[][] s_testKeys2202 = diff --git a/src/libraries/System.Security.Cryptography/tests/HmacSha256Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacSha256Tests.cs index 587711a920ad27..e0f43489931174 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacSha256Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacSha256Tests.cs @@ -9,7 +9,6 @@ namespace System.Security.Cryptography.Tests { - [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] public class HmacSha256Tests : Rfc4231HmacTests { protected override int BlockSize => 64; diff --git a/src/libraries/System.Security.Cryptography/tests/HmacSha384Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacSha384Tests.cs index eb3bbf5681e8b8..deb23962cbe51e 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacSha384Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacSha384Tests.cs @@ -9,7 +9,6 @@ namespace System.Security.Cryptography.Tests { - [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] public class HmacSha384Tests : Rfc4231HmacTests { protected override int BlockSize => 128; diff --git a/src/libraries/System.Security.Cryptography/tests/HmacSha512Tests.cs b/src/libraries/System.Security.Cryptography/tests/HmacSha512Tests.cs index 7172d68d43dfe7..8c9f0271bd8283 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacSha512Tests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacSha512Tests.cs @@ -9,7 +9,6 @@ namespace System.Security.Cryptography.Tests { - [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] public class HmacSha512Tests : Rfc4231HmacTests { protected override int BlockSize => 128; diff --git a/src/libraries/System.Security.Cryptography/tests/HmacTests.cs b/src/libraries/System.Security.Cryptography/tests/HmacTests.cs index 9083a9fd15e7b5..3590ab90c50441 100644 --- a/src/libraries/System.Security.Cryptography/tests/HmacTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/HmacTests.cs @@ -9,7 +9,6 @@ namespace System.Security.Cryptography.Tests { - [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] public abstract class HmacTests { // RFC2202 defines the test vectors for HMACMD5 and HMACSHA1 diff --git a/src/libraries/System.Security.Cryptography/tests/IncrementalHashTests.cs b/src/libraries/System.Security.Cryptography/tests/IncrementalHashTests.cs index e1a31bd49dc935..400b8aa57834c0 100644 --- a/src/libraries/System.Security.Cryptography/tests/IncrementalHashTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/IncrementalHashTests.cs @@ -29,14 +29,14 @@ public static IEnumerable GetHashAlgorithms() public static IEnumerable GetHMACs() { - return new[] + if (!PlatformDetection.IsBrowser) { - new object[] { new HMACMD5(), HashAlgorithmName.MD5 }, - new object[] { new HMACSHA1(), HashAlgorithmName.SHA1 }, - new object[] { new HMACSHA256(), HashAlgorithmName.SHA256 }, - new object[] { new HMACSHA384(), HashAlgorithmName.SHA384 }, - new object[] { new HMACSHA512(), HashAlgorithmName.SHA512 }, - }; + yield return new object[] { new HMACMD5(), HashAlgorithmName.MD5 }; + } + yield return new object[] { new HMACSHA1(), HashAlgorithmName.SHA1 }; + yield return new object[] { new HMACSHA256(), HashAlgorithmName.SHA256 }; + yield return new object[] { new HMACSHA384(), HashAlgorithmName.SHA384 }; + yield return new object[] { new HMACSHA512(), HashAlgorithmName.SHA512 }; } [Fact] @@ -81,7 +81,6 @@ public static void VerifyIncrementalHash(HashAlgorithm referenceAlgorithm, HashA } [Theory] - [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] [MemberData(nameof(GetHMACs))] public static void VerifyIncrementalHMAC(HMAC referenceAlgorithm, HashAlgorithmName hashAlgorithm) { @@ -95,7 +94,6 @@ public static void VerifyIncrementalHMAC(HMAC referenceAlgorithm, HashAlgorithmN } [Theory] - [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] [MemberData(nameof(GetHMACs))] public static void VerifyIncrementalHMAC_SpanKey(HMAC referenceAlgorithm, HashAlgorithmName hashAlgorithm) { @@ -162,7 +160,6 @@ public static void VerifyEmptyHash(HashAlgorithm referenceAlgorithm, HashAlgorit } [Theory] - [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] [MemberData(nameof(GetHMACs))] public static void VerifyEmptyHMAC(HMAC referenceAlgorithm, HashAlgorithmName hashAlgorithm) { @@ -198,7 +195,6 @@ public static void VerifyTrivialHash(HashAlgorithm referenceAlgorithm, HashAlgor } [Theory] - [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] [MemberData(nameof(GetHMACs))] public static void VerifyTrivialHMAC(HMAC referenceAlgorithm, HashAlgorithmName hashAlgorithm) { @@ -229,7 +225,6 @@ public static void AppendDataAfterHashClose() } [Fact] - [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] public static void AppendDataAfterHMACClose() { using (IncrementalHash hash = IncrementalHash.CreateHMAC(HashAlgorithmName.SHA256, s_hmacKey)) @@ -256,7 +251,6 @@ public static void GetHashTwice() } [Fact] - [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] public static void GetHMACTwice() { using (IncrementalHash hash = IncrementalHash.CreateHMAC(HashAlgorithmName.SHA256, s_hmacKey)) @@ -280,7 +274,6 @@ public static void ModifyAfterHashDispose() } [Fact] - [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] public static void ModifyAfterHMACDispose() { using (IncrementalHash hash = IncrementalHash.CreateHMAC(HashAlgorithmName.SHA256, s_hmacKey)) @@ -299,7 +292,6 @@ public static void UnknownDigestAlgorithm() } [Fact] - [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] public static void UnknownHmacAlgorithm() { Assert.ThrowsAny( @@ -318,7 +310,6 @@ public static void VerifyIncrementalHash_Span(HashAlgorithm referenceAlgorithm, } [Theory] - [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] [MemberData(nameof(GetHMACs))] public static void VerifyIncrementalHMAC_Span(HMAC referenceAlgorithm, HashAlgorithmName hashAlgorithm) { @@ -395,7 +386,6 @@ public static void VerifyEmptyHash_Span(HashAlgorithm referenceAlgorithm, HashAl } [Theory] - [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] [MemberData(nameof(GetHMACs))] public static void VerifyEmptyHMAC_Span(HMAC referenceAlgorithm, HashAlgorithmName hashAlgorithm) { @@ -433,7 +423,6 @@ public static void VerifyTrivialHash_Span(HashAlgorithm referenceAlgorithm, Hash } [Theory] - [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] [MemberData(nameof(GetHMACs))] public static void VerifyTrivialHMAC_Span(HMAC referenceAlgorithm, HashAlgorithmName hashAlgorithm) { @@ -474,7 +463,6 @@ public static void Dispose_HashAlgorithm_ThrowsException(HashAlgorithm reference } [Theory] - [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] [MemberData(nameof(GetHMACs))] public static void Dispose_HMAC_ThrowsException(HMAC referenceAlgorithm, HashAlgorithmName hashAlgorithm) { @@ -511,7 +499,6 @@ public static void VerifyGetCurrentHash_Digest(HashAlgorithm referenceAlgorithm, } [Theory] - [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] [SkipOnPlatform(TestPlatforms.Android, "Android doesn't support cloning the current state for HMAC, so it doesn't support GetCurrentHash.")] [MemberData(nameof(GetHMACs))] public static void VerifyGetCurrentHash_HMAC(HMAC referenceAlgorithm, HashAlgorithmName hashAlgorithm) @@ -526,7 +513,6 @@ public static void VerifyGetCurrentHash_HMAC(HMAC referenceAlgorithm, HashAlgori } [Theory] - [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] [SkipOnPlatform(TestPlatforms.Android, "Android doesn't support cloning the current state for HMAC, so it doesn't support GetCurrentHash.")] [MemberData(nameof(GetHMACs))] public static void VerifyBounds_GetCurrentHash_HMAC(HMAC referenceAlgorithm, HashAlgorithmName hashAlgorithm) @@ -548,7 +534,6 @@ public static void VerifyBounds_GetCurrentHash_HMAC(HMAC referenceAlgorithm, Has } [Theory] - [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] [MemberData(nameof(GetHMACs))] public static void VerifyBounds_GetHashAndReset_HMAC(HMAC referenceAlgorithm, HashAlgorithmName hashAlgorithm) { diff --git a/src/libraries/System.Security.Cryptography/tests/InvalidUsageTests.cs b/src/libraries/System.Security.Cryptography/tests/InvalidUsageTests.cs index 4114d97167e952..e37aeef839ff26 100644 --- a/src/libraries/System.Security.Cryptography/tests/InvalidUsageTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/InvalidUsageTests.cs @@ -9,7 +9,6 @@ namespace System.Security.Cryptography.Tests public class InvalidUsageTests { [Fact] - [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] public void InvalidHashCoreArgumentsFromDerivedType() { using (var hmac = new DerivedHMACSHA1()) diff --git a/src/libraries/System.Security.Cryptography/tests/ReusabilityTests.cs b/src/libraries/System.Security.Cryptography/tests/ReusabilityTests.cs index 998890765df40a..29571d3beb812b 100644 --- a/src/libraries/System.Security.Cryptography/tests/ReusabilityTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/ReusabilityTests.cs @@ -6,7 +6,6 @@ namespace System.Security.Cryptography.Tests { - [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] public class ReusabilityTests { [Theory] @@ -25,18 +24,19 @@ public void TestReusability(HashAlgorithm hashAlgorithm) public static IEnumerable ReusabilityHashAlgorithms() { - return new[] + if (!PlatformDetection.IsBrowser) { - new object[] { MD5.Create(), }, - new object[] { SHA1.Create(), }, - new object[] { SHA256.Create(), }, - new object[] { SHA384.Create(), }, - new object[] { SHA512.Create(), }, - new object[] { new HMACSHA1(), }, - new object[] { new HMACSHA256(), }, - new object[] { new HMACSHA384(), }, - new object[] { new HMACSHA512(), }, - }; + yield return new object[] { MD5.Create(), }; + } + + yield return new object[] { SHA1.Create(), }; + yield return new object[] { SHA256.Create(), }; + yield return new object[] { SHA384.Create(), }; + yield return new object[] { SHA512.Create(), }; + yield return new object[] { new HMACSHA1(), }; + yield return new object[] { new HMACSHA256(), }; + yield return new object[] { new HMACSHA384(), }; + yield return new object[] { new HMACSHA512(), }; } } } diff --git a/src/libraries/System.Security.Cryptography/tests/Rfc2202HmacTests.cs b/src/libraries/System.Security.Cryptography/tests/Rfc2202HmacTests.cs index 892d1d9748d286..e4bcc0a66667a2 100644 --- a/src/libraries/System.Security.Cryptography/tests/Rfc2202HmacTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Rfc2202HmacTests.cs @@ -6,7 +6,6 @@ namespace System.Security.Cryptography.Tests { - [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] public abstract class Rfc2202HmacTests : HmacTests { private static readonly byte[][] s_testData2202 = diff --git a/src/libraries/System.Security.Cryptography/tests/Rfc4231HmacTests.cs b/src/libraries/System.Security.Cryptography/tests/Rfc4231HmacTests.cs index 45070c834eed2e..2dd668a288ffd8 100644 --- a/src/libraries/System.Security.Cryptography/tests/Rfc4231HmacTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/Rfc4231HmacTests.cs @@ -6,7 +6,6 @@ namespace System.Security.Cryptography.Tests { - [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] public abstract class Rfc4231HmacTests : HmacTests { private static readonly byte[][] s_testKeys4231 = diff --git a/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.txt b/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.txt index dbe5f53d99e3db..30e8d88d4acff6 100644 --- a/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.txt +++ b/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.txt @@ -13,6 +13,10 @@ CannotChangeAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatfo CannotChangeAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' on 'System.Security.Cryptography.DSA.Create(System.Security.Cryptography.DSAParameters)' changed from '[UnsupportedOSPlatformAttribute("ios")]' in the contract to '[UnsupportedOSPlatformAttribute("browser")]' in the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.DSASignatureDeformatter' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.DSASignatureFormatter' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.HMACSHA1' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.HMACSHA256' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.HMACSHA384' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.HMACSHA512' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.MaskGenerationMethod' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.PKCS1MaskGenerationMethod' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.RandomNumberGenerator.Create(System.String)' in the contract but not the implementation. @@ -65,6 +69,12 @@ CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatfo CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.ECDiffieHellman' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.ECDsa' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.ECParameters' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.HMACSHA1' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.HMACSHA256' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.HMACSHA384' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.HMACSHA512' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.IncrementalHash.CreateHMAC(System.Security.Cryptography.HashAlgorithmName, System.Byte[])' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.IncrementalHash.CreateHMAC(System.Security.Cryptography.HashAlgorithmName, System.ReadOnlySpan)' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.MaskGenerationMethod' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.PKCS1MaskGenerationMethod' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.RandomNumberGenerator.Create(System.String)' in the contract but not the implementation. @@ -93,6 +103,8 @@ CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatfo CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.ECDiffieHellman' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.ECDsa' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.ECParameters' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.IncrementalHash.CreateHMAC(System.Security.Cryptography.HashAlgorithmName, System.Byte[])' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.IncrementalHash.CreateHMAC(System.Security.Cryptography.HashAlgorithmName, System.ReadOnlySpan)' in the contract but not the implementation. Compat issues with assembly System.Diagnostics.Process: CannotChangeAttribute : Attribute 'System.Runtime.Versioning.SupportedOSPlatformAttribute' on 'System.Diagnostics.Process.MaxWorkingSet.set(System.IntPtr)' changed from '[SupportedOSPlatformAttribute("freebsd")]' in the contract to '[SupportedOSPlatformAttribute("freebsd")]' in the implementation. CannotChangeAttribute : Attribute 'System.Runtime.Versioning.SupportedOSPlatformAttribute' on 'System.Diagnostics.Process.MinWorkingSet.set(System.IntPtr)' changed from '[SupportedOSPlatformAttribute("freebsd")]' in the contract to '[SupportedOSPlatformAttribute("freebsd")]' in the implementation. @@ -143,6 +155,12 @@ CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatfo CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.ECDiffieHellman' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.ECDsa' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.ECParameters' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.HMACSHA1' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.HMACSHA256' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.HMACSHA384' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.HMACSHA512' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.IncrementalHash.CreateHMAC(System.Security.Cryptography.HashAlgorithmName, System.Byte[])' in the contract but not the implementation. +CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.IncrementalHash.CreateHMAC(System.Security.Cryptography.HashAlgorithmName, System.ReadOnlySpan)' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.MaskGenerationMethod' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.PKCS1MaskGenerationMethod' in the contract but not the implementation. CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.RandomNumberGenerator.Create(System.String)' in the contract but not the implementation. @@ -160,4 +178,4 @@ CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatfo CannotRemoveAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' exists on 'System.Security.Cryptography.TripleDES' in the contract but not the implementation. Compat issues with assembly System.Security.Cryptography.X509Certificates: CannotChangeAttribute : Attribute 'System.Runtime.Versioning.UnsupportedOSPlatformAttribute' on 'System.Security.Cryptography.X509Certificates.PublicKey.GetDSAPublicKey()' changed from '[UnsupportedOSPlatformAttribute("ios")]' in the contract to '[UnsupportedOSPlatformAttribute("browser")]' in the implementation. -Total Issues: 149 +Total Issues: 167 From 190ec2c395b0e1919290ad44e739225cb03b17e9 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Mon, 13 Jun 2022 07:39:10 -0700 Subject: [PATCH 080/337] Localized file check-in by OneLocBuild Task: Build definition ID 679: Build ID 1818534 (#70596) --- .../gen/Resources/xlf/Strings.cs.xlf | 4 ++-- .../gen/Resources/xlf/Strings.de.xlf | 4 ++-- .../gen/Resources/xlf/Strings.es.xlf | 4 ++-- .../gen/Resources/xlf/Strings.fr.xlf | 4 ++-- .../gen/Resources/xlf/Strings.it.xlf | 4 ++-- .../gen/Resources/xlf/Strings.ja.xlf | 4 ++-- .../gen/Resources/xlf/Strings.ko.xlf | 4 ++-- .../gen/Resources/xlf/Strings.pl.xlf | 4 ++-- .../gen/Resources/xlf/Strings.pt-BR.xlf | 4 ++-- .../gen/Resources/xlf/Strings.ru.xlf | 4 ++-- .../gen/Resources/xlf/Strings.tr.xlf | 4 ++-- .../gen/Resources/xlf/Strings.zh-Hans.xlf | 4 ++-- .../gen/Resources/xlf/Strings.zh-Hant.xlf | 4 ++-- 13 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.cs.xlf b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.cs.xlf index 3e48745c4d5d58..0190c1fdb4f4de 100644 --- a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.cs.xlf +++ b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.cs.xlf @@ -264,12 +264,12 @@ Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. - Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. + Pomocí regexGeneratorAttribute vygenerujte implementaci regulárního výrazu za kompilace. Convert to 'RegexGenerator'. - Convert to 'RegexGenerator'. + Převod na RegexGenerator diff --git a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.de.xlf b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.de.xlf index 7ba5fc3ff43ba3..e9185184e05162 100644 --- a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.de.xlf +++ b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.de.xlf @@ -264,12 +264,12 @@ Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. - Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. + Verwenden Sie „RegexGeneratorAttribute“, um die Implementierung regulärer Ausdrücke zur Kompilierzeit zu generieren. Convert to 'RegexGenerator'. - Convert to 'RegexGenerator'. + In „RegexGenerator“ konvertieren. diff --git a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.es.xlf b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.es.xlf index cb919485eda630..abc31f55a8442c 100644 --- a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.es.xlf +++ b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.es.xlf @@ -264,12 +264,12 @@ Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. - Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. + Use 'RegexGeneratorAttribute' para generar la implementación de expresiones regulares en tiempo de compilación. Convert to 'RegexGenerator'. - Convert to 'RegexGenerator'. + Convertir en 'RegexGenerator'. diff --git a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.fr.xlf b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.fr.xlf index 7d0cfa26708f04..24d2980091b478 100644 --- a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.fr.xlf +++ b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.fr.xlf @@ -264,12 +264,12 @@ Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. - Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. + Utilisez « RegexGeneratorAttribute » pour générer l’implémentation d’expression régulière au moment de la compilation. Convert to 'RegexGenerator'. - Convert to 'RegexGenerator'. + Convertissez en 'RegexGenerator'. diff --git a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.it.xlf b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.it.xlf index b56d2baab35cdc..6fe53e60c8cdee 100644 --- a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.it.xlf +++ b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.it.xlf @@ -264,12 +264,12 @@ Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. - Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. + Usare 'RegexGeneratorAttribute' per generare l'implementazione dell'espressione regolare in fase di compilazione. Convert to 'RegexGenerator'. - Convert to 'RegexGenerator'. + Convertire in 'RegexGenerator'. diff --git a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.ja.xlf b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.ja.xlf index ffc2fd22facc8c..a87c6e1e9dda3a 100644 --- a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.ja.xlf +++ b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.ja.xlf @@ -264,12 +264,12 @@ Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. - Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. + 「RegexGeneratorAttribute」を使用すると、コンパイル時に正規表現の実装が生成されます。 Convert to 'RegexGenerator'. - Convert to 'RegexGenerator'. + 「RegexGenerator」に変換します。 diff --git a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.ko.xlf b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.ko.xlf index c5288462f0f542..0dd7066b0ad507 100644 --- a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.ko.xlf +++ b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.ko.xlf @@ -264,12 +264,12 @@ Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. - Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. + 'RegexGeneratorAttribute'를 사용하여 컴파일 시간에 정규식 구현을 생성합니다. Convert to 'RegexGenerator'. - Convert to 'RegexGenerator'. + 'RegexGenerator'로 변환합니다. diff --git a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.pl.xlf b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.pl.xlf index 89027382e84bd0..2c3a22dad224a5 100644 --- a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.pl.xlf @@ -264,12 +264,12 @@ Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. - Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. + Użyj atrybutu „RegexGeneratorAttribute”, aby wygenerować implementację wyrażenia regularnego w czasie kompilacji. Convert to 'RegexGenerator'. - Convert to 'RegexGenerator'. + Konwertuj na „RegexGenerator”. diff --git a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.pt-BR.xlf b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.pt-BR.xlf index ad1c07eeaef839..df89d14ee6ac64 100644 --- a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.pt-BR.xlf +++ b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.pt-BR.xlf @@ -264,12 +264,12 @@ Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. - Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. + Use 'RegexGeneratorAttribute' para gerar a implementação da expressão regular em tempo de compilação. Convert to 'RegexGenerator'. - Convert to 'RegexGenerator'. + Converter para 'RegexGenerator'. diff --git a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.ru.xlf b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.ru.xlf index 25b7a192d47292..d3918d3882b125 100644 --- a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.ru.xlf +++ b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.ru.xlf @@ -264,12 +264,12 @@ Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. - Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. + Используйте "RegexGeneratorAttribute", чтобы создавать реализацию регулярного выражения во время компиляции. Convert to 'RegexGenerator'. - Convert to 'RegexGenerator'. + Преобразовать в "RegexGenerator". diff --git a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.tr.xlf b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.tr.xlf index ca4f7e9dbf66df..1695752eff1a3c 100644 --- a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.tr.xlf +++ b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.tr.xlf @@ -264,12 +264,12 @@ Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. - Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. + Derleme zamanında normal ifade uygulamasını oluşturmak için “RegexGeneratorAttribute” kullanın. Convert to 'RegexGenerator'. - Convert to 'RegexGenerator'. + “RegexGenerator”a dönüştürün. diff --git a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.zh-Hans.xlf b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.zh-Hans.xlf index b016765f981605..ba762b4824ec10 100644 --- a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.zh-Hans.xlf @@ -264,12 +264,12 @@ Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. - Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. + 在编译时使用 “RegexGeneratorAttribute” 生成正则表达式实现。 Convert to 'RegexGenerator'. - Convert to 'RegexGenerator'. + 转换为 “RegexGenerator”。 diff --git a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.zh-Hant.xlf b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.zh-Hant.xlf index 55b0fb96889db1..6c9dddd795422b 100644 --- a/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/libraries/System.Text.RegularExpressions/gen/Resources/xlf/Strings.zh-Hant.xlf @@ -264,12 +264,12 @@ Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. - Use 'RegexGeneratorAttribute' to generate the regular expression implementation at compile-time. + 使用 'RegexGeneratorAttribute' 在編譯時間產生規則運算式實作。 Convert to 'RegexGenerator'. - Convert to 'RegexGenerator'. + 轉換成 'RegexGenerator'。 From 8b4f9c76d43462593b55a65a10854f341f3002e4 Mon Sep 17 00:00:00 2001 From: Sapana-Khemkar <94051076+Sapana-Khemkar@users.noreply.github.com> Date: Mon, 13 Jun 2022 20:23:04 +0530 Subject: [PATCH 081/337] ppc64le build support (#68806) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add ppc64le build support in eng directory files * add platform option linux-ppc64le * add ppc64le support in subfolder libraries * add RID linux-ppc64le and linux-musl-ppc64le as UnofficialBuildRID * ppc64le changes in subfolder native * add support for ppc64le to few coreclr makefiles required to build mono and libraries Co-authored-by: Alexander Köplinger --- Directory.Build.props | 1 + eng/Subsets.props | 2 +- eng/build.sh | 6 ++--- eng/native/build-commons.sh | 6 ++++- eng/native/configurecompiler.cmake | 10 +++++++ eng/native/configureplatform.cmake | 9 +++++++ eng/native/configuretools.cmake | 2 +- eng/native/functions.cmake | 4 +++ eng/native/init-os-and-arch.sh | 3 +++ eng/native/tryrun.cmake | 6 ++--- src/coreclr/jit/CMakeLists.txt | 18 +++++++++++-- src/coreclr/pal/src/CMakeLists.txt | 2 ++ src/coreclr/pal/src/misc/perfjitdump.cpp | 2 ++ .../pkg/projects/netcoreappRIDs.props | 6 +++++ .../src/runtime.compatibility.json | 26 ++++++++++++++++++- .../src/runtime.json | 19 +++++++++++++- .../src/runtimeGroups.props | 6 ++--- .../System.Private.CoreLib.Shared.projitems | 2 +- src/libraries/externals.csproj | 2 +- src/libraries/tests.proj | 9 +++++++ src/native/corehost/hostmisc/utils.cpp | 2 ++ src/native/eventpipe/ep-event-source.c | 2 ++ 22 files changed, 127 insertions(+), 18 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 45dabffc314c74..4f9312803f0309 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -35,6 +35,7 @@ arm64 loongarch64 s390x + ppc64le wasm x64 x64 diff --git a/eng/Subsets.props b/eng/Subsets.props index 7d6bfc86825cc7..1d08c11b1013a2 100644 --- a/eng/Subsets.props +++ b/eng/Subsets.props @@ -27,7 +27,7 @@ flavor is used to decide when to build the hosts and installers. --> CoreCLR - Mono + Mono diff --git a/eng/build.sh b/eng/build.sh index 9c9beb471f1fb1..21784abd80be38 100755 --- a/eng/build.sh +++ b/eng/build.sh @@ -17,7 +17,7 @@ scriptroot="$( cd -P "$( dirname "$source" )" && pwd )" usage() { echo "Common settings:" - echo " --arch (-a) Target platform: x86, x64, arm, armv6, armel, arm64, loongarch64, s390x or wasm." + echo " --arch (-a) Target platform: x86, x64, arm, armv6, armel, arm64, loongarch64, s390x, ppc64le or wasm." echo " [Default: Your machine's architecture.]" echo " --binaryLog (-bl) Output binary log." echo " --cross Optional argument to signify cross compilation." @@ -206,12 +206,12 @@ while [[ $# > 0 ]]; do fi passedArch="$(echo "$2" | tr "[:upper:]" "[:lower:]")" case "$passedArch" in - x64|x86|arm|armv6|armel|arm64|loongarch64|s390x|wasm) + x64|x86|arm|armv6|armel|arm64|loongarch64|s390x|ppc64le|wasm) arch=$passedArch ;; *) echo "Unsupported target architecture '$2'." - echo "The allowed values are x86, x64, arm, armv6, armel, arm64, loongarch64, s390x, and wasm." + echo "The allowed values are x86, x64, arm, armv6, armel, arm64, loongarch64, s390x, ppc64le and wasm." exit 1 ;; esac diff --git a/eng/native/build-commons.sh b/eng/native/build-commons.sh index dca61277f7fff1..1b28031ab4de49 100755 --- a/eng/native/build-commons.sh +++ b/eng/native/build-commons.sh @@ -197,7 +197,7 @@ usage() echo "" echo "Common Options:" echo "" - echo "BuildArch can be: -arm, -armv6, -armel, -arm64, -loongarch64, -s390x, x64, x86, -wasm" + echo "BuildArch can be: -arm, -armv6, -armel, -arm64, -loongarch64, -s390x, -ppc64le, x64, x86, -wasm" echo "BuildType can be: -debug, -checked, -release" echo "-os: target OS (defaults to running OS)" echo "-bindir: output directory (defaults to $__ProjectRoot/artifacts)" @@ -392,6 +392,10 @@ while :; do __TargetArch=wasm ;; + ppc64le|-ppc64le) + __TargetArch=ppc64le + ;; + os|-os) if [[ -n "$2" ]]; then __TargetOS="$2" diff --git a/eng/native/configurecompiler.cmake b/eng/native/configurecompiler.cmake index 931cecdeddb5b6..047999bded88ff 100644 --- a/eng/native/configurecompiler.cmake +++ b/eng/native/configurecompiler.cmake @@ -236,6 +236,9 @@ elseif (CLR_CMAKE_HOST_ARCH_WASM) elseif (CLR_CMAKE_HOST_ARCH_MIPS64) set(ARCH_HOST_NAME mips64) add_definitions(-DHOST_MIPS64 -DHOST_64BIT=1) +elseif (CLR_CMAKE_HOST_ARCH_POWERPC64) + set(ARCH_HOST_NAME ppc64le) + add_definitions(-DHOST_POWERPC64 -DHOST_64BIT) else () clr_unknown_arch() endif () @@ -256,6 +259,8 @@ if (CLR_CMAKE_HOST_UNIX) message("Detected Linux i686") elseif(CLR_CMAKE_HOST_UNIX_S390X) message("Detected Linux s390x") + elseif(CLR_CMAKE_HOST_UNIX_POWERPC64) + message("Detected Linux ppc64le") else() clr_unknown_arch() endif() @@ -332,6 +337,11 @@ elseif (CLR_CMAKE_TARGET_ARCH_S390X) set(ARCH_SOURCES_DIR s390x) add_compile_definitions($<$>>:TARGET_S390X>) add_compile_definitions($<$>>:TARGET_64BIT>) +elseif (CLR_CMAKE_TARGET_ARCH_POWERPC64) + set(ARCH_TARGET_NAME ppc64le) + set(ARCH_SOURCES_DIR ppc64le) + add_compile_definitions($<$>>:TARGET_POWERPC64>) + add_compile_definitions($<$>>:TARGET_64BIT>) elseif (CLR_CMAKE_TARGET_ARCH_WASM) set(ARCH_TARGET_NAME wasm) set(ARCH_SOURCES_DIR wasm) diff --git a/eng/native/configureplatform.cmake b/eng/native/configureplatform.cmake index 573d57f9ed0ddd..d21206f1f8bcad 100644 --- a/eng/native/configureplatform.cmake +++ b/eng/native/configureplatform.cmake @@ -51,6 +51,8 @@ if(CLR_CMAKE_HOST_OS STREQUAL Linux) set(CLR_CMAKE_HOST_UNIX_X86 1) elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL s390x) set(CLR_CMAKE_HOST_UNIX_S390X 1) + elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL ppc64le) + set(CLR_CMAKE_HOST_UNIX_POWERPC64 1) elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL mips64) set(CLR_CMAKE_HOST_UNIX_MIPS64 1) else() @@ -250,6 +252,9 @@ elseif(CLR_CMAKE_HOST_UNIX_X86) elseif(CLR_CMAKE_HOST_UNIX_S390X) set(CLR_CMAKE_HOST_ARCH_S390X 1) set(CLR_CMAKE_HOST_ARCH "s390x") +elseif(CLR_CMAKE_HOST_UNIX_POWERPC64) + set(CLR_CMAKE_HOST_ARCH_POWERPC64 1) + set(CLR_CMAKE_HOST_ARCH "ppc64le") elseif(CLR_CMAKE_HOST_BROWSER) set(CLR_CMAKE_HOST_ARCH_WASM 1) set(CLR_CMAKE_HOST_ARCH "wasm") @@ -303,6 +308,8 @@ if (CLR_CMAKE_TARGET_ARCH STREQUAL x64) set(ARM_SOFTFP 1) elseif(CLR_CMAKE_TARGET_ARCH STREQUAL s390x) set(CLR_CMAKE_TARGET_ARCH_S390X 1) + elseif(CLR_CMAKE_TARGET_ARCH STREQUAL ppc64le) + set(CLR_CMAKE_TARGET_ARCH_POWERPC64 1) elseif(CLR_CMAKE_TARGET_ARCH STREQUAL wasm) set(CLR_CMAKE_TARGET_ARCH_WASM 1) elseif(CLR_CMAKE_TARGET_ARCH STREQUAL mips64) @@ -413,6 +420,8 @@ if(CLR_CMAKE_TARGET_UNIX) set(CLR_CMAKE_TARGET_UNIX_X86 1) elseif(CLR_CMAKE_TARGET_ARCH STREQUAL s390x) set(CLR_CMAKE_TARGET_UNIX_S390X 1) + elseif(CLR_CMAKE_TARGET_ARCH STREQUAL ppc64le) + set(CLR_CMAKE_TARGET_UNIX_POWERPC64 1) elseif(CLR_CMAKE_TARGET_ARCH STREQUAL wasm) set(CLR_CMAKE_TARGET_UNIX_WASM 1) elseif(CLR_CMAKE_TARGET_ARCH STREQUAL mips64) diff --git a/eng/native/configuretools.cmake b/eng/native/configuretools.cmake index 3437ce7cdae64a..6697524c6596ae 100644 --- a/eng/native/configuretools.cmake +++ b/eng/native/configuretools.cmake @@ -53,7 +53,7 @@ if(NOT WIN32 AND NOT CLR_CMAKE_TARGET_BROWSER) if(CLR_CMAKE_TARGET_ANDROID) set(TOOLSET_PREFIX ${ANDROID_TOOLCHAIN_PREFIX}) elseif(CMAKE_CROSSCOMPILING AND NOT DEFINED CLR_CROSS_COMPONENTS_BUILD AND - CMAKE_SYSTEM_PROCESSOR MATCHES "^(armv8l|armv7l|armv6l|aarch64|arm|s390x)$") + CMAKE_SYSTEM_PROCESSOR MATCHES "^(armv8l|armv7l|armv6l|aarch64|arm|s390x|ppc64le)$") set(TOOLSET_PREFIX "${TOOLCHAIN}-") else() set(TOOLSET_PREFIX "") diff --git a/eng/native/functions.cmake b/eng/native/functions.cmake index eaef0d65df0664..6a8c8f24e9a79c 100644 --- a/eng/native/functions.cmake +++ b/eng/native/functions.cmake @@ -175,6 +175,10 @@ function(find_unwind_libs UnwindLibs) find_library(UNWIND_ARCH NAMES unwind-s390x) endif() + if(CLR_CMAKE_HOST_ARCH_POWERPC64) + find_library(UNWIND_ARCH NAMES unwind-ppc64le) + endif() + if(NOT UNWIND_ARCH STREQUAL UNWIND_ARCH-NOTFOUND) set(UNWIND_LIBS ${UNWIND_ARCH}) endif() diff --git a/eng/native/init-os-and-arch.sh b/eng/native/init-os-and-arch.sh index 7a5815081ad2a8..ded32e3f755f36 100644 --- a/eng/native/init-os-and-arch.sh +++ b/eng/native/init-os-and-arch.sh @@ -66,6 +66,9 @@ case "$CPUName" in arch=s390x ;; + ppc64le) + arch=ppc64le + ;; *) echo "Unknown CPU $CPUName detected, configuring as if for x64" arch=x64 diff --git a/eng/native/tryrun.cmake b/eng/native/tryrun.cmake index fca410fcb4b42f..c491422ae7bcec 100644 --- a/eng/native/tryrun.cmake +++ b/eng/native/tryrun.cmake @@ -68,7 +68,7 @@ if(DARWIN) else() message(FATAL_ERROR "Arch is ${TARGET_ARCH_NAME}. Only arm64 or x64 is supported for OSX cross build!") endif() -elseif(TARGET_ARCH_NAME MATCHES "^(armel|arm|armv6|arm64|loongarch64|s390x|x86)$" OR FREEBSD OR ILLUMOS) +elseif(TARGET_ARCH_NAME MATCHES "^(armel|arm|armv6|arm64|loongarch64|s390x|ppc64le|x86)$" OR FREEBSD OR ILLUMOS) set_cache_value(FILE_OPS_CHECK_FERROR_OF_PREVIOUS_CALL_EXITCODE 1) set_cache_value(GETPWUID_R_SETS_ERRNO_EXITCODE 0) set_cache_value(HAS_POSIX_SEMAPHORES_EXITCODE 0) @@ -146,9 +146,9 @@ elseif(TARGET_ARCH_NAME MATCHES "^(armel|arm|armv6|arm64|loongarch64|s390x|x86)$ set_cache_value(HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES_EXITCODE 0) endif() else() - message(FATAL_ERROR "Arch is ${TARGET_ARCH_NAME}. Only armel, arm, armv6, arm64, loongarch64, s390x and x86 are supported!") + message(FATAL_ERROR "Arch is ${TARGET_ARCH_NAME}. Only armel, arm, armv6, arm64, loongarch64, s390x, ppc64le and x86 are supported!") endif() -if(TARGET_ARCH_NAME STREQUAL "x86" OR TARGET_ARCH_NAME STREQUAL "s390x" OR TARGET_ARCH_NAME STREQUAL "armv6" OR TARGET_ARCH_NAME STREQUAL "loongarch64") +if(TARGET_ARCH_NAME STREQUAL "x86" OR TARGET_ARCH_NAME STREQUAL "s390x" OR TARGET_ARCH_NAME STREQUAL "armv6" OR TARGET_ARCH_NAME STREQUAL "loongarch64" OR TARGET_ARCH_NAME STREQUAL "ppc64le") set_cache_value(HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES_EXITCODE 0) endif() diff --git a/src/coreclr/jit/CMakeLists.txt b/src/coreclr/jit/CMakeLists.txt index 4bc1693e8dfb7c..3410747d021eb8 100644 --- a/src/coreclr/jit/CMakeLists.txt +++ b/src/coreclr/jit/CMakeLists.txt @@ -48,6 +48,9 @@ function(create_standalone_jit) elseif(TARGETDETAILS_ARCH STREQUAL "s390x") set(JIT_ARCH_SOURCES ${JIT_S390X_SOURCES}) set(JIT_ARCH_HEADERS ${JIT_S390X_HEADERS}) + elseif(TARGETDETAILS_ARCH STREQUAL "ppc64le") + set(JIT_ARCH_SOURCES ${JIT_POWERPC64_SOURCES}) + set(JIT_ARCH_HEADERS ${JIT_POWERPC64_HEADERS}) elseif(TARGETDETAILS_ARCH STREQUAL "loongarch64") set(JIT_ARCH_SOURCES ${JIT_LOONGARCH64_SOURCES}) set(JIT_ARCH_HEADERS ${JIT_LOONGARCH64_HEADERS}) @@ -241,6 +244,10 @@ set( JIT_S390X_SOURCES # Not supported as JIT target ) +set( JIT_POWERPC64_SOURCES + # Not supported as JIT target +) + set( JIT_LOONGARCH64_SOURCES codegenloongarch64.cpp emitloongarch64.cpp @@ -396,6 +403,10 @@ set ( JIT_S390X_HEADERS # Not supported as JIT target ) +set ( JIT_POWERPC64_HEADERS + # Not supported as JIT target +) + set( JIT_LOONGARCH64_HEADERS emitloongarch64.h emitfmtsloongarch64.h @@ -442,6 +453,9 @@ elseif(CLR_CMAKE_TARGET_ARCH_ARM64) elseif(CLR_CMAKE_TARGET_ARCH_S390X) set(JIT_ARCH_SOURCES ${JIT_S390X_SOURCES}) set(JIT_ARCH_HEADERS ${JIT_S390X_HEADERS}) +elseif(CLR_CMAKE_TARGET_ARCH_POWERPC64) + set(JIT_ARCH_SOURCES ${JIT_POWERPC64_SOURCES}) + set(JIT_ARCH_HEADERS ${JIT_POWERPC64_HEADERS}) elseif(CLR_CMAKE_TARGET_ARCH_LOONGARCH64) set(JIT_ARCH_SOURCES ${JIT_LOONGARCH64_SOURCES}) set(JIT_ARCH_HEADERS ${JIT_LOONGARCH64_HEADERS}) @@ -600,13 +614,13 @@ if (CLR_CMAKE_TARGET_ARCH_I386 AND CLR_CMAKE_TARGET_UNIX) endif (CLR_CMAKE_TARGET_ARCH_I386 AND CLR_CMAKE_TARGET_UNIX) if (CLR_CMAKE_TARGET_UNIX) - if (NOT ARCH_TARGET_NAME STREQUAL s390x AND NOT ARCH_TARGET_NAME STREQUAL armv6) + if (NOT ARCH_TARGET_NAME STREQUAL s390x AND NOT ARCH_TARGET_NAME STREQUAL armv6 AND NOT ARCH_TARGET_NAME STREQUAL ppc64le) if(CLR_CMAKE_TARGET_ARCH_ARM OR CLR_CMAKE_TARGET_ARCH_ARM64) install_clr(TARGETS clrjit_universal_${ARCH_TARGET_NAME}_${ARCH_HOST_NAME} DESTINATIONS . COMPONENT jit) else() install_clr(TARGETS clrjit_unix_${ARCH_TARGET_NAME}_${ARCH_HOST_NAME} DESTINATIONS . COMPONENT jit) endif() - endif(NOT ARCH_TARGET_NAME STREQUAL s390x AND NOT ARCH_TARGET_NAME STREQUAL armv6) + endif(NOT ARCH_TARGET_NAME STREQUAL s390x AND NOT ARCH_TARGET_NAME STREQUAL armv6 AND NOT ARCH_TARGET_NAME STREQUAL ppc64le) endif() if (CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_PGO_INSTRUMENT) diff --git a/src/coreclr/pal/src/CMakeLists.txt b/src/coreclr/pal/src/CMakeLists.txt index 4e6509c88590ce..933333aba64a26 100644 --- a/src/coreclr/pal/src/CMakeLists.txt +++ b/src/coreclr/pal/src/CMakeLists.txt @@ -56,6 +56,8 @@ elseif(CLR_CMAKE_HOST_ARCH_I386) set(PAL_ARCH_SOURCES_DIR i386) elseif(CLR_CMAKE_HOST_ARCH_S390X) set(PAL_ARCH_SOURCES_DIR s390x) +elseif(CLR_CMAKE_HOST_ARCH_POWERPC64) + set(PAL_ARCH_SOURCES_DIR ppc64le) endif() if(CLR_CMAKE_USE_SYSTEM_LIBUNWIND) diff --git a/src/coreclr/pal/src/misc/perfjitdump.cpp b/src/coreclr/pal/src/misc/perfjitdump.cpp index f0c980a61efab7..df7e97af53087e 100644 --- a/src/coreclr/pal/src/misc/perfjitdump.cpp +++ b/src/coreclr/pal/src/misc/perfjitdump.cpp @@ -50,6 +50,8 @@ namespace ELF_MACHINE = EM_LOONGARCH, #elif defined(HOST_S390X) ELF_MACHINE = EM_S390, +#elif defined(HOST_POWERPC) + ELF_MACHINE = EM_PPC64, #else #error ELF_MACHINE unsupported for target #endif diff --git a/src/installer/pkg/projects/netcoreappRIDs.props b/src/installer/pkg/projects/netcoreappRIDs.props index 6b64c905498053..318e97e9b2ac9d 100644 --- a/src/installer/pkg/projects/netcoreappRIDs.props +++ b/src/installer/pkg/projects/netcoreappRIDs.props @@ -65,5 +65,11 @@ s390x + + ppc64le + + + ppc64le + diff --git a/src/libraries/Microsoft.NETCore.Platforms/src/runtime.compatibility.json b/src/libraries/Microsoft.NETCore.Platforms/src/runtime.compatibility.json index caf1063a4db41d..15c8c0a74777fd 100644 --- a/src/libraries/Microsoft.NETCore.Platforms/src/runtime.compatibility.json +++ b/src/libraries/Microsoft.NETCore.Platforms/src/runtime.compatibility.json @@ -4294,6 +4294,16 @@ "unix", "any", "base" + ], + "linux-musl-ppc64le": [ + "linux-musl-ppc64le", + "linux-musl", + "linux-ppc64le", + "linux", + "unix-ppc64le", + "unix", + "any", + "base" ], "linux-musl-x64": [ "linux-musl-x64", @@ -4323,6 +4333,14 @@ "any", "base" ], + "linux-ppc64le": [ + "linux-ppc64le", + "linux", + "unix-ppc64le", + "unix", + "any", + "base" + ], "linux-x64": [ "linux-x64", "linux", @@ -8883,6 +8901,12 @@ "any", "base" ], + "unix-ppc64le": [ + "unix-ppc64le", + "unix", + "any", + "base" + ], "unix-x64": [ "unix-x64", "unix", @@ -9525,4 +9549,4 @@ "any", "base" ] -} \ No newline at end of file +} diff --git a/src/libraries/Microsoft.NETCore.Platforms/src/runtime.json b/src/libraries/Microsoft.NETCore.Platforms/src/runtime.json index 2e5e6aa95cdac7..050ce1e4e8ce36 100644 --- a/src/libraries/Microsoft.NETCore.Platforms/src/runtime.json +++ b/src/libraries/Microsoft.NETCore.Platforms/src/runtime.json @@ -1643,6 +1643,12 @@ "linux-s390x" ] }, + "linux-musl-ppc64le": { + "#import": [ + "linux-musl", + "linux-ppc64le" + ] + }, "linux-musl-x64": { "#import": [ "linux-musl", @@ -1661,6 +1667,12 @@ "unix-s390x" ] }, + "linux-ppc64le": { + "#import": [ + "linux", + "unix-ppc64le" + ] + }, "linux-x64": { "#import": [ "linux", @@ -3629,6 +3641,11 @@ "unix" ] }, + "unix-ppc64le": { + "#import": [ + "unix" + ] + }, "unix-x64": { "#import": [ "unix" @@ -3963,4 +3980,4 @@ ] } } -} \ No newline at end of file +} diff --git a/src/libraries/Microsoft.NETCore.Platforms/src/runtimeGroups.props b/src/libraries/Microsoft.NETCore.Platforms/src/runtimeGroups.props index 1a04ed929e85d6..1b10a2604af28a 100644 --- a/src/libraries/Microsoft.NETCore.Platforms/src/runtimeGroups.props +++ b/src/libraries/Microsoft.NETCore.Platforms/src/runtimeGroups.props @@ -3,15 +3,15 @@ any - x64;x86;arm;armv6;armel;arm64;loongarch64;mips64;s390x + x64;x86;arm;armv6;armel;arm64;loongarch64;mips64;s390x;ppc64le unix - x64;x86;arm;armv6;armel;arm64;loongarch64;mips64;s390x + x64;x86;arm;armv6;armel;arm64;loongarch64;mips64;s390x;ppc64le linux - x64;x86;arm;armel;arm64;s390x + x64;x86;arm;armel;arm64;s390x;ppc64le diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index d3d733b73f5692..ebdb96165b0116 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -18,7 +18,7 @@ true $(MSBuildThisFileDirectory)ILLink\ true - true + true true diff --git a/src/libraries/externals.csproj b/src/libraries/externals.csproj index 9d6d1082c5f5c6..415545b533e76a 100644 --- a/src/libraries/externals.csproj +++ b/src/libraries/externals.csproj @@ -9,7 +9,7 @@ true false true - true + true diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index a7ff3edf11692a..01cc7cd2ceb24b 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -111,6 +111,11 @@ + + + + + @@ -379,6 +384,10 @@ + + + + diff --git a/src/native/corehost/hostmisc/utils.cpp b/src/native/corehost/hostmisc/utils.cpp index e768b04f251d72..519b2ecc583114 100644 --- a/src/native/corehost/hostmisc/utils.cpp +++ b/src/native/corehost/hostmisc/utils.cpp @@ -210,6 +210,8 @@ const pal::char_t* get_arch() return _X("loongarch64"); #elif defined(TARGET_S390X) return _X("s390x"); +#elif defined(TARGET_POWERPC64) + return _X("ppc64le"); #else #error "Unknown target" #endif diff --git a/src/native/eventpipe/ep-event-source.c b/src/native/eventpipe/ep-event-source.c index 2b631205116e7e..5fd07ab77ebd0a 100644 --- a/src/native/eventpipe/ep-event-source.c +++ b/src/native/eventpipe/ep-event-source.c @@ -44,6 +44,8 @@ const ep_char8_t* _ep_arch_info = "arm64"; const ep_char8_t* _ep_arch_info = "s390x"; #elif defined(TARGET_LOONGARCH64) const ep_char8_t* _ep_arch_info = "loongarch64"; +#elif defined(TARGET_POWERPC64) +const ep_char8_t* _ep_arch_info = "ppc64le"; #else const ep_char8_t* _ep_arch_info = "Unknown"; #endif From e4aba625935842fd0479d0a315154ac947f0a3f5 Mon Sep 17 00:00:00 2001 From: Sapana-Khemkar <94051076+Sapana-Khemkar@users.noreply.github.com> Date: Mon, 13 Jun 2022 20:34:41 +0530 Subject: [PATCH 082/337] Add architecture enum value for PPC64le (#68809) --- .../src/System/Runtime/InteropServices/Architecture.cs | 1 + .../src/System/Runtime/InteropServices/RuntimeInformation.cs | 2 ++ .../tests/CheckArchitectureTests.cs | 4 ++++ src/libraries/System.Runtime/ref/System.Runtime.cs | 1 + 4 files changed, 8 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Architecture.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Architecture.cs index 4dead88ce4c92f..a59a9a5868e89f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Architecture.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/Architecture.cs @@ -13,5 +13,6 @@ public enum Architecture S390x, LoongArch64, Armv6, + Ppc64le, } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/RuntimeInformation.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/RuntimeInformation.cs index 2d24563212bb56..d0b1eee65bbbcb 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/RuntimeInformation.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/RuntimeInformation.cs @@ -68,6 +68,8 @@ public static Architecture ProcessArchitecture => Architecture.S390x; #elif TARGET_LOONGARCH64 => Architecture.LoongArch64; +#elif TARGET_POWERPC64 + => Architecture.Ppc64le; #else #error Unknown Architecture #endif diff --git a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/CheckArchitectureTests.cs b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/CheckArchitectureTests.cs index 50fe5210c91ad5..1405411989d9ef 100644 --- a/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/CheckArchitectureTests.cs +++ b/src/libraries/System.Runtime.InteropServices.RuntimeInformation/tests/CheckArchitectureTests.cs @@ -48,6 +48,10 @@ public void VerifyArchitecture() Assert.Equal(Architecture.Armv6, processArch); break; + case Architecture.Ppc64le: + Assert.Equal(Architecture.Ppc64le, processArch); + break; + default: Assert.False(true, "Unexpected Architecture."); break; diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 29dba4b49d954d..680a79f0102a2d 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -12861,6 +12861,7 @@ public enum Architecture S390x = 5, LoongArch64 = 6, Armv6 = 7, + Ppc64le = 8, } public enum CharSet { From 76d322474cea7888bb409ded54cef44fb243c203 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Mon, 13 Jun 2022 17:47:38 +0200 Subject: [PATCH 083/337] JIT: Enable CSE for CLS/STR const handles (#70580) --- src/coreclr/jit/gentree.cpp | 5 +++++ src/coreclr/jit/jitconfigvalues.h | 4 ++-- src/coreclr/jit/optcse.cpp | 14 ++++++++------ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 46cec07a192ffb..559a86c26a11b5 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -4401,6 +4401,11 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) { costSz = 10; costEx = 2; + if (con->IsIconHandle()) + { + // A sort of a hint for CSE to try harder for class handles + costEx += 1; + } } #endif // TARGET_AMD64 else diff --git a/src/coreclr/jit/jitconfigvalues.h b/src/coreclr/jit/jitconfigvalues.h index 0d701bb958ce30..33cf1d74f206eb 100644 --- a/src/coreclr/jit/jitconfigvalues.h +++ b/src/coreclr/jit/jitconfigvalues.h @@ -354,9 +354,9 @@ CONFIG_INTEGER(JitDisableSimdVN, W("JitDisableSimdVN"), 0) // Default 0, ValueNu // CONFIG_INTEGER(JitConstCSE, W("JitConstCSE"), 0) -#define CONST_CSE_ENABLE_ARM64 0 +#define CONST_CSE_ENABLE_ARM 0 #define CONST_CSE_DISABLE_ALL 1 -#define CONST_CSE_ENABLE_ARM64_NO_SHARING 2 +#define CONST_CSE_ENABLE_ARM_NO_SHARING 2 #define CONST_CSE_ENABLE_ALL 3 #define CONST_CSE_ENABLE_ALL_NO_SHARING 4 diff --git a/src/coreclr/jit/optcse.cpp b/src/coreclr/jit/optcse.cpp index af04a6b11fcc3d..6898c5ae62a44d 100644 --- a/src/coreclr/jit/optcse.cpp +++ b/src/coreclr/jit/optcse.cpp @@ -385,13 +385,13 @@ unsigned Compiler::optValnumCSE_Index(GenTree* tree, Statement* stmt) bool isSharedConst = false; int configValue = JitConfig.JitConstCSE(); -#if defined(TARGET_ARM64) - // ARM64 - allow to combine with nearby offsets, when config is not 2 or 4 - if ((configValue != CONST_CSE_ENABLE_ARM64_NO_SHARING) && (configValue != CONST_CSE_ENABLE_ALL_NO_SHARING)) +#if defined(TARGET_ARMARCH) + // ARMARCH - allow to combine with nearby offsets, when config is not 2 or 4 + if ((configValue != CONST_CSE_ENABLE_ARM_NO_SHARING) && (configValue != CONST_CSE_ENABLE_ALL_NO_SHARING)) { enableSharedConstCSE = true; } -#endif // TARGET_ARM64 +#endif // TARGET_ARMARCH // All Platforms - also allow to combine with nearby offsets, when config is 3 if (configValue == CONST_CSE_ENABLE_ALL) @@ -785,10 +785,12 @@ bool Compiler::optValnumCSE_Locate() } // Don't allow CSE of constants if it is disabled - // if (tree->IsIntegralConst()) { - if (!enableConstCSE) + if (!enableConstCSE && + // Unconditionally allow these constant handles to be CSE'd + !tree->IsIconHandle(GTF_ICON_STATIC_HDL) && !tree->IsIconHandle(GTF_ICON_CLASS_HDL) && + !tree->IsIconHandle(GTF_ICON_STR_HDL)) { continue; } From 27811e5746ffd50e3efac0ed008dc3f5ff564f14 Mon Sep 17 00:00:00 2001 From: Weihan Li Date: Tue, 14 Jun 2022 00:11:18 +0800 Subject: [PATCH 084/337] Add DeleteFromJsonAsync extension for HttpClient (#65619) * Add DeleteFromJsonAsync extension for HttpClient * Fix Build * Add functional tests Co-authored-by: Eirik Tsarpalis --- .../ref/System.Net.Http.Json.cs | 20 ++ .../src/System.Net.Http.Json.csproj | 1 + .../Json/HttpClientJsonExtensions.Delete.cs | 179 ++++++++++++++++++ .../HttpClientJsonExtensionsTests.cs | 46 +++++ 4 files changed, 246 insertions(+) create mode 100644 src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.Delete.cs diff --git a/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.cs b/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.cs index a78eafa30d79c1..3df4d2971dc56d 100644 --- a/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.cs +++ b/src/libraries/System.Net.Http.Json/ref/System.Net.Http.Json.cs @@ -8,6 +8,26 @@ namespace System.Net.Http.Json { public static partial class HttpClientJsonExtensions { + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task DeleteFromJsonAsync(this System.Net.Http.HttpClient client, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("Uri")] string? requestUri, System.Type type, System.Text.Json.JsonSerializerOptions? options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Threading.Tasks.Task DeleteFromJsonAsync(this System.Net.Http.HttpClient client, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("Uri")] string? requestUri, System.Type type, System.Text.Json.Serialization.JsonSerializerContext context, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task DeleteFromJsonAsync(this System.Net.Http.HttpClient client, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("Uri")] string? requestUri, System.Type type, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task DeleteFromJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, System.Type type, System.Text.Json.JsonSerializerOptions? options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Threading.Tasks.Task DeleteFromJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, System.Type type, System.Text.Json.Serialization.JsonSerializerContext context, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task DeleteFromJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, System.Type type, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task DeleteFromJsonAsync(this System.Net.Http.HttpClient client, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("Uri")] string? requestUri, System.Text.Json.JsonSerializerOptions? options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Threading.Tasks.Task DeleteFromJsonAsync(this System.Net.Http.HttpClient client, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("Uri")] string? requestUri, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task DeleteFromJsonAsync(this System.Net.Http.HttpClient client, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("Uri")] string? requestUri, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task DeleteFromJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, System.Text.Json.JsonSerializerOptions? options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + public static System.Threading.Tasks.Task DeleteFromJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, System.Text.Json.Serialization.Metadata.JsonTypeInfo jsonTypeInfo, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] + public static System.Threading.Tasks.Task DeleteFromJsonAsync(this System.Net.Http.HttpClient client, System.Uri? requestUri, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")] public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("Uri")] string? requestUri, System.Type type, System.Text.Json.JsonSerializerOptions? options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public static System.Threading.Tasks.Task GetFromJsonAsync(this System.Net.Http.HttpClient client, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("Uri")] string? requestUri, System.Type type, System.Text.Json.Serialization.JsonSerializerContext context, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } diff --git a/src/libraries/System.Net.Http.Json/src/System.Net.Http.Json.csproj b/src/libraries/System.Net.Http.Json/src/System.Net.Http.Json.csproj index 31145acf20a9cd..c8fd20b69afcd8 100644 --- a/src/libraries/System.Net.Http.Json/src/System.Net.Http.Json.csproj +++ b/src/libraries/System.Net.Http.Json/src/System.Net.Http.Json.csproj @@ -12,6 +12,7 @@ System.Net.Http.Json.JsonContent + diff --git a/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.Delete.cs b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.Delete.cs new file mode 100644 index 00000000000000..075a1fda8e50dc --- /dev/null +++ b/src/libraries/System.Net.Http.Json/src/System/Net/Http/Json/HttpClientJsonExtensions.Delete.cs @@ -0,0 +1,179 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics.CodeAnalysis; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Text.Json.Serialization.Metadata; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Net.Http.Json +{ + /// + /// Contains the extensions methods for using JSON as the content-type in HttpClient. + /// + public static partial class HttpClientJsonExtensions + { + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static Task DeleteFromJsonAsync(this HttpClient client, [StringSyntax("Uri")] string? requestUri, Type type, JsonSerializerOptions? options, CancellationToken cancellationToken = default) + { + if (client is null) + { + throw new ArgumentNullException(nameof(client)); + } + + Task taskResponse = client.DeleteAsync(requestUri, cancellationToken); + return DeleteFromJsonAsyncCore(taskResponse, type, options, cancellationToken); + } + + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static Task DeleteFromJsonAsync(this HttpClient client, Uri? requestUri, Type type, JsonSerializerOptions? options, CancellationToken cancellationToken = default) + { + if (client is null) + { + throw new ArgumentNullException(nameof(client)); + } + + Task taskResponse = client.DeleteAsync(requestUri, cancellationToken); + return DeleteFromJsonAsyncCore(taskResponse, type, options, cancellationToken); + } + + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static Task DeleteFromJsonAsync(this HttpClient client, [StringSyntax("Uri")] string? requestUri, JsonSerializerOptions? options, CancellationToken cancellationToken = default) + { + if (client is null) + { + throw new ArgumentNullException(nameof(client)); + } + + Task taskResponse = client.DeleteAsync(requestUri, cancellationToken); + return DeleteFromJsonAsyncCore(taskResponse, options, cancellationToken); + } + + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static Task DeleteFromJsonAsync(this HttpClient client, Uri? requestUri, JsonSerializerOptions? options, CancellationToken cancellationToken = default) + { + if (client is null) + { + throw new ArgumentNullException(nameof(client)); + } + + Task taskResponse = client.DeleteAsync(requestUri, cancellationToken); + return DeleteFromJsonAsyncCore(taskResponse, options, cancellationToken); + } + + public static Task DeleteFromJsonAsync(this HttpClient client, [StringSyntax("Uri")] string? requestUri, Type type, JsonSerializerContext context, CancellationToken cancellationToken = default) + { + if (client is null) + { + throw new ArgumentNullException(nameof(client)); + } + + Task taskResponse = client.DeleteAsync(requestUri, cancellationToken); + return DeleteFromJsonAsyncCore(taskResponse, type, context, cancellationToken); + } + + public static Task DeleteFromJsonAsync(this HttpClient client, Uri? requestUri, Type type, JsonSerializerContext context, CancellationToken cancellationToken = default) + { + if (client is null) + { + throw new ArgumentNullException(nameof(client)); + } + + Task taskResponse = client.DeleteAsync(requestUri, cancellationToken); + return DeleteFromJsonAsyncCore(taskResponse, type, context, cancellationToken); + } + + public static Task DeleteFromJsonAsync(this HttpClient client, [StringSyntax("Uri")] string? requestUri, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken = default) + { + if (client is null) + { + throw new ArgumentNullException(nameof(client)); + } + + Task taskResponse = client.DeleteAsync(requestUri, cancellationToken); + return DeleteFromJsonAsyncCore(taskResponse, jsonTypeInfo, cancellationToken); + } + + public static Task DeleteFromJsonAsync(this HttpClient client, Uri? requestUri, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken = default) + { + if (client is null) + { + throw new ArgumentNullException(nameof(client)); + } + + Task taskResponse = client.DeleteAsync(requestUri, cancellationToken); + return DeleteFromJsonAsyncCore(taskResponse, jsonTypeInfo, cancellationToken); + } + + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static Task DeleteFromJsonAsync(this HttpClient client, [StringSyntax("Uri")] string? requestUri, Type type, CancellationToken cancellationToken = default) + => client.DeleteFromJsonAsync(requestUri, type, options: null, cancellationToken); + + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static Task DeleteFromJsonAsync(this HttpClient client, Uri? requestUri, Type type, CancellationToken cancellationToken = default) + => client.DeleteFromJsonAsync(requestUri, type, options: null, cancellationToken); + + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static Task DeleteFromJsonAsync(this HttpClient client, [StringSyntax("Uri")] string? requestUri, CancellationToken cancellationToken = default) + => client.DeleteFromJsonAsync(requestUri, options: null, cancellationToken); + + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + public static Task DeleteFromJsonAsync(this HttpClient client, Uri? requestUri, CancellationToken cancellationToken = default) + => client.DeleteFromJsonAsync(requestUri, options: null, cancellationToken); + + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + private static async Task DeleteFromJsonAsyncCore(Task taskResponse, Type type, JsonSerializerOptions? options, CancellationToken cancellationToken) + { + using (HttpResponseMessage response = await taskResponse.ConfigureAwait(false)) + { + response.EnsureSuccessStatusCode(); + // Nullable forgiving reason: + // DeleteAsync will usually return Content as not-null. + // If Content happens to be null, the extension will throw. + return await ReadFromJsonAsyncHelper(response.Content!, type, options, cancellationToken).ConfigureAwait(false); + } + + // Workaround for https://github.com/mono/linker/issues/1416, extracting the offending call into a separate method + // which can be annotated with suppressions. + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", + Justification = "Workaround for https://github.com/mono/linker/issues/1416. The outer method is marked as RequiresUnreferencedCode.")] + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2067:UnrecognizedReflectionPattern", + Justification = "Workaround for https://github.com/mono/linker/issues/1416. The outer method is marked as RequiresUnreferencedCode.")] + static Task ReadFromJsonAsyncHelper(HttpContent content, Type type, JsonSerializerOptions? options, CancellationToken cancellationToken) + => content.ReadFromJsonAsync(type, options, cancellationToken); + } + + [RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)] + private static async Task DeleteFromJsonAsyncCore(Task taskResponse, JsonSerializerOptions? options, CancellationToken cancellationToken) + { + using (HttpResponseMessage response = await taskResponse.ConfigureAwait(false)) + { + response.EnsureSuccessStatusCode(); + // Nullable forgiving reason: + // DeleteAsync will usually return Content as not-null. + // If Content happens to be null, the extension will throw. + return await ReadFromJsonAsyncHelper(response.Content!, options, cancellationToken).ConfigureAwait(false); + } + } + + private static async Task DeleteFromJsonAsyncCore(Task taskResponse, Type type, JsonSerializerContext context, CancellationToken cancellationToken) + { + using (HttpResponseMessage response = await taskResponse.ConfigureAwait(false)) + { + response.EnsureSuccessStatusCode(); + return await response.Content!.ReadFromJsonAsync(type, context, cancellationToken).ConfigureAwait(false); + } + } + + private static async Task DeleteFromJsonAsyncCore(Task taskResponse, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken) + { + using (HttpResponseMessage response = await taskResponse.ConfigureAwait(false)) + { + response.EnsureSuccessStatusCode(); + return await response.Content!.ReadFromJsonAsync(jsonTypeInfo, cancellationToken).ConfigureAwait(false); + } + } + } +} diff --git a/src/libraries/System.Net.Http.Json/tests/FunctionalTests/HttpClientJsonExtensionsTests.cs b/src/libraries/System.Net.Http.Json/tests/FunctionalTests/HttpClientJsonExtensionsTests.cs index fd9ecd90a40092..076c223877384d 100644 --- a/src/libraries/System.Net.Http.Json/tests/FunctionalTests/HttpClientJsonExtensionsTests.cs +++ b/src/libraries/System.Net.Http.Json/tests/FunctionalTests/HttpClientJsonExtensionsTests.cs @@ -224,6 +224,52 @@ await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( }); } + [Fact] + public async Task TestDeleteFromJsonAsync() + { + await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync( + async (handler, uri) => + { + using (HttpClient client = new HttpClient(handler)) + { + Person person = Person.Create(); + Type typePerson = typeof(Person); + + object response = await client.DeleteFromJsonAsync(uri.ToString(), typeof(Person)); + Assert.IsType(response).Validate(); + + response = await client.DeleteFromJsonAsync(uri, typeof(Person)); + Assert.IsType(response).Validate(); + + response = await client.DeleteFromJsonAsync(uri.ToString(), typeof(Person), CancellationToken.None); + Assert.IsType(response).Validate(); + + response = await client.DeleteFromJsonAsync(uri, CancellationToken.None); + Assert.IsType(response).Validate(); + + response = await client.DeleteFromJsonAsync(uri.ToString(), JsonContext.Default.Person); + Assert.IsType(response).Validate(); + + response = await client.DeleteFromJsonAsync(uri, JsonContext.Default.Person); + Assert.IsType(response).Validate(); + + response = await client.DeleteFromJsonAsync(uri.ToString(), JsonContext.Default.Person, CancellationToken.None); + Assert.IsType(response).Validate(); + + response = await client.DeleteFromJsonAsync(uri, JsonContext.Default.Person, CancellationToken.None); + Assert.IsType(response).Validate(); + } + }, + async server => { + HttpRequestData request = await server.HandleRequestAsync(); + Assert.Equal("DELETE", request.Method); + + List headers = new List { new HttpHeaderData("Content-Type", "application/json") }; + string json = Person.Create().Serialize(); + await server.HandleRequestAsync(content: json, headers: headers, statusCode: HttpStatusCode.Accepted); + }); + } + [Fact] public void TestHttpClientIsNullAsync() { From 495d08fb282af42154b9e7bc2019527426609f4b Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Mon, 13 Jun 2022 12:51:09 -0400 Subject: [PATCH 085/337] [mono][wasm] Avoid falling back to the interpreter for generic delegate invocation (#70653) * [mono][jit] Fix the handling of delegate invokes wrappers in mini_get_shared_method_full (). Previously, we computed the shared version of the wrapper created from the invoke method on the generic type definition. This always returned a shared instance with ref gparams even if the original method had valuetype generic arguments. * [mono][aot] Fix the addition of delegate invoke wrappers. Previously, these were added using add_method (), which didn't try to use generic sharing, so the actual instance was added, and the shared version was not. This led to increased executable size and the shared versions were not found at runtime, causing fallbacks to the interpreter. --- src/mono/mono/mini/aot-compiler.c | 2 +- src/mono/mono/mini/mini-generic-sharing.c | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 3c551b139facbd..bd751c1f956508 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -5490,7 +5490,7 @@ add_generic_class_with_depth (MonoAotCompile *acfg, MonoClass *klass, int depth, if (acfg->aot_opts.log_generics) aot_printf (acfg, "%*sAdding method %s.\n", depth, "", mono_method_get_full_name (method)); - add_method (acfg, method); + add_extra_method_with_depth (acfg, method, 0); } /* Add superclasses */ diff --git a/src/mono/mono/mini/mini-generic-sharing.c b/src/mono/mono/mini/mini-generic-sharing.c index 2fb32e0c08b8d2..23911dc0bffe01 100644 --- a/src/mono/mono/mini/mini-generic-sharing.c +++ b/src/mono/mono/mini/mini-generic-sharing.c @@ -4280,7 +4280,9 @@ mini_get_shared_method_full (MonoMethod *method, GetSharedMethodFlags flags, Mon } case MONO_WRAPPER_DELEGATE_INVOKE: { if (info->subtype == WRAPPER_SUBTYPE_NONE) { - MonoMethod *ginvoke = mini_get_shared_method_full (info->d.delegate_invoke.method, flags, error); + MonoMethod *m = mono_class_inflate_generic_method_checked (info->d.delegate_invoke.method, context, error); + return_val_if_nok (error, NULL); + MonoMethod *ginvoke = mini_get_shared_method_full (m, flags, error); return_val_if_nok (error, NULL); return mono_marshal_get_delegate_invoke (ginvoke, NULL); @@ -4289,7 +4291,9 @@ mini_get_shared_method_full (MonoMethod *method, GetSharedMethodFlags flags, Mon } case MONO_WRAPPER_DELEGATE_BEGIN_INVOKE: case MONO_WRAPPER_DELEGATE_END_INVOKE: { - MonoMethod *ginvoke = mini_get_shared_method_full (info->d.delegate_invoke.method, flags, error); + MonoMethod *m = mono_class_inflate_generic_method_checked (info->d.delegate_invoke.method, context, error); + return_val_if_nok (error, NULL); + MonoMethod *ginvoke = mini_get_shared_method_full (m, flags, error); return_val_if_nok (error, NULL); if (method->wrapper_type == MONO_WRAPPER_DELEGATE_BEGIN_INVOKE) From 52077ff5161533dd84003ff2aa608e4f4abd7e53 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Mon, 13 Jun 2022 13:34:21 -0400 Subject: [PATCH 086/337] [mono][wasm] Enable a subset of the gc_pin area optimizations. (#70465) The OP_ARG one causes random crashes. --- src/mono/mono/mini/mini-llvm.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/mono/mono/mini/mini-llvm.c b/src/mono/mono/mini/mini-llvm.c index 444f39ac8b7a13..d2e5b30058014d 100644 --- a/src/mono/mono/mini/mini-llvm.c +++ b/src/mono/mono/mini/mini-llvm.c @@ -216,6 +216,7 @@ typedef struct { GHashTable *jit_callees; LLVMValueRef long_bb_break_var; int *gc_var_indexes; + int gc_var_indexes_len; Address *gc_pin_area; LLVMValueRef il_state; LLVMValueRef il_state_ret; @@ -3858,11 +3859,10 @@ emit_gc_pin (EmitContext *ctx, LLVMBuilderRef builder, int vreg) { if (ctx->values [vreg] == LLVMConstNull (IntPtrType ())) return; -#if 0 MonoInst *var = get_vreg_to_inst (ctx->cfg, vreg); if (var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT|MONO_INST_IS_DEAD)) return; -#endif + g_assert (vreg < ctx->gc_var_indexes_len); LLVMValueRef index0 = const_int32 (0); LLVMValueRef index1 = const_int32 (ctx->gc_var_indexes [vreg] - 1); LLVMValueRef indexes [] = { index0, index1 }; @@ -3905,6 +3905,7 @@ emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder) if (vreg_is_ref (cfg, i)) { ctx->gc_var_indexes [i] = ngc_vars + 1; ngc_vars ++; + ctx->gc_var_indexes_len = i + 1; /* MonoInst *var = get_vreg_to_inst (ctx->cfg, i); if (!(var && var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT|MONO_INST_IS_DEAD))) { @@ -11339,8 +11340,8 @@ MONO_RESTORE_WARNING if (!skip_volatile_store) emit_volatile_store (ctx, ins->dreg); #ifdef TARGET_WASM - //if (vreg_is_ref (cfg, ins->dreg) && ctx->values [ins->dreg] && ins->opcode != OP_MOVE) - if (vreg_is_ref (cfg, ins->dreg) && ctx->values [ins->dreg]) + //if (vreg_is_ref (cfg, ins->dreg) && ctx->values [ins->dreg]) + if (vreg_is_ref (cfg, ins->dreg) && ctx->values [ins->dreg] && ins->opcode != OP_MOVE) emit_gc_pin (ctx, builder, ins->dreg); #endif } @@ -11836,7 +11837,8 @@ emit_method_inner (EmitContext *ctx) LLVMSetGC (method, "coreclr"); emit_gc_safepoint_poll (ctx->module, ctx->lmodule, cfg); } else { - LLVMSetGC (method, "coreclr"); + if (!cfg->llvm_only) + LLVMSetGC (method, "coreclr"); } } LLVMSetLinkage (method, LLVMPrivateLinkage); From 9b19542580e93012985939ab132dc69b688fd6d8 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Mon, 13 Jun 2022 13:36:49 -0400 Subject: [PATCH 087/337] Use hash one-shots for key adjustment in HMACCommon --- .../System/Security/Cryptography/HMACCommon.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACCommon.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACCommon.cs index 7e64fc27c8da90..fec3c37cd3c620 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACCommon.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HMACCommon.cs @@ -57,12 +57,15 @@ public void ChangeKey(byte[] key) if (key.Length > _blockSize && _blockSize > 0) { // Perform RFC 2104, section 2 key adjustment. - if (_lazyHashProvider == null) + modifiedKey = _hashAlgorithmId switch { - _lazyHashProvider = HashProviderDispenser.CreateHashProvider(_hashAlgorithmId); - } - _lazyHashProvider.AppendHashData(key); - modifiedKey = _lazyHashProvider.FinalizeHashAndReset(); + HashAlgorithmNames.SHA256 => SHA256.HashData(key), + HashAlgorithmNames.SHA384 => SHA384.HashData(key), + HashAlgorithmNames.SHA512 => SHA512.HashData(key), + HashAlgorithmNames.SHA1 => SHA1.HashData(key), + HashAlgorithmNames.MD5 when Helpers.HasMD5 => MD5.HashData(key), + _ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, _hashAlgorithmId)), + }; } HashProvider? oldHashProvider = _hMacProvider; @@ -105,14 +108,11 @@ public void Dispose(bool disposing) { _hMacProvider?.Dispose(true); _hMacProvider = null!; - _lazyHashProvider?.Dispose(true); - _lazyHashProvider = null; } } private readonly string _hashAlgorithmId; private HashProvider _hMacProvider; - private volatile HashProvider? _lazyHashProvider; private readonly int _blockSize; } } From 098b14239fa8cb1f64c7790b7f1f095151d00df8 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Mon, 13 Jun 2022 14:17:19 -0400 Subject: [PATCH 088/337] [wasm] Re-enable previously failing tests - System.IO.FileSystem (#70594) Fixes https://github.com/dotnet/runtime/issues/40536 --- src/libraries/System.IO.FileSystem/tests/Directory/Delete.cs | 1 - src/libraries/System.IO.FileSystem/tests/Directory/Move.cs | 1 - src/libraries/System.IO.FileSystem/tests/DirectoryInfo/MoveTo.cs | 1 - 3 files changed, 3 deletions(-) diff --git a/src/libraries/System.IO.FileSystem/tests/Directory/Delete.cs b/src/libraries/System.IO.FileSystem/tests/Directory/Delete.cs index f95eeca12fb8b0..fa6cc76cda47b9 100644 --- a/src/libraries/System.IO.FileSystem/tests/Directory/Delete.cs +++ b/src/libraries/System.IO.FileSystem/tests/Directory/Delete.cs @@ -247,7 +247,6 @@ public void RecursiveDelete() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/40536", TestPlatforms.Browser)] public void RecursiveDeleteWithTrailingSlash() { DirectoryInfo testDir = Directory.CreateDirectory(GetTestFilePath()); diff --git a/src/libraries/System.IO.FileSystem/tests/Directory/Move.cs b/src/libraries/System.IO.FileSystem/tests/Directory/Move.cs index e5fef2369b95f9..a9d2c482e3f066 100644 --- a/src/libraries/System.IO.FileSystem/tests/Directory/Move.cs +++ b/src/libraries/System.IO.FileSystem/tests/Directory/Move.cs @@ -173,7 +173,6 @@ public void DirectoryNameWithSpaces() } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/40536", TestPlatforms.Browser)] public void TrailingDirectorySeparators() { string testDirSource = Path.Combine(TestDirectory, GetTestFileName()); diff --git a/src/libraries/System.IO.FileSystem/tests/DirectoryInfo/MoveTo.cs b/src/libraries/System.IO.FileSystem/tests/DirectoryInfo/MoveTo.cs index fba22eb092824b..e5e5478fcb39df 100644 --- a/src/libraries/System.IO.FileSystem/tests/DirectoryInfo/MoveTo.cs +++ b/src/libraries/System.IO.FileSystem/tests/DirectoryInfo/MoveTo.cs @@ -24,7 +24,6 @@ protected virtual void Move(DirectoryInfo sourceDir, string destDir) #region UniversalTests [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/40536", TestPlatforms.Browser)] public void DirectoryPathUpdatesOnMove() { //NOTE: MoveTo adds a trailing separator character to the FullName of a DirectoryInfo From 6418252c4ebc07c059c4e5c8d3e12be63433f7ae Mon Sep 17 00:00:00 2001 From: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> Date: Mon, 13 Jun 2022 22:01:47 +0300 Subject: [PATCH 089/337] Use the signature types when building ABI info (#70635) * Use signature types when building the ABI info This will allow us to let "mismatched" struct types as call arguments, which in turn is expected to simplify and de-pessimize much of the code working around the need to keep precise handles on struct nodes. Credit to @jakobbotsch for being able to make this change. * Work around the "InferOpSizeAlign" problem Handling it generally requires solving a larger problem of "eeGetArgSizeAlignment" not working well on ARM. (See also the use of "eeGetArgSizeAlignment" in "lvaInitUserArgs") --- src/coreclr/jit/codegencommon.cpp | 29 --------- src/coreclr/jit/compiler.h | 5 -- src/coreclr/jit/lower.cpp | 8 +-- src/coreclr/jit/morph.cpp | 100 +++++++++++++++--------------- 4 files changed, 54 insertions(+), 88 deletions(-) diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index ed16b9a9fa4984..044aa740a19d59 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -6581,35 +6581,6 @@ bool Compiler::IsHfa(CORINFO_CLASS_HANDLE hClass) return varTypeIsValidHfaType(GetHfaType(hClass)); } -bool Compiler::IsHfa(GenTree* tree) -{ - if (GlobalJitOptions::compFeatureHfa) - { - return IsHfa(gtGetStructHandleIfPresent(tree)); - } - else - { - return false; - } -} - -var_types Compiler::GetHfaType(GenTree* tree) -{ - if (GlobalJitOptions::compFeatureHfa) - { - return GetHfaType(gtGetStructHandleIfPresent(tree)); - } - else - { - return TYP_UNDEF; - } -} - -unsigned Compiler::GetHfaCount(GenTree* tree) -{ - return GetHfaCount(gtGetStructHandle(tree)); -} - var_types Compiler::GetHfaType(CORINFO_CLASS_HANDLE hClass) { if (GlobalJitOptions::compFeatureHfa) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index c838b9e9c7268f..8df241aacce85d 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -1882,11 +1882,6 @@ class Compiler // bool IsHfa(CORINFO_CLASS_HANDLE hClass); - bool IsHfa(GenTree* tree); - - var_types GetHfaType(GenTree* tree); - unsigned GetHfaCount(GenTree* tree); - var_types GetHfaType(CORINFO_CLASS_HANDLE hClass); unsigned GetHfaCount(CORINFO_CLASS_HANDLE hClass); diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index 49dde8acd1fd41..c560f369529b0f 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -3814,18 +3814,18 @@ void Lowering::LowerCallStruct(GenTreeCall* call) if (GlobalJitOptions::compFeatureHfa) { - if (comp->IsHfa(call)) + if (comp->IsHfa(call->gtRetClsHnd)) { #if defined(TARGET_ARM64) - assert(comp->GetHfaCount(call) == 1); + assert(comp->GetHfaCount(call->gtRetClsHnd) == 1); #elif defined(TARGET_ARM) // ARM returns double in 2 float registers, but // `call->HasMultiRegRetVal()` count double registers. - assert(comp->GetHfaCount(call) <= 2); + assert(comp->GetHfaCount(call->gtRetClsHnd) <= 2); #else // !TARGET_ARM64 && !TARGET_ARM NYI("Unknown architecture"); #endif // !TARGET_ARM64 && !TARGET_ARM - var_types hfaType = comp->GetHfaType(call); + var_types hfaType = comp->GetHfaType(call->gtRetClsHnd); if (call->TypeIs(hfaType)) { return; diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 4e65b06d9a75fc..c571c48a7545f8 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -2233,7 +2233,12 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call argx->gtType = TYP_I_IMPL; } - // Setup any HFA information about 'argx' + // Note we must use the signature types for making ABI decisions. This is especially important for structs, + // where the "argx" node can legally have a type that is not ABI-compatible with the one in the signature. + const var_types argSigType = arg.GetSignatureType(); + const CORINFO_CLASS_HANDLE argSigClass = arg.GetSignatureClassHandle(); + + // Setup any HFA information about the argument. bool isHfaArg = false; var_types hfaType = TYP_UNDEF; unsigned hfaSlots = 0; @@ -2245,7 +2250,7 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call if (GlobalJitOptions::compFeatureHfa) { - hfaType = comp->GetHfaType(argx); + hfaType = comp->GetHfaType(argSigClass); isHfaArg = varTypeIsValidHfaType(hfaType); #if defined(TARGET_ARM64) @@ -2258,7 +2263,7 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call if (isHfaArg) { - hfaSlots = comp->GetHfaCount(argx); + hfaSlots = comp->GetHfaCount(argSigClass); // If we have a HFA struct it's possible we transition from a method that originally // only had integer types to now start having FP types. We have to communicate this @@ -2272,11 +2277,19 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call const bool isFloatHfa = (hfaType == TYP_FLOAT); #ifdef TARGET_ARM - passUsingFloatRegs = !callIsVararg && (isHfaArg || varTypeUsesFloatReg(argx)) && !comp->opts.compUseSoftFP; + passUsingFloatRegs = + !callIsVararg && (isHfaArg || varTypeUsesFloatReg(argSigType)) && !comp->opts.compUseSoftFP; bool passUsingIntRegs = passUsingFloatRegs ? false : (intArgRegNum < MAX_REG_ARG); - // We don't use the "size" return value from InferOpSizeAlign(). - comp->codeGen->InferOpSizeAlign(argx, &argAlignBytes); + // TODO-Cleanup: use "eeGetArgSizeAlignment" here. See also: https://github.com/dotnet/runtime/issues/46026. + if (varTypeIsStruct(argSigType)) + { + argAlignBytes = comp->info.compCompHnd->getClassAlignmentRequirement(argSigClass); + } + else + { + argAlignBytes = genTypeSize(argSigType); + } argAlignBytes = roundUp(argAlignBytes, TARGET_POINTER_SIZE); @@ -2303,11 +2316,11 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call #elif defined(TARGET_ARM64) assert(!callIsVararg || !isHfaArg); - passUsingFloatRegs = !callIsVararg && (isHfaArg || varTypeUsesFloatReg(argx)); + passUsingFloatRegs = !callIsVararg && (isHfaArg || varTypeUsesFloatReg(argSigType)); #elif defined(TARGET_AMD64) - passUsingFloatRegs = varTypeIsFloating(argx); + passUsingFloatRegs = varTypeIsFloating(argSigType); #elif defined(TARGET_X86) @@ -2316,7 +2329,7 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call #elif defined(TARGET_LOONGARCH64) assert(!callIsVararg && !isHfaArg); - passUsingFloatRegs = varTypeUsesFloatReg(argx); + passUsingFloatRegs = varTypeUsesFloatReg(argSigType); DWORD floatFieldFlags = STRUCT_NO_FLOAT_FIELD; #else @@ -2325,43 +2338,34 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call bool isBackFilled = false; unsigned nextFltArgRegNum = fltArgRegNum; // This is the next floating-point argument register number to use + bool isStructArg = varTypeIsStruct(argSigType); var_types structBaseType = TYP_STRUCT; unsigned structSize = 0; bool passStructByRef = false; - bool isStructArg; - GenTree* actualArg = argx->gtEffectiveVal(true /* Commas only */); - // // Figure out the size of the argument. This is either in number of registers, or number of // TARGET_POINTER_SIZE stack slots, or the sum of these if the argument is split between the registers and // the stack. // - isStructArg = varTypeIsStruct(argx); - // Note that we internally in the JIT can change some struct args to - // primitive args (e.g. OBJ(x) -> IND(x)). Similarly, - // the ABI type can also change from struct to primitive (e.g. a 8-byte - // struct passed in a register). So isStructArg may be false even if - // the signature type was (or is) a struct, however only in cases where - // it does not matter. - CORINFO_CLASS_HANDLE objClass = NO_CLASS_HANDLE; + if (isStructArg) { - objClass = comp->gtGetStructHandle(argx); - if (argx->TypeGet() == TYP_STRUCT) + GenTree* actualArg = argx->gtEffectiveVal(true /* Commas only */); + + // Here we look at "actualArg" to avoid calling "getClassSize". + if (actualArg->TypeGet() == TYP_STRUCT) { - // For TYP_STRUCT arguments we must have an OBJ, LCL_VAR or MKREFANY switch (actualArg->OperGet()) { case GT_OBJ: - structSize = actualArg->AsObj()->GetLayout()->GetSize(); - assert(structSize == comp->info.compCompHnd->getClassSize(objClass)); + structSize = actualArg->AsObj()->Size(); break; case GT_LCL_VAR: structSize = comp->lvaGetDesc(actualArg->AsLclVarCommon())->lvExactSize; break; case GT_MKREFANY: - structSize = comp->info.compCompHnd->getClassSize(objClass); + structSize = comp->info.compCompHnd->getClassSize(argSigClass); break; default: BADCODE("illegal argument tree: cannot determine size for ABI handling"); @@ -2370,28 +2374,29 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call } else { - structSize = genTypeSize(argx); - assert(structSize == comp->info.compCompHnd->getClassSize(objClass)); + structSize = genTypeSize(actualArg); } + + assert(structSize = comp->info.compCompHnd->getClassSize(argSigClass)); } #if defined(TARGET_AMD64) #ifdef UNIX_AMD64_ABI if (!isStructArg) { size = 1; // On AMD64, all primitives fit in a single (64-bit) 'slot' - byteSize = genTypeSize(arg.GetSignatureType()); + byteSize = genTypeSize(argSigType); } else { size = (unsigned)(roundUp(structSize, TARGET_POINTER_SIZE)) / TARGET_POINTER_SIZE; byteSize = structSize; - comp->eeGetSystemVAmd64PassStructInRegisterDescriptor(objClass, &structDesc); + comp->eeGetSystemVAmd64PassStructInRegisterDescriptor(argSigClass, &structDesc); } #else // !UNIX_AMD64_ABI size = 1; // On AMD64 Windows, all args fit in a single (64-bit) 'slot' if (!isStructArg) { - byteSize = genTypeSize(arg.GetSignatureType()); + byteSize = genTypeSize(argSigType); } #endif // UNIX_AMD64_ABI @@ -2402,9 +2407,8 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call { // HFA structs are passed by value in multiple registers. // The "size" in registers may differ the size in pointer-sized units. - CORINFO_CLASS_HANDLE structHnd = comp->gtGetStructHandle(argx); - size = comp->GetHfaCount(structHnd); - byteSize = comp->info.compCompHnd->getClassSize(structHnd); + size = hfaSlots; + byteSize = structSize; } else { @@ -2420,13 +2424,13 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call size = 1; } } - // Note that there are some additional rules for multireg structs. + // Note that there are some additional rules for multireg structs on ARM64. // (i.e they cannot be split between registers and the stack) } else { size = 1; // Otherwise, all primitive types fit in a single (64-bit) 'slot' - byteSize = genTypeSize(arg.GetSignatureType()); + byteSize = genTypeSize(argSigType); } #elif defined(TARGET_ARM) || defined(TARGET_X86) if (isStructArg) @@ -2438,8 +2442,8 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call { // The typical case. // Long/double type argument(s) will be modified as needed in Lowering. - size = genTypeStSz(argx->gtType); - byteSize = genTypeSize(arg.GetSignatureType()); + size = genTypeStSz(argSigType); + byteSize = genTypeSize(argSigType); } #else #error Unsupported or unset target architecture @@ -2451,14 +2455,14 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call assert(structSize != 0); Compiler::structPassingKind howToPassStruct; - structBaseType = comp->getArgTypeForStruct(objClass, &howToPassStruct, callIsVararg, structSize); + structBaseType = comp->getArgTypeForStruct(argSigClass, &howToPassStruct, callIsVararg, structSize); passStructByRef = (howToPassStruct == Compiler::SPK_ByReference); #if defined(TARGET_LOONGARCH64) if (!passStructByRef) { assert((howToPassStruct == Compiler::SPK_ByValue) || (howToPassStruct == Compiler::SPK_PrimitiveType)); - floatFieldFlags = comp->info.compCompHnd->getLoongArch64PassStructInRegisterFlags(objClass); + floatFieldFlags = comp->info.compCompHnd->getLoongArch64PassStructInRegisterFlags(argSigClass); passUsingFloatRegs = (floatFieldFlags & STRUCT_HAS_FLOAT_FIELDS_MASK) ? true : false; comp->compFloatingPointUsed |= passUsingFloatRegs; @@ -2469,8 +2473,7 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call // for "struct { float, float }", and retyping to a primitive here will cause the // multi-reg morphing to not kick in (the struct in question needs to be passed in // two FP registers). Here is just keep "structBaseType" as "TYP_STRUCT". - // TODO-LoongArch64: fix "getPrimitiveTypeForStruct" or use the ABI information in - // the arg entry instead of calling it here. + // TODO-LoongArch64: fix "getPrimitiveTypeForStruct". structBaseType = TYP_STRUCT; } @@ -2529,7 +2532,7 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call // Arm64 Apple has a special ABI for passing small size arguments on stack, // bytes are aligned to 1-byte, shorts to 2-byte, int/float to 4-byte, etc. // It means passing 8 1-byte arguments on stack can take as small as 8 bytes. - argAlignBytes = comp->eeGetArgSizeAlignment(arg.GetSignatureType(), isFloatHfa); + argAlignBytes = comp->eeGetArgSizeAlignment(argSigType, isFloatHfa); } #ifdef TARGET_LOONGARCH64 @@ -2541,11 +2544,11 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call bool isRegArg = false; regNumber nonStdRegNum = REG_NA; - if (isRegParamType(genActualType(argx->TypeGet())) + if (isRegParamType(genActualType(argSigType)) #ifdef UNIX_AMD64_ABI && (!isStructArg || structDesc.passedInRegisters) #elif defined(TARGET_X86) - || (isStructArg && comp->isTrivialPointerSizedStruct(objClass)) + || (isStructArg && comp->isTrivialPointerSizedStruct(argSigClass)) #endif ) { @@ -3001,12 +3004,9 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call #endif } - if (GlobalJitOptions::compFeatureHfa) + if (isHfaArg) { - if (isHfaArg) - { - arg.AbiInfo.SetHfaType(hfaType, hfaSlots); - } + arg.AbiInfo.SetHfaType(hfaType, hfaSlots); } arg.AbiInfo.SetMultiRegNums(); From 4277bc519d24bd3073a5026e3eebf9f87faf6056 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Mon, 13 Jun 2022 16:08:32 -0400 Subject: [PATCH 090/337] [wasm] Build WasmAppHost with UseAppHost=false (#70606) * [wasm] Build WasmAppHost with UseAppHost=false - WasmAppHost is included in the WebAssembly.Sdk pack, and doesn't have a platform specific package. - Since, this is being built for x64, the build defaults to using the app host, which means that we get a single binary file that can be run directly. - But this also means that the binary included in the WebAssembly.Sdk platform-agnostic package will target the platform where it was built. - Instead, build with UseAppHost=false, and update the wasm host to use the managed assembly instead. And update the RunCommand to use `dotnet exec WasmAppHost.dll`. * fix --- src/mono/wasm/build/WasmApp.targets | 5 +++-- .../wasm/debugger/BrowserDebugHost/BrowserDebugHost.csproj | 1 + src/mono/wasm/host/WasmAppHost.csproj | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/mono/wasm/build/WasmApp.targets b/src/mono/wasm/build/WasmApp.targets index 1fe3c7cddb8c2e..6c43547f2e03a7 100644 --- a/src/mono/wasm/build/WasmApp.targets +++ b/src/mono/wasm/build/WasmApp.targets @@ -120,8 +120,9 @@ - $([MSBuild]::NormalizePath($(WasmAppHostDir), 'WasmAppHost')) - --runtime-config $(_AppBundleDirForRunCommand)/$(AssemblyName).runtimeconfig.json $(WasmHostArguments) + $(DOTNET_HOST_PATH) + dotnet + exec $([MSBuild]::NormalizePath($(WasmAppHostDir), 'WasmAppHost.dll')) --runtime-config $(_AppBundleDirForRunCommand)/$(AssemblyName).runtimeconfig.json $(WasmHostArguments) $(_AppBundleDirForRunCommand) diff --git a/src/mono/wasm/debugger/BrowserDebugHost/BrowserDebugHost.csproj b/src/mono/wasm/debugger/BrowserDebugHost/BrowserDebugHost.csproj index 66d0b287f76559..5bb950ac301d68 100644 --- a/src/mono/wasm/debugger/BrowserDebugHost/BrowserDebugHost.csproj +++ b/src/mono/wasm/debugger/BrowserDebugHost/BrowserDebugHost.csproj @@ -4,6 +4,7 @@ $(AspNetCoreAppCurrent) true $(NoWarn),CA2007 + false diff --git a/src/mono/wasm/host/WasmAppHost.csproj b/src/mono/wasm/host/WasmAppHost.csproj index ece55d3763c43a..eb563352f198fd 100644 --- a/src/mono/wasm/host/WasmAppHost.csproj +++ b/src/mono/wasm/host/WasmAppHost.csproj @@ -5,6 +5,7 @@ true $(NoWarn),CA2007 enable + false From 025b7638ce84c404eb4cdc1a12ea114029e511fc Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Mon, 13 Jun 2022 22:59:21 +0200 Subject: [PATCH 091/337] JIT: Optimize expansion of indir cell addresses for CFG (#70491) On ARM64 it is expensive to materialize the address of an indirection cell since that requires multiple instructions. This is particular a problem when CFG is enabled where validation + call uses the indir cell twice. This changes the CFG logic to create a local in this case. We also were forcing the indir cell argument node into the register. This is not ideal for this particular case, so remove this logic and let LSRA deal with it. ARM still needs this logic. Fix #65076 --- src/coreclr/jit/gentree.h | 2 +- src/coreclr/jit/lower.cpp | 56 +++++++++++++++++++++++++++++++++--- src/coreclr/jit/morph.cpp | 21 +++++++------- src/coreclr/jit/valuenum.cpp | 15 ++++------ 4 files changed, 69 insertions(+), 25 deletions(-) diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index 6ef9cb3032e0af..13addb8b46768c 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -5309,7 +5309,7 @@ struct GenTreeCall final : public GenTree #if defined(TARGET_ARMARCH) // For ARM architectures, we always use an indirection cell for R2R calls. - if (IsR2RRelativeIndir()) + if (IsR2RRelativeIndir() && !IsDelegateInvoke()) { return WellKnownArg::R2RIndirectionCell; } diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index c560f369529b0f..f6626dc3e6f7b0 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -2283,10 +2283,58 @@ void Lowering::LowerCFGCall(GenTreeCall* call) } GenTree* callTarget = call->gtCallType == CT_INDIRECT ? call->gtCallAddr : call->gtControlExpr; - if ((callTarget == nullptr) || callTarget->IsIntegralConst()) + if (callTarget == nullptr) { - // This is a direct call, no CFG check is necessary. - return; + assert((call->gtCallType != CT_INDIRECT) && (!call->IsVirtual() || call->IsVirtualStubRelativeIndir())); + if (!call->IsVirtual()) + { + // Direct call with stashed address + return; + } + + // This is a VSD call with the call target being null because we are + // supposed to load it from the indir cell. Due to CFG we will need + // this address twice, and at least on ARM64 we do not want to + // materialize the constant both times. + CallArg* indirCellArg = call->gtArgs.FindWellKnownArg(WellKnownArg::VirtualStubCell); + assert((indirCellArg != nullptr) && indirCellArg->GetNode()->OperIs(GT_PUTARG_REG)); + + GenTreeOp* putArgNode = indirCellArg->GetNode()->AsOp(); + LIR::Use indirCellArgUse(BlockRange(), &putArgNode->gtOp1, putArgNode); + + // On non-xarch, we create a local even for constants. On xarch cloning + // the constant is better since it can be contained in the load below. + bool cloneConsts = false; +#ifdef TARGET_XARCH + cloneConsts = true; +#endif + + GenTree* indirCellClone; + + if (indirCellArgUse.Def()->OperIs(GT_LCL_VAR) || (cloneConsts && indirCellArgUse.Def()->IsCnsIntOrI())) + { + indirCellClone = comp->gtClone(indirCellArgUse.Def()); + } + else + { + unsigned newLcl = indirCellArgUse.ReplaceWithLclVar(comp); + indirCellClone = comp->gtNewLclvNode(newLcl, TYP_I_IMPL); + } + + callTarget = Ind(indirCellClone); + LIR::Range controlExprRange = LIR::SeqTree(comp, callTarget); + ContainCheckRange(controlExprRange); + + BlockRange().InsertBefore(call, std::move(controlExprRange)); + call->gtControlExpr = callTarget; + } + else + { + if (callTarget->IsIntegralConst()) + { + // This is a direct call, no CFG check is necessary. + return; + } } CFGCallKind cfgKind = call->GetCFGCallKind(); @@ -5127,7 +5175,7 @@ GenTree* Lowering::LowerVirtualStubCall(GenTreeCall* call) // Skip inserting the indirection node to load the address that is already // computed in the VSD stub arg register as a hidden parameter. Instead during the // codegen, just load the call target from there. - shouldOptimizeVirtualStubCall = !comp->opts.IsCFGEnabled(); + shouldOptimizeVirtualStubCall = true; #endif if (!shouldOptimizeVirtualStubCall) diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index c571c48a7545f8..1aa8b8cee2c94b 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -2108,18 +2108,20 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call size_t addrValue = (size_t)call->gtEntryPoint.addr; GenTree* indirectCellAddress = comp->gtNewIconHandleNode(addrValue, GTF_ICON_FTN_ADDR); INDEBUG(indirectCellAddress->AsIntCon()->gtTargetHandle = (size_t)call->gtCallMethHnd); - indirectCellAddress->SetRegNum(REG_R2R_INDIRECT_PARAM); + #ifdef TARGET_ARM - // Issue #xxxx : Don't attempt to CSE this constant on ARM32 - // - // This constant has specific register requirements, and LSRA doesn't currently correctly - // handle them when the value is in a CSE'd local. + // TODO-ARM: We currently do not properly kill this register in LSRA + // (see getKillSetForCall which does so only for VSD calls). + // We should be able to remove these two workarounds once we do so, + // however when this was tried there were significant regressions. + indirectCellAddress->SetRegNum(REG_R2R_INDIRECT_PARAM); indirectCellAddress->SetDoNotCSE(); -#endif // TARGET_ARM +#endif // Push the stub address onto the list of arguments. - InsertAfterThisOrFirst(comp, - NewCallArg::Primitive(indirectCellAddress).WellKnown(WellKnownArg::R2RIndirectionCell)); + NewCallArg indirCellAddrArg = + NewCallArg::Primitive(indirectCellAddress).WellKnown(WellKnownArg::R2RIndirectionCell); + InsertAfterThisOrFirst(comp, indirCellAddrArg); } #endif @@ -7917,7 +7919,7 @@ void Compiler::fgMorphTailCallViaJitHelper(GenTreeCall* call) // call - a call that needs virtual stub dispatching. // // Return Value: -// addr tree with set resister requirements. +// addr tree // GenTree* Compiler::fgGetStubAddrArg(GenTreeCall* call) { @@ -7935,7 +7937,6 @@ GenTree* Compiler::fgGetStubAddrArg(GenTreeCall* call) INDEBUG(stubAddrArg->AsIntCon()->gtTargetHandle = (size_t)call->gtCallMethHnd); } assert(stubAddrArg != nullptr); - stubAddrArg->SetRegNum(virtualStubParamInfo->GetReg()); return stubAddrArg; } diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index c97fb6dc11ce14..802115117e706e 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -9682,19 +9682,14 @@ void Compiler::fgValueNumberHelperCallFunc(GenTreeCall* call, VNFunc vnf, ValueN vnpUniq.SetBoth(vnStore->VNForExpr(compCurBB, call->TypeGet())); } -#if defined(FEATURE_READYTORUN) && (defined(TARGET_ARMARCH) || defined(TARGET_LOONGARCH64)) - if (call->IsR2RRelativeIndir()) + if (call->GetIndirectionCellArgKind() != WellKnownArg::None) { -#ifdef DEBUG - GenTree* indirectCellAddress = args->GetArgByIndex(0)->GetNode(); - assert(indirectCellAddress->IsCnsIntOrI() && indirectCellAddress->GetRegNum() == REG_R2R_INDIRECT_PARAM); -#endif // DEBUG - - // For ARM indirectCellAddress is consumed by the call itself, so it should have added as an implicit argument - // in morph. So we do not need to use EntryPointAddrAsArg0, because arg0 is already an entry point addr. + // If we are VN'ing a call with indirection cell arg (e.g. because this + // is a helper in a R2R compilation) then morph should already have + // added this arg, so we do not need to use EntryPointAddrAsArg0 + // because the indirection cell itself allows us to disambiguate. useEntryPointAddrAsArg0 = false; } -#endif // FEATURE_READYTORUN && (TARGET_ARMARCH || TARGET_LOONGARCH64) CallArg* curArg = &*args->Args().begin(); if (nArgs == 0) From 15f1e1d5e83d8ab76ab605624ef0cdd004229032 Mon Sep 17 00:00:00 2001 From: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> Date: Tue, 14 Jun 2022 01:01:23 +0300 Subject: [PATCH 092/337] Handle mis-sized structs in XARCH `PUTARG_STK` codegen (#68611) * Handle "mis-sized" structs in XARCH PUTARG_STK codegen Previously, for structs which were not a multiple of TARGET_POINTER_SIZE in size: 1) On x86, we copied them to a local in morph. This was a small CQ issue. 2) On Unix x64, we didn't handle them at all and could read out of bounds in "genStructPutArgUnroll". This change fixes both issues by properly detecting cases where we need to be careful and updating codegen to use correct load sizes. * Add a test --- src/coreclr/jit/codegenxarch.cpp | 73 +++++++++---------- src/coreclr/jit/gentree.h | 43 ++++++++++- src/coreclr/jit/lowerxarch.cpp | 20 ++--- src/coreclr/jit/lsraxarch.cpp | 20 +++-- src/coreclr/jit/morph.cpp | 30 -------- .../JitBlue/Runtime_65937/Runtime_65937.cs | 71 ++++++++++++++++++ .../Runtime_65937/Runtime_65937.csproj | 11 +++ 7 files changed, 178 insertions(+), 90 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_65937/Runtime_65937.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_65937/Runtime_65937.csproj diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index bb1206bfb5c5bf..4435e2aea5f691 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -3471,36 +3471,34 @@ unsigned CodeGen::genMove1IfNeeded(unsigned size, regNumber intTmpReg, GenTree* void CodeGen::genStructPutArgUnroll(GenTreePutArgStk* putArgNode) { GenTree* src = putArgNode->AsOp()->gtOp1; - // We will never call this method for SIMD types, which are stored directly - // in genPutStructArgStk(). + // We will never call this method for SIMD types, which are stored directly in genPutStructArgStk(). assert(src->isContained() && src->OperIs(GT_OBJ) && src->TypeIs(TYP_STRUCT)); - assert(!src->AsObj()->GetLayout()->HasGCPtr()); #ifdef TARGET_X86 assert(!m_pushStkArg); #endif - unsigned size = putArgNode->GetStackByteSize(); -#ifdef TARGET_X86 - assert((XMM_REGSIZE_BYTES <= size) && (size <= CPBLK_UNROLL_LIMIT)); -#else // !TARGET_X86 - assert(size <= CPBLK_UNROLL_LIMIT); -#endif // !TARGET_X86 - if (src->AsOp()->gtOp1->isUsedFromReg()) { genConsumeReg(src->AsOp()->gtOp1); } + unsigned loadSize = putArgNode->GetArgLoadSize(); + assert(!src->AsObj()->GetLayout()->HasGCPtr() && (loadSize <= CPBLK_UNROLL_LIMIT)); + unsigned offset = 0; regNumber xmmTmpReg = REG_NA; regNumber intTmpReg = REG_NA; regNumber longTmpReg = REG_NA; - if (size >= XMM_REGSIZE_BYTES) +#ifdef TARGET_X86 + if (loadSize >= 8) +#else + if (loadSize >= XMM_REGSIZE_BYTES) +#endif { xmmTmpReg = putArgNode->GetSingleTempReg(RBM_ALLFLOAT); } - if ((size % XMM_REGSIZE_BYTES) != 0) + if ((loadSize % XMM_REGSIZE_BYTES) != 0) { intTmpReg = putArgNode->GetSingleTempReg(RBM_ALLINT); } @@ -3512,7 +3510,7 @@ void CodeGen::genStructPutArgUnroll(GenTreePutArgStk* putArgNode) #endif // Let's use SSE2 to be able to do 16 byte at a time with loads and stores. - size_t slots = size / XMM_REGSIZE_BYTES; + size_t slots = loadSize / XMM_REGSIZE_BYTES; while (slots-- > 0) { // TODO: In the below code the load and store instructions are for 16 bytes, but the @@ -3528,13 +3526,13 @@ void CodeGen::genStructPutArgUnroll(GenTreePutArgStk* putArgNode) } // Fill the remainder (15 bytes or less) if there's one. - if ((size % XMM_REGSIZE_BYTES) != 0) + if ((loadSize % XMM_REGSIZE_BYTES) != 0) { - offset += genMove8IfNeeded(size, longTmpReg, src->AsOp()->gtOp1, offset); - offset += genMove4IfNeeded(size, intTmpReg, src->AsOp()->gtOp1, offset); - offset += genMove2IfNeeded(size, intTmpReg, src->AsOp()->gtOp1, offset); - offset += genMove1IfNeeded(size, intTmpReg, src->AsOp()->gtOp1, offset); - assert(offset == size); + offset += genMove8IfNeeded(loadSize, longTmpReg, src->AsOp()->gtOp1, offset); + offset += genMove4IfNeeded(loadSize, intTmpReg, src->AsOp()->gtOp1, offset); + offset += genMove2IfNeeded(loadSize, intTmpReg, src->AsOp()->gtOp1, offset); + offset += genMove1IfNeeded(loadSize, intTmpReg, src->AsOp()->gtOp1, offset); + assert(offset == loadSize); } } @@ -3570,8 +3568,9 @@ void CodeGen::genStructPutArgRepMovs(GenTreePutArgStk* putArgNode) // putArgNode - the PutArgStk tree. // // Notes: -// Used only on x86, in two cases: +// Used (only) on x86 for: // - Structs 4, 8, or 12 bytes in size (less than XMM_REGSIZE_BYTES, multiple of TARGET_POINTER_SIZE). +// - Local structs less than 16 bytes in size (it is ok to load "too much" from our stack frame). // - Structs that contain GC pointers - they are guaranteed to be sized correctly by the VM. // void CodeGen::genStructPutArgPush(GenTreePutArgStk* putArgNode) @@ -3605,9 +3604,9 @@ void CodeGen::genStructPutArgPush(GenTreePutArgStk* putArgNode) } ClassLayout* layout = src->AsObj()->GetLayout(); - const unsigned byteSize = putArgNode->GetStackByteSize(); - assert((byteSize % TARGET_POINTER_SIZE == 0) && ((byteSize < XMM_REGSIZE_BYTES) || layout->HasGCPtr())); - const unsigned numSlots = byteSize / TARGET_POINTER_SIZE; + const unsigned loadSize = putArgNode->GetArgLoadSize(); + assert(((loadSize < XMM_REGSIZE_BYTES) || layout->HasGCPtr()) && ((loadSize % TARGET_POINTER_SIZE) == 0)); + const unsigned numSlots = loadSize / TARGET_POINTER_SIZE; for (int i = numSlots - 1; i >= 0; --i) { @@ -3654,9 +3653,9 @@ void CodeGen::genStructPutArgPartialRepMovs(GenTreePutArgStk* putArgNode) #endif // DEBUG assert(layout->HasGCPtr()); - const unsigned byteSize = putArgNode->GetStackByteSize(); - assert(byteSize % TARGET_POINTER_SIZE == 0); - const unsigned numSlots = byteSize / TARGET_POINTER_SIZE; + const unsigned argSize = putArgNode->GetStackByteSize(); + assert(argSize % TARGET_POINTER_SIZE == 0); + const unsigned numSlots = argSize / TARGET_POINTER_SIZE; // No need to disable GC the way COPYOBJ does. Here the refs are copied in atomic operations always. for (unsigned i = 0; i < numSlots;) @@ -5525,23 +5524,17 @@ void CodeGen::genCall(GenTreeCall* call) GenTree* argNode = arg.GetEarlyNode(); if (argNode->OperIs(GT_PUTARG_STK) && (arg.GetLateNode() == nullptr)) { - GenTree* source = argNode->AsPutArgStk()->gtGetOp1(); - unsigned size = argNode->AsPutArgStk()->GetStackByteSize(); - stackArgBytes += size; + GenTree* source = argNode->AsPutArgStk()->gtGetOp1(); + unsigned argSize = argNode->AsPutArgStk()->GetStackByteSize(); + stackArgBytes += argSize; + #ifdef DEBUG - assert(size == arg.AbiInfo.ByteSize); + assert(argSize == arg.AbiInfo.ByteSize); #ifdef FEATURE_PUT_STRUCT_ARG_STK - if (!source->OperIs(GT_FIELD_LIST) && (source->TypeGet() == TYP_STRUCT)) + if (source->TypeIs(TYP_STRUCT) && !source->OperIs(GT_FIELD_LIST)) { - GenTreeObj* obj = source->AsObj(); - unsigned argBytes = roundUp(obj->GetLayout()->GetSize(), TARGET_POINTER_SIZE); -#ifdef TARGET_X86 - // If we have an OBJ, we must have created a copy if the original arg was not a - // local and was not a multiple of TARGET_POINTER_SIZE. - // Note that on x64/ux this will be handled by unrolling in genStructPutArgUnroll. - assert((argBytes == obj->GetLayout()->GetSize()) || obj->Addr()->IsLocalAddrExpr()); -#endif // TARGET_X86 - assert(arg.AbiInfo.ByteSize == argBytes); + unsigned loadSize = source->AsObj()->GetLayout()->GetSize(); + assert(argSize == roundUp(loadSize, TARGET_POINTER_SIZE)); } #endif // FEATURE_PUT_STRUCT_ARG_STK #endif // DEBUG diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index 13addb8b46768c..b4057c9d033ed7 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -7442,12 +7442,18 @@ struct GenTreePutArgStk : public GenTreeUnOp // TODO-Throughput: The following information should be obtained from the child // block node. - enum class Kind : __int8{ + enum class Kind : int8_t{ Invalid, RepInstr, PartialRepInstr, Unroll, Push, }; Kind gtPutArgStkKind; -#endif +#ifdef TARGET_XARCH +private: + uint8_t m_argLoadSizeDelta; +#endif // TARGET_XARCH +#endif // FEATURE_PUT_STRUCT_ARG_STK + +public: GenTreePutArgStk(genTreeOps oper, var_types type, GenTree* op1, @@ -7473,7 +7479,10 @@ struct GenTreePutArgStk : public GenTreeUnOp #endif // FEATURE_FASTTAILCALL #if defined(FEATURE_PUT_STRUCT_ARG_STK) , gtPutArgStkKind(Kind::Invalid) +#if defined(TARGET_XARCH) + , m_argLoadSizeDelta(UINT8_MAX) #endif +#endif // FEATURE_PUT_STRUCT_ARG_STK { } @@ -7520,6 +7529,36 @@ struct GenTreePutArgStk : public GenTreeUnOp return m_byteSize; } +#ifdef TARGET_XARCH + //------------------------------------------------------------------------ + // SetArgLoadSize: Set the optimal number of bytes to load for this argument. + // + // On XARCH, it is profitable to use wider loads when our source is a local + // variable. To not duplicate the logic between lowering, LSRA and codegen, + // we do the legality check once, in lowering, and save the result here, as + // a negative delta relative to the size of the argument with padding. + // + // Arguments: + // loadSize - The optimal number of bytes to load + // + void SetArgLoadSize(unsigned loadSize) + { + unsigned argSize = GetStackByteSize(); + assert(roundUp(loadSize, TARGET_POINTER_SIZE) == argSize); + + m_argLoadSizeDelta = static_cast(argSize - loadSize); + } + + //------------------------------------------------------------------------ + // GetArgLoadSize: Get the optimal number of bytes to load for this argument. + // + unsigned GetArgLoadSize() const + { + assert(m_argLoadSizeDelta != UINT8_MAX); + return GetStackByteSize() - m_argLoadSizeDelta; + } +#endif // TARGET_XARCH + // Return true if this is a PutArgStk of a SIMD12 struct. // This is needed because such values are re-typed to SIMD16, and the type of PutArgStk is VOID. unsigned isSIMD12() const diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp index f0004d7113cc1c..ee9b370d61866b 100644 --- a/src/coreclr/jit/lowerxarch.cpp +++ b/src/coreclr/jit/lowerxarch.cpp @@ -556,30 +556,24 @@ void Lowering::LowerPutArgStk(GenTreePutArgStk* putArgStk) // The cpyXXXX code is rather complex and this could cause it to be more complex, but // it might be the right thing to do. - unsigned size = putArgStk->GetStackByteSize(); - unsigned loadSize = layout->GetSize(); - - assert(loadSize <= size); + // If possible, widen the load, this results in more compact code. + unsigned loadSize = srcIsLocal ? roundUp(layout->GetSize(), TARGET_POINTER_SIZE) : layout->GetSize(); + putArgStk->SetArgLoadSize(loadSize); // TODO-X86-CQ: The helper call either is not supported on x86 or required more work // (I don't know which). - if (!layout->HasGCPtr()) { #ifdef TARGET_X86 // Codegen for "Kind::Push" will always load bytes in TARGET_POINTER_SIZE - // chunks. As such, the correctness of this code depends on the fact that - // morph will copy any "mis-sized" (too small) non-local OBJs into a temp, - // thus preventing any possible out-of-bounds memory reads. - assert(((layout->GetSize() % TARGET_POINTER_SIZE) == 0) || src->OperIsLocalRead() || - (src->OperIsIndir() && src->AsIndir()->Addr()->IsLocalAddrExpr())); - if (size < XMM_REGSIZE_BYTES) + // chunks. As such, we'll only use this path for correctly-sized sources. + if ((loadSize < XMM_REGSIZE_BYTES) && ((loadSize % TARGET_POINTER_SIZE) == 0)) { putArgStk->gtPutArgStkKind = GenTreePutArgStk::Kind::Push; } else #endif // TARGET_X86 - if (size <= CPBLK_UNROLL_LIMIT) + if (loadSize <= CPBLK_UNROLL_LIMIT) { putArgStk->gtPutArgStkKind = GenTreePutArgStk::Kind::Unroll; } @@ -615,7 +609,7 @@ void Lowering::LowerPutArgStk(GenTreePutArgStk* putArgStk) // so if possible, widen the load to avoid the sign/zero-extension. if (varTypeIsSmall(regType) && srcIsLocal) { - assert(putArgStk->GetStackByteSize() <= genTypeSize(TYP_INT)); + assert(genTypeSize(TYP_INT) <= putArgStk->GetStackByteSize()); regType = TYP_INT; } diff --git a/src/coreclr/jit/lsraxarch.cpp b/src/coreclr/jit/lsraxarch.cpp index 5386ed5769558c..5be7b32972da62 100644 --- a/src/coreclr/jit/lsraxarch.cpp +++ b/src/coreclr/jit/lsraxarch.cpp @@ -1561,21 +1561,31 @@ int LinearScan::BuildPutArgStk(GenTreePutArgStk* putArgStk) return BuildOperandUses(src); } - ssize_t size = putArgStk->GetStackByteSize(); + unsigned loadSize = putArgStk->GetArgLoadSize(); switch (putArgStk->gtPutArgStkKind) { case GenTreePutArgStk::Kind::Unroll: // If we have a remainder smaller than XMM_REGSIZE_BYTES, we need an integer temp reg. - if ((size % XMM_REGSIZE_BYTES) != 0) + if ((loadSize % XMM_REGSIZE_BYTES) != 0) { regMaskTP regMask = allRegs(TYP_INT); +#ifdef TARGET_X86 + // Storing at byte granularity requires a byteable register. + if ((loadSize & 1) != 0) + { + regMask &= allByteRegs(); + } +#endif // TARGET_X86 buildInternalIntRegisterDefForNode(putArgStk, regMask); } - if (size >= XMM_REGSIZE_BYTES) +#ifdef TARGET_X86 + if (loadSize >= 8) +#else + if (loadSize >= XMM_REGSIZE_BYTES) +#endif { - // If we have a buffer larger than or equal to XMM_REGSIZE_BYTES, reserve - // an XMM register to use it for a series of 16-byte loads and stores. + // See "genStructPutArgUnroll" -- we will use this XMM register for wide stores. buildInternalFloatRegisterDefForNode(putArgStk, internalFloatRegCandidates()); SetContainsAVXFlags(); } diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 1aa8b8cee2c94b..1ecb8dab146b0e 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -3437,36 +3437,6 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call) assert(varTypeIsEnregisterable(argObj->TypeGet()) || (makeOutArgCopy && varTypeIsEnregisterable(structBaseType))); } - -#if !defined(UNIX_AMD64_ABI) && !defined(TARGET_ARMARCH) && !defined(TARGET_LOONGARCH64) - // TODO-CQ-XARCH: there is no need for a temp copy if we improve our code generation in - // `genPutStructArgStk` for xarch like we did it for Arm/Arm64. - - // We still have a struct unless we converted the GT_OBJ into a GT_IND above... - if (isHfaArg && passUsingFloatRegs) - { - } - else if (structBaseType == TYP_STRUCT) - { - // If the valuetype size is not a multiple of TARGET_POINTER_SIZE, - // we must copyblk to a temp before doing the obj to avoid - // the obj reading memory past the end of the valuetype - if (roundupSize > originalSize) - { - makeOutArgCopy = true; - - // There are a few special cases where we can omit using a CopyBlk - // where we normally would need to use one. - - if (argObj->OperIs(GT_OBJ) && - argObj->AsObj()->gtGetOp1()->IsLocalAddrExpr() != nullptr) // Is the source a LclVar? - { - makeOutArgCopy = false; - } - } - } - -#endif // !UNIX_AMD64_ABI } } diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_65937/Runtime_65937.cs b/src/tests/JIT/Regression/JitBlue/Runtime_65937/Runtime_65937.cs new file mode 100644 index 00000000000000..2591dd373a0fe5 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_65937/Runtime_65937.cs @@ -0,0 +1,71 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +public unsafe class Runtime_65937 +{ + [MethodImpl(MethodImplOptions.NoInlining)] + public static int Main() + { + if (!OperatingSystem.IsLinux()) + { + return 100; + } + + const int PROT_NONE = 0x0; + const int PROT_READ = 0x1; + const int PROT_WRITE = 0x2; + const int MAP_PRIVATE = 0x02; + const int MAP_ANONYMOUS = 0x20; + const int PAGE_SIZE = 0x1000; + + byte* pages = (byte*)mmap(null, 2 * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + if (pages == (byte*)-1) + { + Console.WriteLine("Failed to allocate two pages, errno is {0}, giving up on the test", Marshal.GetLastSystemError()); + return 100; + } + + if (mprotect(pages + PAGE_SIZE, PAGE_SIZE, PROT_NONE) != 0) + { + Console.WriteLine("Failed to protect the second page, errno is {0}, giving up on the test", Marshal.GetLastSystemError()); + munmap(pages, 2 * PAGE_SIZE); + return 100; + } + + CallWithStkArg(0, 0, 0, 0, 0, 0, *(StructWithNineBytes*)(pages + PAGE_SIZE - sizeof(StructWithNineBytes))); + + munmap(pages, 2 * PAGE_SIZE); + + return 100; + } + + struct StructWithNineBytes + { + byte ByteOne; + byte ByteTwo; + byte ByteThree; + byte ByteFour; + byte ByteFive; + byte ByteSix; + byte ByteSeven; + byte ByteEight; + byte ByteNine; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void CallWithStkArg(int a, int b, int c, int d, int e, int f, StructWithNineBytes stkArg) { } + + [DllImport("libc")] + private static extern void* mmap(void* addr, nuint length, int prot, int flags, int fd, nuint offset); + + [DllImport("libc")] + private static extern int mprotect(void* addr, nuint len, int prot); + + [DllImport("libc")] + private static extern int munmap(void* addr, nuint length); +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_65937/Runtime_65937.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_65937/Runtime_65937.csproj new file mode 100644 index 00000000000000..9379af57e1c721 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_65937/Runtime_65937.csproj @@ -0,0 +1,11 @@ + + + None + True + Exe + true + + + + + From 59b2dd9fa373588d400b5f432773b6b5164ad389 Mon Sep 17 00:00:00 2001 From: Levi Broderick Date: Mon, 13 Jun 2022 16:43:31 -0700 Subject: [PATCH 093/337] Improve distribution of CoseHeaderLabel hash codes (#70695) --- .../src/System/HashCodeRandomization.cs | 58 +++++++++++++++++++ .../System.Security.Cryptography.Cose.csproj | 6 ++ .../Cryptography/Cose/CoseHeaderLabel.cs | 8 ++- .../tests/CoseHeaderLabelTests.cs | 36 ++++++++---- 4 files changed, 94 insertions(+), 14 deletions(-) create mode 100644 src/libraries/Common/src/System/HashCodeRandomization.cs diff --git a/src/libraries/Common/src/System/HashCodeRandomization.cs b/src/libraries/Common/src/System/HashCodeRandomization.cs new file mode 100644 index 00000000000000..16cd6cb577c052 --- /dev/null +++ b/src/libraries/Common/src/System/HashCodeRandomization.cs @@ -0,0 +1,58 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System +{ + // Contains helpers for calculating randomized hash codes of common types. + // Since these hash codes are randomized, callers must not persist them between + // AppDomain restarts. There's still the potential for limited collisions + // if two distinct types have the same bit pattern (e.g., string.Empty and (int)0). + // This should be acceptable because the number of practical collisions is + // limited by the number of distinct types used here, and we expect callers to + // have a small, fixed set of accepted types for any hash-based collection. + // If we really do need to address this in the future, we can use a seed per type + // rather than a global seed for the entire AppDomain. + internal static class HashCodeRandomization + { + public static int GetRandomizedOrdinalHashCode(this string value) + { +#if NETCOREAPP + // In .NET Core, string hash codes are already randomized. + + return value.GetHashCode(); +#else + // Downlevel, we need to perform randomization ourselves. There's still + // the potential for limited collisions ("Hello!" and "Hello!\0"), but + // this shouldn't be a problem in practice. If we need to address it, + // we can mix the string length into the accumulator before running the + // string contents through. + // + // We'll pull out pairs of chars and write 32 bits at a time. + + HashCode hashCode = default; + int pair = 0; + for (int i = 0; i < value.Length; i++) + { + int ch = value[i]; + if ((i & 1) == 0) + { + pair = ch << 16; // first member of pair + } + else + { + pair |= ch; // second member of pair + hashCode.Add(pair); // write pair as single unit + pair = 0; + } + } + hashCode.Add(pair); // flush any leftover data (could be 0 or 1 chars) + return hashCode.ToHashCode(); +#endif + } + + public static int GetRandomizedHashCode(this int value) + { + return HashCode.Combine(value); + } + } +} diff --git a/src/libraries/System.Security.Cryptography.Cose/src/System.Security.Cryptography.Cose.csproj b/src/libraries/System.Security.Cryptography.Cose/src/System.Security.Cryptography.Cose.csproj index 2c66e4920a1e71..e2ef885d16954b 100644 --- a/src/libraries/System.Security.Cryptography.Cose/src/System.Security.Cryptography.Cose.csproj +++ b/src/libraries/System.Security.Cryptography.Cose/src/System.Security.Cryptography.Cose.csproj @@ -13,6 +13,7 @@ + @@ -32,6 +33,11 @@ + + + + + diff --git a/src/libraries/System.Security.Cryptography.Cose/src/System/Security/Cryptography/Cose/CoseHeaderLabel.cs b/src/libraries/System.Security.Cryptography.Cose/src/System/Security/Cryptography/Cose/CoseHeaderLabel.cs index e3fd261674f31d..1c800f871fcda7 100644 --- a/src/libraries/System.Security.Cryptography.Cose/src/System/Security/Cryptography/Cose/CoseHeaderLabel.cs +++ b/src/libraries/System.Security.Cryptography.Cose/src/System/Security/Cryptography/Cose/CoseHeaderLabel.cs @@ -54,12 +54,16 @@ public bool Equals(CoseHeaderLabel other) public override int GetHashCode() { + // Since this type is used as a key in a dictionary (see CoseHeaderMap) + // and since the label is potentially adversary-provided, we'll need + // to randomize the hash code. + if (LabelAsString != null) { - return LabelAsString.GetHashCode(); + return LabelAsString.GetRandomizedOrdinalHashCode(); } - return LabelAsInt32.GetHashCode(); + return LabelAsInt32.GetRandomizedHashCode(); } public static bool operator ==(CoseHeaderLabel left, CoseHeaderLabel right) => left.Equals(right); diff --git a/src/libraries/System.Security.Cryptography.Cose/tests/CoseHeaderLabelTests.cs b/src/libraries/System.Security.Cryptography.Cose/tests/CoseHeaderLabelTests.cs index a7d65a1d9a5216..d4c4b44b296879 100644 --- a/src/libraries/System.Security.Cryptography.Cose/tests/CoseHeaderLabelTests.cs +++ b/src/libraries/System.Security.Cryptography.Cose/tests/CoseHeaderLabelTests.cs @@ -10,23 +10,35 @@ public class CoseHeaderLabelTests [Fact] public void CoseHeaderLabel_GetHashCode() { - CoseHeaderLabel label = default; - Assert.Equal(0, label.GetHashCode()); // There's no need to call GetHashCode on integers as they are their own hashcode. + // First, construct a COSE header of (0) using several different methods. + // They should all have the same hash code, though we don't know what + // the hash code is. - label = new CoseHeaderLabel(); - Assert.Equal(0, label.GetHashCode()); + CoseHeaderLabel label1 = default; + CoseHeaderLabel label2 = new CoseHeaderLabel(); + CoseHeaderLabel label3 = new CoseHeaderLabel(0); - label = new CoseHeaderLabel(0); - Assert.Equal(0, label.GetHashCode()); + int label1HashCode = label1.GetHashCode(); + Assert.Equal(label1HashCode, label2.GetHashCode()); + Assert.Equal(label1HashCode, label3.GetHashCode()); - label = new CoseHeaderLabel(""); - Assert.Equal("".GetHashCode(), label.GetHashCode()); + // Make sure the integer hash code calculation really is randomized. + // Checking 1 & 2 together rather than independently cuts the false + // positive rate down to nearly 1 in 2^64. - label = new CoseHeaderLabel(1); - Assert.Equal(1, label.GetHashCode()); + bool isReturningNormalInt32HashCode = + (new CoseHeaderLabel(1).GetHashCode() == 1) + && (new CoseHeaderLabel(2).GetHashCode() == 2); + Assert.False(isReturningNormalInt32HashCode); - label = new CoseHeaderLabel("content-type"); - Assert.Equal("content-type".GetHashCode(), label.GetHashCode()); + // Make sure the string hash code calculation really is randomized. + // Checking 1 & 2 together rather than independently cuts the false + // positive rate down to nearly 1 in 2^64. + + bool isReturningNormalStringHashCode = + (new CoseHeaderLabel("Hello").GetHashCode() == "Hello".GetHashCode()) + && (new CoseHeaderLabel("World").GetHashCode() == "World".GetHashCode()); + Assert.Equal(PlatformDetection.IsNetCore, isReturningNormalStringHashCode); } [Fact] From fbae62d1f9b3b6e97edaa73c98b376bd70ba1b1b Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Mon, 13 Jun 2022 20:19:02 -0400 Subject: [PATCH 094/337] Implement digest one shots for browser implementation --- .../HashProviderDispenser.Browser.cs | 13 +++-- .../SHAHashProvider.Browser.Native.cs | 50 +++++++++++-------- 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Browser.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Browser.cs index e6c394d6220b48..1326aeb0420f9d 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Browser.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/HashProviderDispenser.Browser.cs @@ -39,9 +39,16 @@ public static unsafe int MacData( public static int HashData(string hashAlgorithmId, ReadOnlySpan source, Span destination) { - HashProvider provider = CreateHashProvider(hashAlgorithmId); - provider.AppendHashData(source); - return provider.FinalizeHashAndReset(destination); + if (CanUseSubtleCryptoImpl) + { + return SHANativeHashProvider.HashOneShot(hashAlgorithmId, source, destination); + } + else + { + HashProvider provider = CreateHashProvider(hashAlgorithmId); + provider.AppendHashData(source); + return provider.FinalizeHashAndReset(destination); + } } } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHAHashProvider.Browser.Native.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHAHashProvider.Browser.Native.cs index c037761aafb541..e7748e607a71a9 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHAHashProvider.Browser.Native.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SHAHashProvider.Browser.Native.cs @@ -19,28 +19,7 @@ internal sealed class SHANativeHashProvider : HashProvider public SHANativeHashProvider(string hashAlgorithmId) { Debug.Assert(HashProviderDispenser.CanUseSubtleCryptoImpl); - - switch (hashAlgorithmId) - { - case HashAlgorithmNames.SHA1: - _impl = SimpleDigest.Sha1; - _hashSizeInBytes = 20; - break; - case HashAlgorithmNames.SHA256: - _impl = SimpleDigest.Sha256; - _hashSizeInBytes = 32; - break; - case HashAlgorithmNames.SHA384: - _impl = SimpleDigest.Sha384; - _hashSizeInBytes = 48; - break; - case HashAlgorithmNames.SHA512: - _impl = SimpleDigest.Sha512; - _hashSizeInBytes = 64; - break; - default: - throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId)); - } + (_impl, _hashSizeInBytes) = HashAlgorithmToPal(hashAlgorithmId); } public override void AppendHashData(ReadOnlySpan data) @@ -82,6 +61,21 @@ public override int GetCurrentHash(Span destination) return _hashSizeInBytes; } + public static unsafe int HashOneShot(string hashAlgorithmId, ReadOnlySpan data, Span destination) + { + (SimpleDigest impl, int hashSizeInBytes) = HashAlgorithmToPal(hashAlgorithmId); + Debug.Assert(destination.Length >= hashSizeInBytes); + + fixed (byte* src = data) + fixed (byte* dest = destination) + { + int res = Interop.BrowserCrypto.SimpleDigestHash(impl, src, data.Length, dest, destination.Length); + Debug.Assert(res != 0); + } + + return hashSizeInBytes; + } + public override int HashSizeInBytes => _hashSizeInBytes; public override void Dispose(bool disposing) @@ -92,5 +86,17 @@ public override void Reset() { _buffer = null; } + + private static (SimpleDigest, int) HashAlgorithmToPal(string hashAlgorithmId) + { + return hashAlgorithmId switch + { + HashAlgorithmNames.SHA256 => (SimpleDigest.Sha256, SHA256.HashSizeInBytes), + HashAlgorithmNames.SHA1 => (SimpleDigest.Sha1, SHA1.HashSizeInBytes), + HashAlgorithmNames.SHA384 => (SimpleDigest.Sha384, SHA384.HashSizeInBytes), + HashAlgorithmNames.SHA512 => (SimpleDigest.Sha512, SHA512.HashSizeInBytes), + _ => throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmId)), + }; + } } } From a34444147a3d53bbcad15b4fe42d1fe9813a8637 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Mon, 13 Jun 2022 20:40:10 -0400 Subject: [PATCH 095/337] [wasm] Don't use a fixed listening port for the proxy (#70681) Fixes https://github.com/dotnet/runtime/issues/70670 . --- src/mono/wasm/debugger/BrowserDebugProxy/ProxyOptions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/ProxyOptions.cs b/src/mono/wasm/debugger/BrowserDebugProxy/ProxyOptions.cs index cf7f4318604820..ca8084795b1148 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/ProxyOptions.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/ProxyOptions.cs @@ -11,9 +11,9 @@ public class ProxyOptions { public Uri DevToolsUrl { get; set; } = new Uri($"http://localhost:9222"); public int? OwnerPid { get; set; } - public int FirefoxProxyPort { get; set; } = 6300; + public int FirefoxProxyPort { get; set; } public int FirefoxDebugPort { get; set; } = 6000; - public int DevToolsProxyPort { get; set; } = 9300; + public int DevToolsProxyPort { get; set; } public int DevToolsDebugPort { get => DevToolsUrl.Port; From 731c2626594e0aee5231f78894845d36e23bc7ae Mon Sep 17 00:00:00 2001 From: Mike McLaughlin Date: Mon, 13 Jun 2022 18:26:28 -0700 Subject: [PATCH 096/337] Fix SOS tests on 7.0 (#70677) The wcscpy_s in ClrDataAccess::GetRegisterName was failing with an invalid parameter exception because the prefixLen and regLen didn't include the terminating null wchar. --- src/coreclr/debug/daccess/request.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/coreclr/debug/daccess/request.cpp b/src/coreclr/debug/daccess/request.cpp index f73b1ce8afa2c1..35aac26d72b222 100644 --- a/src/coreclr/debug/daccess/request.cpp +++ b/src/coreclr/debug/daccess/request.cpp @@ -647,9 +647,10 @@ ClrDataAccess::GetRegisterName(int regNum, unsigned int count, _Inout_updates_z_ return E_UNEXPECTED; const WCHAR callerPrefix[] = W("caller."); - unsigned int prefixLen = (unsigned int)ARRAY_SIZE(callerPrefix) - 1; - unsigned int regLen = (unsigned int)wcslen(regs[regNum]); - unsigned int needed = (callerFrame?prefixLen:0) + regLen + 1; + // Include null terminator in prefixLen/regLen because wcscpy_s will fail otherwise + unsigned int prefixLen = (unsigned int)ARRAY_SIZE(callerPrefix); + unsigned int regLen = (unsigned int)wcslen(regs[regNum]) + 1; + unsigned int needed = (callerFrame ? prefixLen - 1 : 0) + regLen; if (pNeeded) *pNeeded = needed; @@ -662,6 +663,8 @@ ClrDataAccess::GetRegisterName(int regNum, unsigned int count, _Inout_updates_z_ { unsigned int toCopy = prefixLen < destSize ? prefixLen : destSize; wcscpy_s(curr, toCopy, callerPrefix); + // Point to null terminator + toCopy--; curr += toCopy; destSize -= toCopy; } @@ -670,6 +673,8 @@ ClrDataAccess::GetRegisterName(int regNum, unsigned int count, _Inout_updates_z_ { unsigned int toCopy = regLen < destSize ? regLen : destSize; wcscpy_s(curr, toCopy, regs[regNum]); + // Point to null terminator + toCopy--; curr += toCopy; destSize -= toCopy; } From 367193d0854a75e258ff57f913b8f640c8dbb751 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Mon, 13 Jun 2022 22:17:52 -0400 Subject: [PATCH 097/337] [wasm] Enable some previously failing WBT/AOT tests on windows (#70595) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [wasm] Enable some previously failing WBT/AOT tests on windows Fixes https://github.com/dotnet/runtime/issues/61725 . * [wasm] WBT: Fix a failing satellite assembly test The test fails because it is trying to find the string `got: こんにちは` in the app output, but it sees `?????`. This is due to xharness not setting the console output to UTF8, and then the tests not doing the same. Instead of that, we can move the check to be in the app itself, thus removing the need for any of this. Fixes https://github.com/dotnet/runtime/issues/58709 . --- .../Wasm.Build.Tests/MainWithArgsTests.cs | 2 - .../ReferenceNewAssemblyRebuildTest.cs | 1 - .../SatelliteAssembliesTests.cs | 47 ++++++++++--------- .../Wasm.Build.Tests/WasmBuildAppTest.cs | 2 - 4 files changed, 25 insertions(+), 27 deletions(-) diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/MainWithArgsTests.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/MainWithArgsTests.cs index 4411b821634b75..b21c3db75c55c6 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/MainWithArgsTests.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/MainWithArgsTests.cs @@ -25,7 +25,6 @@ public MainWithArgsTests(ITestOutputHelper output, SharedBuildPerTestClassFixtur ).WithRunHosts(host).UnwrapItemsAsArrays(); [Theory] - [ActiveIssue("https://github.com/dotnet/runtime/issues/61725", TestPlatforms.Windows)] [MemberData(nameof(MainWithArgsTestData), parameters: new object[] { /*aot*/ false, RunHost.All })] [MemberData(nameof(MainWithArgsTestData), parameters: new object[] { /*aot*/ true, RunHost.All })] public void AsyncMainWithArgs(BuildArgs buildArgs, string[] args, RunHost host, string id) @@ -40,7 +39,6 @@ public static async System.Threading.Tasks.Task Main(string[] args) buildArgs, args, host, id); [Theory] - [ActiveIssue("https://github.com/dotnet/runtime/issues/61725", TestPlatforms.Windows)] [MemberData(nameof(MainWithArgsTestData), parameters: new object[] { /*aot*/ false, RunHost.All })] [MemberData(nameof(MainWithArgsTestData), parameters: new object[] { /*aot*/ true, RunHost.All })] public void TopLevelWithArgs(BuildArgs buildArgs, string[] args, RunHost host, string id) diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/NativeRebuildTests/ReferenceNewAssemblyRebuildTest.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/NativeRebuildTests/ReferenceNewAssemblyRebuildTest.cs index d920ac400559ab..6f733b14c33ec3 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/NativeRebuildTests/ReferenceNewAssemblyRebuildTest.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/NativeRebuildTests/ReferenceNewAssemblyRebuildTest.cs @@ -20,7 +20,6 @@ public ReferenceNewAssemblyRebuildTest(ITestOutputHelper output, SharedBuildPerT } [Theory] - [ActiveIssue("https://github.com/dotnet/runtime/issues/61725", TestPlatforms.Windows)] [MemberData(nameof(NativeBuildData))] public void ReferenceNewAssembly(BuildArgs buildArgs, bool nativeRelink, bool invariant, RunHost host, string id) { diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/SatelliteAssembliesTests.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/SatelliteAssembliesTests.cs index 959a79221af885..1723e651acba3a 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/SatelliteAssembliesTests.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/SatelliteAssembliesTests.cs @@ -22,21 +22,19 @@ public SatelliteAssembliesTests(ITestOutputHelper output, SharedBuildPerTestClas public static IEnumerable SatelliteAssemblyTestData(bool aot, bool relinking, RunHost host) => ConfigWithAOTData(aot) .Multiply( - new object?[] { relinking, "es-ES", "got: hola" }, - new object?[] { relinking, null, "got: hello" }, - new object?[] { relinking, "ja-JP", "got: \u3053\u3093\u306B\u3061\u306F" }) + new object?[] { relinking, "es-ES" }, + new object?[] { relinking, null }, + new object?[] { relinking, "ja-JP" }) .WithRunHosts(host) .UnwrapItemsAsArrays(); [Theory] - [ActiveIssue("https://github.com/dotnet/runtime/issues/61725", TestPlatforms.Windows)] [MemberData(nameof(SatelliteAssemblyTestData), parameters: new object[] { /*aot*/ false, /*relinking*/ false, RunHost.All })] [MemberData(nameof(SatelliteAssemblyTestData), parameters: new object[] { /*aot*/ false, /*relinking*/ true, RunHost.All })] [MemberData(nameof(SatelliteAssemblyTestData), parameters: new object[] { /*aot*/ true, /*relinking*/ false, RunHost.All })] public void ResourcesFromMainAssembly(BuildArgs buildArgs, bool nativeRelink, string? argCulture, - string expectedOutput, RunHost host, string id) { @@ -62,25 +60,21 @@ public void ResourcesFromMainAssembly(BuildArgs buildArgs, }, DotnetWasmFromRuntimePack: dotnetWasmFromRuntimePack)); - string output = RunAndTestWasmApp( - buildArgs, expectedExitCode: 42, - args: argCulture, - host: host, id: id, - // check that downloading assets doesn't have timing race conditions - extraXHarnessMonoArgs: "--fetch-random-delay=200"); - - Assert.Contains(expectedOutput, output); + RunAndTestWasmApp( + buildArgs, expectedExitCode: 42, + args: argCulture, + host: host, id: id, + // check that downloading assets doesn't have timing race conditions + extraXHarnessMonoArgs: "--fetch-random-delay=200"); } [Theory] - [ActiveIssue("https://github.com/dotnet/runtime/issues/61725", TestPlatforms.Windows)] [MemberData(nameof(SatelliteAssemblyTestData), parameters: new object[] { /*aot*/ false, /*relinking*/ false, RunHost.All })] [MemberData(nameof(SatelliteAssemblyTestData), parameters: new object[] { /*aot*/ false, /*relinking*/ true, RunHost.All })] [MemberData(nameof(SatelliteAssemblyTestData), parameters: new object[] { /*aot*/ true, /*relinking*/ false, RunHost.All })] public void ResourcesFromProjectReference(BuildArgs buildArgs, bool nativeRelink, string? argCulture, - string expectedOutput, RunHost host, string id) { @@ -107,12 +101,10 @@ public void ResourcesFromProjectReference(BuildArgs buildArgs, CreateProgramForCultureTest(_projectDir, "LibraryWithResources.resx.words", "LibraryWithResources.Class1"); })); - string output = RunAndTestWasmApp(buildArgs, - expectedExitCode: 42, - args: argCulture, - host: host, id: id); - - Assert.Contains(expectedOutput, output); + RunAndTestWasmApp(buildArgs, + expectedExitCode: 42, + args: argCulture, + host: host, id: id); } #pragma warning disable xUnit1026 @@ -180,12 +172,23 @@ public class TestClass { public static int Main(string[] args) { + string expected; if (args.Length == 1) { string cultureToTest = args[0]; var newCulture = new CultureInfo(cultureToTest); Thread.CurrentThread.CurrentCulture = newCulture; Thread.CurrentThread.CurrentUICulture = newCulture; + + if (cultureToTest == ""es-ES"") + expected = ""hola""; + else if (cultureToTest == ""ja-JP"") + expected = ""\u3053\u3093\u306B\u3061\u306F""; + else + throw new Exception(""Cannot determine the expected output for {cultureToTest}""); + + } else { + expected = ""hello""; } var currentCultureName = Thread.CurrentThread.CurrentCulture.Name; @@ -193,7 +196,7 @@ public static int Main(string[] args) var rm = new ResourceManager(""##RESOURCE_NAME##"", typeof(##TYPE_NAME##).Assembly); Console.WriteLine($""For '{currentCultureName}' got: {rm.GetString(""hello"")}""); - return 42; + return rm.GetString(""hello"") == expected ? 42 : -1; } } }"; diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmBuildAppTest.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmBuildAppTest.cs index 1e8f600ec86b03..8a2eaa9f8b0b1c 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmBuildAppTest.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmBuildAppTest.cs @@ -16,7 +16,6 @@ public WasmBuildAppTest(ITestOutputHelper output, SharedBuildPerTestClassFixture {} [Theory] - [ActiveIssue("https://github.com/dotnet/runtime/issues/61725", TestPlatforms.Windows)] [MemberData(nameof(MainMethodTestData), parameters: new object[] { /*aot*/ true, RunHost.All })] [MemberData(nameof(MainMethodTestData), parameters: new object[] { /*aot*/ false, RunHost.All })] public void TopLevelMain(BuildArgs buildArgs, RunHost host, string id) @@ -25,7 +24,6 @@ public void TopLevelMain(BuildArgs buildArgs, RunHost host, string id) buildArgs, host, id); [Theory] - [ActiveIssue("https://github.com/dotnet/runtime/issues/61725", TestPlatforms.Windows)] [MemberData(nameof(MainMethodTestData), parameters: new object[] { /*aot*/ true, RunHost.All })] [MemberData(nameof(MainMethodTestData), parameters: new object[] { /*aot*/ false, RunHost.All })] public void AsyncMain(BuildArgs buildArgs, RunHost host, string id) From 20e5237104ddd178f12bc501352e45a5e91e5048 Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Mon, 13 Jun 2022 19:48:28 -0700 Subject: [PATCH 098/337] List other architectures and DOTNET_ROOT environment variables in dotnet --info (#70403) --- .../MultiArchInstallLocation.cs | 82 +++++++++++++++++++ .../tests/HostActivation.Tests/SDKLookup.cs | 2 +- src/installer/tests/TestUtils/DotNetCli.cs | 30 +++---- .../corehost/apphost/apphost.windows.cpp | 2 +- src/native/corehost/corehost.cpp | 4 +- src/native/corehost/deps_format.cpp | 2 +- src/native/corehost/fxr/command_line.cpp | 58 +++++++++---- src/native/corehost/fxr/command_line.h | 2 +- src/native/corehost/fxr/files.cmake | 2 + src/native/corehost/fxr/fx_muxer.cpp | 8 +- src/native/corehost/fxr/fx_resolver.cpp | 2 +- .../corehost/fxr/fx_resolver.messages.cpp | 4 +- src/native/corehost/fxr/install_info.cpp | 59 +++++++++++++ src/native/corehost/fxr/install_info.h | 15 ++++ src/native/corehost/fxr/sdk_resolver.cpp | 9 -- src/native/corehost/fxr/sdk_resolver.h | 1 - src/native/corehost/fxr_resolver.cpp | 4 +- src/native/corehost/hostmisc/pal.h | 26 +++++- src/native/corehost/hostmisc/pal.unix.cpp | 77 +++++++++++++---- src/native/corehost/hostmisc/pal.windows.cpp | 73 ++++++++++++++--- src/native/corehost/hostmisc/utils.cpp | 60 ++++++++++---- src/native/corehost/hostmisc/utils.h | 15 +++- src/native/corehost/hostpolicy/args.cpp | 8 +- .../corehost/hostpolicy/deps_resolver.cpp | 2 +- src/native/corehost/hostpolicy/hostpolicy.cpp | 2 +- 25 files changed, 435 insertions(+), 114 deletions(-) create mode 100644 src/native/corehost/fxr/install_info.cpp create mode 100644 src/native/corehost/fxr/install_info.h diff --git a/src/installer/tests/HostActivation.Tests/MultiArchInstallLocation.cs b/src/installer/tests/HostActivation.Tests/MultiArchInstallLocation.cs index a84ec8e3ef6d7b..fa7733f2c11e06 100644 --- a/src/installer/tests/HostActivation.Tests/MultiArchInstallLocation.cs +++ b/src/installer/tests/HostActivation.Tests/MultiArchInstallLocation.cs @@ -4,6 +4,7 @@ using System; using System.IO; using System.Runtime.InteropServices; +using Microsoft.DotNet.Cli.Build; using Microsoft.DotNet.Cli.Build.Framework; using Microsoft.DotNet.CoreSetup.Test; using Microsoft.DotNet.CoreSetup.Test.HostActivation; @@ -146,6 +147,44 @@ public void EnvironmentVariable_DotnetRootPathExistsButHasNoHost() } } + [Fact] + public void EnvironmentVariable_DotNetInfo_ListEnvironment() + { + var dotnet = new DotNetCli(sharedTestState.RepoDirectories.BuiltDotnet); + + var command = dotnet.Exec("--info") + .CaptureStdOut(); + + var envVars = new (string Architecture, string Path)[] { + ("arm64", "/arm64/dotnet/root"), + ("x64", "/x64/dotnet/root"), + ("x86", "/x86/dotnet/root") + }; + foreach(var envVar in envVars) + { + command = command.DotNetRoot(envVar.Path, envVar.Architecture); + } + + string dotnetRootNoArch = "/dotnet/root"; + command = command.DotNetRoot(dotnetRootNoArch); + + (string Architecture, string Path) unknownEnvVar = ("unknown", "/unknown/dotnet/root"); + command = command.DotNetRoot(unknownEnvVar.Path, unknownEnvVar.Architecture); + + var result = command.Execute(); + result.Should().Pass() + .And.HaveStdOutContaining("Environment variables:") + .And.HaveStdOutMatching($@"{Constants.DotnetRoot.EnvironmentVariable}\s*\[{dotnetRootNoArch}\]") + .And.NotHaveStdOutContaining($"{Constants.DotnetRoot.ArchitectureEnvironmentVariablePrefix}{unknownEnvVar.Architecture.ToUpper()}") + .And.NotHaveStdOutContaining($"[{unknownEnvVar.Path}]"); + + foreach ((string architecture, string path) in envVars) + { + result.Should() + .HaveStdOutMatching($@"{Constants.DotnetRoot.ArchitectureEnvironmentVariablePrefix}{architecture.ToUpper()}\s*\[{path}\]"); + } + } + [Fact] public void RegisteredInstallLocation_ArchSpecificLocationIsPickedFirst() { @@ -241,6 +280,49 @@ public void InstallLocationFile_MissingFile() } } + [Fact] + public void RegisteredInstallLocation_DotNetInfo_ListOtherArchitectures() + { + using (var testArtifact = new TestArtifact(SharedFramework.CalculateUniqueTestDirectory(Path.Combine(TestArtifact.TestArtifactsPath, "listOtherArchs")))) + { + var dotnet = new DotNetBuilder(testArtifact.Location, sharedTestState.RepoDirectories.BuiltDotnet, "exe").Build(); + using (var registeredInstallLocationOverride = new RegisteredInstallLocationOverride(dotnet.GreatestVersionHostFxrFilePath)) + { + var installLocations = new (string, string)[] { + ("arm64", "/arm64/install/path"), + ("x64", "/x64/install/path"), + ("x86", "/x86/install/path") + }; + (string Architecture, string Path) unknownArchInstall = ("unknown", "/unknown/install/path"); + registeredInstallLocationOverride.SetInstallLocation(installLocations); + registeredInstallLocationOverride.SetInstallLocation(unknownArchInstall); + + var result = dotnet.Exec("--info") + .CaptureStdOut() + .ApplyRegisteredInstallLocationOverride(registeredInstallLocationOverride) + .Execute(); + + result.Should().Pass() + .And.HaveStdOutContaining("Other architectures found:") + .And.NotHaveStdOutContaining(unknownArchInstall.Architecture) + .And.NotHaveStdOutContaining($"[{unknownArchInstall.Path}]"); + + string pathOverride = OperatingSystem.IsWindows() // Host uses short form of base key for Windows + ? registeredInstallLocationOverride.PathValueOverride.Replace(Microsoft.Win32.Registry.CurrentUser.Name, "HKCU") + : registeredInstallLocationOverride.PathValueOverride; + pathOverride = System.Text.RegularExpressions.Regex.Escape(pathOverride); + foreach ((string arch, string path) in installLocations) + { + if (arch == sharedTestState.RepoDirectories.BuildArchitecture) + continue; + + result.Should() + .HaveStdOutMatching($@"{arch}\s*\[{path}\]\r?$\s*registered at \[{pathOverride}.*{arch}.*\]", System.Text.RegularExpressions.RegexOptions.Multiline); + } + } + } + } + public class SharedTestState : IDisposable { public string BaseDirectory { get; } diff --git a/src/installer/tests/HostActivation.Tests/SDKLookup.cs b/src/installer/tests/HostActivation.Tests/SDKLookup.cs index 3828213e18ca59..7d28535c248a95 100644 --- a/src/installer/tests/HostActivation.Tests/SDKLookup.cs +++ b/src/installer/tests/HostActivation.Tests/SDKLookup.cs @@ -49,7 +49,7 @@ public void SdkLookup_Global_Json_Single_Digit_Patch_Rollup() .Should().Fail() .And.NotFindCompatibleSdk(globalJsonPath, requestedVersion) .And.FindAnySdk(false) - .And.HaveStdErrContaining("aka.ms/dotnet-download") + .And.HaveStdErrContaining("aka.ms/dotnet/download") .And.NotHaveStdErrContaining("Checking if resolved SDK dir"); // Add SDK versions diff --git a/src/installer/tests/TestUtils/DotNetCli.cs b/src/installer/tests/TestUtils/DotNetCli.cs index 513deea28b3b4d..08e40aaf25e6c1 100644 --- a/src/installer/tests/TestUtils/DotNetCli.cs +++ b/src/installer/tests/TestUtils/DotNetCli.cs @@ -12,7 +12,7 @@ public partial class DotNetCli { public string BinPath { get; } public string GreatestVersionSharedFxPath { get; } - public string GreatestVersionHostFxrPath { get; } + public string GreatestVersionHostFxrPath { get; } public string GreatestVersionHostFxrFilePath { get => Path.Combine( GreatestVersionHostFxrPath, RuntimeInformationExtensions.GetSharedLibraryFileNameForCurrentPlatform("hostfxr")); } @@ -29,30 +29,22 @@ public DotNetCli(string binPath) BinPath = binPath; var sharedFxBaseDirectory = Path.Combine(BinPath, "shared", "Microsoft.NETCore.App"); - if (!Directory.Exists(sharedFxBaseDirectory)) + if (Directory.Exists(sharedFxBaseDirectory)) { - GreatestVersionSharedFxPath = null; - return; + var sharedFxVersionDirectories = Directory.EnumerateDirectories(sharedFxBaseDirectory); + GreatestVersionSharedFxPath = sharedFxVersionDirectories + .OrderByDescending(p => p.ToLower()) + .First(); } var hostFxrBaseDirectory = Path.Combine(BinPath, "host", "fxr"); - - if (!Directory.Exists(hostFxrBaseDirectory)) + if (Directory.Exists(hostFxrBaseDirectory)) { - GreatestVersionHostFxrPath = null; - return; + var hostFxrVersionDirectories = Directory.EnumerateDirectories(hostFxrBaseDirectory); + GreatestVersionHostFxrPath = hostFxrVersionDirectories + .OrderByDescending(p => p.ToLower()) + .First(); } - - var sharedFxVersionDirectories = Directory.EnumerateDirectories(sharedFxBaseDirectory); - - GreatestVersionSharedFxPath = sharedFxVersionDirectories - .OrderByDescending(p => p.ToLower()) - .First(); - - var hostFxrVersionDirectories = Directory.EnumerateDirectories(hostFxrBaseDirectory); - GreatestVersionHostFxrPath = hostFxrVersionDirectories - .OrderByDescending(p => p.ToLower()) - .First(); } public Command Exec(string command, params string[] args) diff --git a/src/native/corehost/apphost/apphost.windows.cpp b/src/native/corehost/apphost/apphost.windows.cpp index c43f6105f59035..528ce95f859193 100644 --- a/src/native/corehost/apphost/apphost.windows.cpp +++ b/src/native/corehost/apphost/apphost.windows.cpp @@ -73,7 +73,7 @@ namespace pal::string_t get_apphost_details_message() { pal::string_t msg = _X("Architecture: "); - msg.append(get_arch()); + msg.append(get_current_arch_name()); msg.append(_X("\n") _X("App host version: ") _STRINGIFY(COMMON_HOST_PKG_VER) _X("\n\n")); return msg; diff --git a/src/native/corehost/corehost.cpp b/src/native/corehost/corehost.cpp index e8fa78647ef9c9..97a4e0753895cd 100644 --- a/src/native/corehost/corehost.cpp +++ b/src/native/corehost/corehost.cpp @@ -100,7 +100,7 @@ void need_newer_framework_error(const pal::string_t& dotnet_root, const pal::str _X("Download the .NET runtime:\n") _X("%s&apphost_version=%s"), host_path.c_str(), - get_arch(), + get_current_arch_name(), _STRINGIFY(COMMON_HOST_PKG_VER), dotnet_root.c_str(), get_download_url().c_str(), @@ -225,7 +225,7 @@ int exe_start(const int argc, const pal::char_t* argv[]) else { // An outdated hostfxr can only be found for framework-related apps. - trace::error(_X("The required library %s does not support single-file apps."), fxr.fxr_path().c_str()); + trace::error(_X("The required library %s does not support single-file apps."), fxr.fxr_path().c_str()); need_newer_framework_error(fxr.dotnet_root(), host_path); rc = StatusCode::FrameworkMissingFailure; } diff --git a/src/native/corehost/deps_format.cpp b/src/native/corehost/deps_format.cpp index 32f9d7c8df39ba..9abf6ae8f69223 100644 --- a/src/native/corehost/deps_format.cpp +++ b/src/native/corehost/deps_format.cpp @@ -130,7 +130,7 @@ pal::string_t deps_json_t::get_current_rid(const rid_fallback_graph_t& rid_fallb // We do the same even when the RID is empty. if (currentRid.empty() || (rid_fallback_graph.count(currentRid) == 0)) { - currentRid = pal::get_current_os_fallback_rid() + pal::string_t(_X("-")) + get_arch(); + currentRid = pal::get_current_os_fallback_rid() + pal::string_t(_X("-")) + get_current_arch_name(); trace::info(_X("Falling back to base HostRID: %s"), currentRid.c_str()); } diff --git a/src/native/corehost/fxr/command_line.cpp b/src/native/corehost/fxr/command_line.cpp index 7f6916273f9e38..ea04984877b572 100644 --- a/src/native/corehost/fxr/command_line.cpp +++ b/src/native/corehost/fxr/command_line.cpp @@ -4,6 +4,7 @@ #include "command_line.h" #include #include "framework_info.h" +#include "install_info.h" #include #include "sdk_info.h" #include @@ -279,37 +280,58 @@ int command_line::parse_args_for_sdk_command( return parse_args(host_info, 1, argc, argv, false, host_mode_t::muxer, new_argoff, app_candidate, opts); } -void command_line::print_muxer_info(const pal::string_t &dotnet_root) +void command_line::print_muxer_info(const pal::string_t &dotnet_root, const pal::string_t &global_json_path) { - trace::println(); - trace::println(_X("Host:")); - trace::println(_X(" Version: %s"), _STRINGIFY(HOST_FXR_PKG_VER)); - trace::println(_X(" Architecture: %s"), get_arch()); - pal::string_t commit = _STRINGIFY(REPO_COMMIT_HASH); - trace::println(_X(" Commit: %s"), commit.substr(0, 10).c_str()); - - trace::println(); - trace::println(_X(".NET SDKs installed:")); + trace::println(_X("\n") + _X("Host:\n") + _X(" Version: ") _STRINGIFY(HOST_FXR_PKG_VER) _X("\n") + _X(" Architecture: %s\n") + _X(" Commit: %s"), + get_current_arch_name(), + commit.substr(0, 10).c_str()); + + trace::println(_X("\n") + _X(".NET SDKs installed:")); if (!sdk_info::print_all_sdks(dotnet_root, _X(" "))) { trace::println(_X(" No SDKs were found.")); } - trace::println(); - trace::println(_X(".NET runtimes installed:")); + trace::println(_X("\n") + _X(".NET runtimes installed:")); if (!framework_info::print_all_frameworks(dotnet_root, _X(" "))) { trace::println(_X(" No runtimes were found.")); } - trace::println(); - trace::println(_X("Download .NET:")); - trace::println(_X(" %s"), DOTNET_CORE_DOWNLOAD_URL); + trace::println(_X("\n") + _X("Other architectures found:")); + if (!install_info::print_other_architectures(_X(" "))) + { + trace::println(_X(" None")); + } - trace::println(); - trace::println(_X("Learn about .NET Runtimes and SDKs:")); - trace::println(_X(" %s"), DOTNET_INFO_URL);} + trace::println(_X("\n") + _X("Environment variables:")); + if (!install_info::print_environment(_X(" "))) + { + trace::println(_X(" Not set")); + } + + trace::println(_X("\n") + _X("global.json file:\n") + _X(" %s"), + global_json_path.empty() ? _X("Not found") : global_json_path.c_str()); + + trace::println(_X("\n") + _X("Learn more:\n") + _X(" ") DOTNET_INFO_URL); + + trace::println(_X("\n") + _X("Download .NET:\n") + _X(" ") DOTNET_CORE_DOWNLOAD_URL); +} void command_line::print_muxer_usage(bool is_sdk_present) { diff --git a/src/native/corehost/fxr/command_line.h b/src/native/corehost/fxr/command_line.h index 118206b13a9a67..4880ea60f0e45c 100644 --- a/src/native/corehost/fxr/command_line.h +++ b/src/native/corehost/fxr/command_line.h @@ -57,7 +57,7 @@ namespace command_line /*out*/ pal::string_t &app_candidate, /*out*/ opt_map_t &opts); - void print_muxer_info(const pal::string_t &dotnet_root); + void print_muxer_info(const pal::string_t &dotnet_root, const pal::string_t &global_json_path); void print_muxer_usage(bool is_sdk_present); }; diff --git a/src/native/corehost/fxr/files.cmake b/src/native/corehost/fxr/files.cmake index 1d46688166aaa0..f2bea0e2c7fe01 100644 --- a/src/native/corehost/fxr/files.cmake +++ b/src/native/corehost/fxr/files.cmake @@ -15,6 +15,7 @@ list(APPEND SOURCES ${CMAKE_CURRENT_LIST_DIR}/fx_resolver.messages.cpp ${CMAKE_CURRENT_LIST_DIR}/framework_info.cpp ${CMAKE_CURRENT_LIST_DIR}/host_context.cpp + ${CMAKE_CURRENT_LIST_DIR}/install_info.cpp ${CMAKE_CURRENT_LIST_DIR}/sdk_info.cpp ${CMAKE_CURRENT_LIST_DIR}/sdk_resolver.cpp ) @@ -31,6 +32,7 @@ list(APPEND HEADERS ${CMAKE_CURRENT_LIST_DIR}/fx_resolver.h ${CMAKE_CURRENT_LIST_DIR}/framework_info.h ${CMAKE_CURRENT_LIST_DIR}/host_context.h + ${CMAKE_CURRENT_LIST_DIR}/install_info.h ${CMAKE_CURRENT_LIST_DIR}/sdk_info.h ${CMAKE_CURRENT_LIST_DIR}/sdk_resolver.h ) diff --git a/src/native/corehost/fxr/fx_muxer.cpp b/src/native/corehost/fxr/fx_muxer.cpp index 877dd03e454df1..e4a9f4139751ad 100644 --- a/src/native/corehost/fxr/fx_muxer.cpp +++ b/src/native/corehost/fxr/fx_muxer.cpp @@ -245,7 +245,7 @@ void append_probe_realpath(const pal::string_t& path, std::vector if (pos_placeholder != pal::string_t::npos) { - pal::string_t segment = get_arch(); + pal::string_t segment = get_current_arch_name(); segment.push_back(DIR_SEPARATOR); segment.append(tfm); probe_path.replace(pos_placeholder, placeholder.length(), segment); @@ -1066,8 +1066,7 @@ int fx_muxer_t::handle_cli( } else if (pal::strcasecmp(_X("--info"), argv[1]) == 0) { - resolver.print_global_file_path(); - command_line::print_muxer_info(host_info.dotnet_root); + command_line::print_muxer_info(host_info.dotnet_root, resolver.global_file_path()); return StatusCode::Success; } @@ -1124,8 +1123,7 @@ int fx_muxer_t::handle_cli( if (pal::strcasecmp(_X("--info"), argv[1]) == 0) { - resolver.print_global_file_path(); - command_line::print_muxer_info(host_info.dotnet_root); + command_line::print_muxer_info(host_info.dotnet_root, resolver.global_file_path()); } return result; diff --git a/src/native/corehost/fxr/fx_resolver.cpp b/src/native/corehost/fxr/fx_resolver.cpp index 14a40012c78439..e31e100b088fd8 100644 --- a/src/native/corehost/fxr/fx_resolver.cpp +++ b/src/native/corehost/fxr/fx_resolver.cpp @@ -448,7 +448,7 @@ StatusCode fx_resolver_t::read_framework( _X("App: %s\n") _X("Architecture: %s"), app_display_name != nullptr ? app_display_name : host_info.host_path.c_str(), - get_arch()); + get_current_arch_name()); display_missing_framework_error(fx_name, new_effective_fx_ref.get_fx_version(), pal::string_t(), host_info.dotnet_root, disable_multilevel_lookup); return FrameworkMissingFailure; } diff --git a/src/native/corehost/fxr/fx_resolver.messages.cpp b/src/native/corehost/fxr/fx_resolver.messages.cpp index e67344d9449dab..1113e9ced98223 100644 --- a/src/native/corehost/fxr/fx_resolver.messages.cpp +++ b/src/native/corehost/fxr/fx_resolver.messages.cpp @@ -113,11 +113,11 @@ void fx_resolver_t::display_missing_framework_error( // Display the error message about missing FX. if (fx_version.length()) { - trace::error(_X("Framework: '%s', version '%s' (%s)"), fx_name.c_str(), fx_version.c_str(), get_arch()); + trace::error(_X("Framework: '%s', version '%s' (%s)"), fx_name.c_str(), fx_version.c_str(), get_current_arch_name()); } else { - trace::error(_X("Framework: '%s', (%s)"), fx_name.c_str(), get_arch()); + trace::error(_X("Framework: '%s', (%s)"), fx_name.c_str(), get_current_arch_name()); } trace::error(_X(".NET location: %s\n"), dotnet_root.c_str()); diff --git a/src/native/corehost/fxr/install_info.cpp b/src/native/corehost/fxr/install_info.cpp new file mode 100644 index 00000000000000..ff231938db0d87 --- /dev/null +++ b/src/native/corehost/fxr/install_info.cpp @@ -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. + +#include "install_info.h" +#include "pal.h" +#include "trace.h" +#include "utils.h" + +bool install_info::print_environment(const pal::char_t* leading_whitespace) +{ + bool found_any = false; + + const pal::char_t* fmt = _X("%s%-17s [%s]"); + pal::string_t value; + if (pal::getenv(DOTNET_ROOT_ENV_VAR, &value)) + { + found_any = true; + trace::println(fmt, leading_whitespace, DOTNET_ROOT_ENV_VAR, value.c_str()); + } + + for (uint32_t i = 0; i < static_cast(pal::architecture::__last); ++i) + { + pal::string_t env_var = get_dotnet_root_env_var_for_arch(static_cast(i)); + if (pal::getenv(env_var.c_str(), &value)) + { + found_any = true; + trace::println(fmt, leading_whitespace, env_var.c_str(), value.c_str()); + } + } + + return found_any; +} + +bool install_info::print_other_architectures(const pal::char_t* leading_whitespace) +{ + bool found_any = false; + for (uint32_t i = 0; i < static_cast(pal::architecture::__last); ++i) + { + pal::architecture arch = static_cast(i); + if (arch == get_current_arch()) + continue; + + pal::string_t install_location; + bool is_registered = pal::get_dotnet_self_registered_dir_for_arch(arch, &install_location); + if (is_registered + || (pal::get_default_installation_dir_for_arch(arch, &install_location) && pal::directory_exists(install_location))) + { + found_any = true; + remove_trailing_dir_separator(&install_location); + trace::println(_X("%s%-5s [%s]"), leading_whitespace, get_arch_name(arch), install_location.c_str()); + if (is_registered) + { + trace::println(_X("%s registered at [%s]"), leading_whitespace, pal::get_dotnet_self_registered_config_location(arch).c_str()); + } + } + } + + return found_any; +} diff --git a/src/native/corehost/fxr/install_info.h b/src/native/corehost/fxr/install_info.h new file mode 100644 index 00000000000000..3a100486b8f3e5 --- /dev/null +++ b/src/native/corehost/fxr/install_info.h @@ -0,0 +1,15 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#ifndef __INSTALL_INFO_H__ +#define __INSTALL_INFO_H__ + +#include "pal.h" + +namespace install_info +{ + bool print_environment(const pal::char_t* leading_whitespace); + bool print_other_architectures(const pal::char_t* leading_whitespace); +}; + +#endif // __INSTALL_INFO_H__ diff --git a/src/native/corehost/fxr/sdk_resolver.cpp b/src/native/corehost/fxr/sdk_resolver.cpp index 6f532042ef44a9..a2c76a600665c1 100644 --- a/src/native/corehost/fxr/sdk_resolver.cpp +++ b/src/native/corehost/fxr/sdk_resolver.cpp @@ -90,15 +90,6 @@ pal::string_t sdk_resolver::resolve(const pal::string_t& dotnet_root, bool print return {}; } -void sdk_resolver::print_global_file_path() -{ - trace::println( - _X("\n") - _X("global.json file:\n") - _X(" %s"), - global_file.empty() ? _X("Not found") : global_file.c_str()); -} - void sdk_resolver::print_resolution_error(const pal::string_t& dotnet_root, const pal::char_t *main_error_prefix) const { bool sdk_exists = false; diff --git a/src/native/corehost/fxr/sdk_resolver.h b/src/native/corehost/fxr/sdk_resolver.h index 936a6d950c61b1..064f22b4567cf8 100644 --- a/src/native/corehost/fxr/sdk_resolver.h +++ b/src/native/corehost/fxr/sdk_resolver.h @@ -43,7 +43,6 @@ class sdk_resolver pal::string_t resolve(const pal::string_t& dotnet_root, bool print_errors = true) const; - void print_global_file_path(); void print_resolution_error(const pal::string_t& dotnet_root, const pal::char_t *prefix) const; static sdk_resolver from_nearest_global_file(bool allow_prerelease = true); diff --git a/src/native/corehost/fxr_resolver.cpp b/src/native/corehost/fxr_resolver.cpp index e70ec907a1393a..c2f8666f56be73 100644 --- a/src/native/corehost/fxr_resolver.cpp +++ b/src/native/corehost/fxr_resolver.cpp @@ -100,7 +100,7 @@ bool fxr_resolver::try_get_path(const pal::string_t& root_path, pal::string_t* o pal::get_default_installation_dir(&default_install_location); } - pal::string_t self_registered_config_location = pal::get_dotnet_self_registered_config_location(); + pal::string_t self_registered_config_location = pal::get_dotnet_self_registered_config_location(get_current_arch()); trace::verbose(_X("The required library %s could not be found. Searched with root path [%s], environment variable [%s], default install location [%s], self-registered config location [%s]"), LIBFXR_NAME, root_path.c_str(), @@ -124,7 +124,7 @@ bool fxr_resolver::try_get_path(const pal::string_t& root_path, pal::string_t* o _X("Download the .NET runtime:\n") _X("%s&apphost_version=%s"), host_path.c_str(), - get_arch(), + get_current_arch_name(), _STRINGIFY(COMMON_HOST_PKG_VER), get_download_url().c_str(), _STRINGIFY(COMMON_HOST_PKG_VER)); diff --git a/src/native/corehost/hostmisc/pal.h b/src/native/corehost/hostmisc/pal.h index 55d03f572299f3..1f91504a6d9b57 100644 --- a/src/native/corehost/hostmisc/pal.h +++ b/src/native/corehost/hostmisc/pal.h @@ -293,15 +293,35 @@ namespace pal bool getenv(const char_t* name, string_t* recv); bool get_default_servicing_directory(string_t* recv); - // Returns the globally registered install location (if any) + enum class architecture + { + arm, + arm64, + armv6, + loongarch64, + ppc64le, + s390X, + x64, + x86, + + __last // Sentinel value + }; + + // Returns the globally registered install location (if any) for the current architecture bool get_dotnet_self_registered_dir(string_t* recv); + // Returns the globally registered install location (if any) for the specified architecture + bool get_dotnet_self_registered_dir_for_arch(architecture arch, string_t* recv); + // Returns name of the config location for global install registration (for example, registry key or file path) - string_t get_dotnet_self_registered_config_location(); + string_t get_dotnet_self_registered_config_location(architecture arch); - // Returns the default install location for a given platform + // Returns the default install location for a given platform for the current architecture bool get_default_installation_dir(string_t* recv); + // Returns the default install location for a given platform for the specified architecture + bool get_default_installation_dir_for_arch(architecture arch, string_t* recv); + // Returns the global locations to search for SDK/Frameworks - used when multi-level lookup is enabled bool get_global_dotnet_dirs(std::vector* recv); diff --git a/src/native/corehost/hostmisc/pal.unix.cpp b/src/native/corehost/hostmisc/pal.unix.cpp index a71af30832f470..a961a981e0f79a 100644 --- a/src/native/corehost/hostmisc/pal.unix.cpp +++ b/src/native/corehost/hostmisc/pal.unix.cpp @@ -414,16 +414,19 @@ bool pal::get_global_dotnet_dirs(std::vector* recv) return false; } -pal::string_t pal::get_dotnet_self_registered_config_location() +pal::string_t pal::get_dotnet_self_registered_config_location(pal::architecture arch) { + pal::string_t config_location = _X("/etc/dotnet"); + // ***Used only for testing*** pal::string_t environment_install_location_override; if (test_only_getenv(_X("_DOTNET_TEST_INSTALL_LOCATION_PATH"), &environment_install_location_override)) { - return environment_install_location_override; + config_location = environment_install_location_override; } - return _X("/etc/dotnet"); + append_path(&config_location, (_X("install_location_") + to_lower(get_arch_name(arch))).c_str()); + return config_location; } namespace @@ -487,8 +490,6 @@ bool get_install_location_from_file(const pal::string_t& file_path, bool& file_f bool pal::get_dotnet_self_registered_dir(pal::string_t* recv) { - recv->clear(); - // ***Used only for testing*** pal::string_t environment_override; if (test_only_getenv(_X("_DOTNET_TEST_GLOBALLY_REGISTERED_PATH"), &environment_override)) @@ -498,9 +499,14 @@ bool pal::get_dotnet_self_registered_dir(pal::string_t* recv) } // *************************** - pal::string_t install_location_path = get_dotnet_self_registered_config_location(); - pal::string_t arch_specific_install_location_file_path = install_location_path; - append_path(&arch_specific_install_location_file_path, (_X("install_location_") + to_lower(get_arch())).c_str()); + return pal::get_dotnet_self_registered_dir_for_arch(get_current_arch(), recv); +} + +bool pal::get_dotnet_self_registered_dir_for_arch(pal::architecture arch, pal::string_t* recv) +{ + recv->clear(); + + pal::string_t arch_specific_install_location_file_path = get_dotnet_self_registered_config_location(arch); trace::verbose(_X("Looking for architecture-specific install_location file in '%s'."), arch_specific_install_location_file_path.c_str()); pal::string_t install_location; @@ -512,11 +518,19 @@ bool pal::get_dotnet_self_registered_dir(pal::string_t* recv) return false; } - pal::string_t legacy_install_location_file_path = install_location_path; - append_path(&legacy_install_location_file_path, _X("install_location")); - trace::verbose(_X("Looking for install_location file in '%s'."), legacy_install_location_file_path.c_str()); + // If looking for the current architecture, also look for the non-architecture-specific file + if (arch == get_current_arch()) + { + pal::string_t legacy_install_location_file_path = get_directory(arch_specific_install_location_file_path); + append_path(&legacy_install_location_file_path, _X("install_location")); + trace::verbose(_X("Looking for install_location file in '%s'."), legacy_install_location_file_path.c_str()); - if (!get_install_location_from_file(legacy_install_location_file_path, file_found, install_location)) + if (!get_install_location_from_file(legacy_install_location_file_path, file_found, install_location)) + { + return false; + } + } + else { return false; } @@ -524,7 +538,21 @@ bool pal::get_dotnet_self_registered_dir(pal::string_t* recv) recv->assign(install_location); trace::verbose(_X("Found registered install location '%s'."), recv->c_str()); - return true; + return file_found; +} + +namespace +{ + bool is_supported_multi_arch_install(pal::architecture arch) + { +#if defined(TARGET_OSX) && defined(TARGET_ARM64) + // arm64, looking for x64 install + return arch == pal::architecture::x64; +#else + // Others do not support default install locations on a different architecture + return false; +#endif + } } bool pal::get_default_installation_dir(pal::string_t* recv) @@ -538,12 +566,31 @@ bool pal::get_default_installation_dir(pal::string_t* recv) } // *************************** + return get_default_installation_dir_for_arch(get_current_arch(), recv); +} + +bool pal::get_default_installation_dir_for_arch(pal::architecture arch, pal::string_t* recv) +{ + bool is_current_arch = arch == get_current_arch(); + + // Bail out early for unsupported requests for different architectures + if (!is_current_arch && !is_supported_multi_arch_install(arch)) + return false; + #if defined(TARGET_OSX) recv->assign(_X("/usr/local/share/dotnet")); - if (pal::is_emulating_x64()) + if (is_current_arch && pal::is_emulating_x64()) + { + append_path(recv, get_arch_name(arch)); + } +#if defined(TARGET_ARM64) + else if (!is_current_arch) { - append_path(recv, _X("x64")); + // Running arm64, looking for x64 install + assert(arch == pal::architecture::x64); + append_path(recv, get_arch_name(arch)); } +#endif #else recv->assign(_X("/usr/share/dotnet")); #endif diff --git a/src/native/corehost/hostmisc/pal.windows.cpp b/src/native/corehost/hostmisc/pal.windows.cpp index 0eacdd8f5bc1b0..bbb6fabb30b79f 100644 --- a/src/native/corehost/hostmisc/pal.windows.cpp +++ b/src/native/corehost/hostmisc/pal.windows.cpp @@ -265,6 +265,27 @@ bool pal::get_default_servicing_directory(string_t* recv) return true; } +namespace +{ + bool is_supported_multi_arch_install(pal::architecture arch) + { +#if defined(TARGET_AMD64) + // x64, looking for x86 install or emulating x64, looking for arm64 install + return arch == pal::architecture::x86 + || (arch == pal::architecture::arm64 && pal::is_emulating_x64()); +#elif defined(TARGET_ARM64) + // arm64, looking for x64 install + return arch == pal::architecture::x64; +#elif defined(TARGET_X86) + // x86 running in WoW64, looking for x64 install + return arch == pal::architecture::x64 && pal::is_running_in_wow64(); +#else + // Others do not support default install locations on a different architecture + return false; +#endif + } +} + bool pal::get_default_installation_dir(pal::string_t* recv) { // ***Used only for testing*** @@ -276,11 +297,30 @@ bool pal::get_default_installation_dir(pal::string_t* recv) } // *************************** + return get_default_installation_dir_for_arch(get_current_arch(), recv); +} + +bool pal::get_default_installation_dir_for_arch(pal::architecture arch, pal::string_t* recv) +{ + bool is_current_arch = arch == get_current_arch(); + + // Bail out early for unsupported requests for different architectures + if (!is_current_arch && !is_supported_multi_arch_install(arch)) + return false; + const pal::char_t* program_files_dir; - if (pal::is_running_in_wow64()) + if (is_current_arch && pal::is_running_in_wow64()) { + // Running x86 on x64, looking for x86 install program_files_dir = _X("ProgramFiles(x86)"); } +#if defined(TARGET_AMD64) + else if (!is_current_arch && arch == pal::architecture::x86) + { + // Running x64, looking for x86 install + program_files_dir = _X("ProgramFiles(x86)"); + } +#endif else { program_files_dir = _X("ProgramFiles"); @@ -292,18 +332,26 @@ bool pal::get_default_installation_dir(pal::string_t* recv) } append_path(recv, _X("dotnet")); - if (pal::is_emulating_x64()) + if (is_current_arch && pal::is_emulating_x64()) { // Install location for emulated x64 should be %ProgramFiles%\dotnet\x64. - append_path(recv, _X("x64")); + append_path(recv, get_arch_name(arch)); + } +#if defined(TARGET_ARM64) + else if (!is_current_arch) + { + // Running arm64, looking for x64 install + assert(arch == pal::architecture::x64); + append_path(recv, get_arch_name(arch)); } +#endif return true; } namespace { - void get_dotnet_install_location_registry_path(HKEY * key_hive, pal::string_t * sub_key, const pal::char_t ** value) + void get_dotnet_install_location_registry_path(pal::architecture arch, HKEY * key_hive, pal::string_t * sub_key, const pal::char_t ** value) { *key_hive = HKEY_LOCAL_MACHINE; // The registry search occurs in the 32-bit registry in all cases. @@ -322,7 +370,7 @@ namespace dotnet_key_path = environmentRegistryPathOverride; } - *sub_key = dotnet_key_path + pal::string_t(_X("\\Setup\\InstalledVersions\\")) + get_arch(); + *sub_key = dotnet_key_path + pal::string_t(_X("\\Setup\\InstalledVersions\\")) + get_arch_name(arch); *value = _X("InstallLocation"); } @@ -333,20 +381,18 @@ namespace } } -pal::string_t pal::get_dotnet_self_registered_config_location() +pal::string_t pal::get_dotnet_self_registered_config_location(pal::architecture arch) { HKEY key_hive; pal::string_t sub_key; const pal::char_t* value; - get_dotnet_install_location_registry_path(&key_hive, &sub_key, &value); + get_dotnet_install_location_registry_path(arch, &key_hive, &sub_key, &value); return registry_path_as_string(key_hive, sub_key, value); } bool pal::get_dotnet_self_registered_dir(pal::string_t* recv) { - recv->clear(); - // ***Used only for testing*** pal::string_t environmentOverride; if (test_only_getenv(_X("_DOTNET_TEST_GLOBALLY_REGISTERED_PATH"), &environmentOverride)) @@ -356,10 +402,17 @@ bool pal::get_dotnet_self_registered_dir(pal::string_t* recv) } // *************************** + return get_dotnet_self_registered_dir_for_arch(get_current_arch(), recv); +} + +bool pal::get_dotnet_self_registered_dir_for_arch(pal::architecture arch, pal::string_t* recv) +{ + recv->clear(); + HKEY hkeyHive; pal::string_t sub_key; const pal::char_t* value; - get_dotnet_install_location_registry_path(&hkeyHive, &sub_key, &value); + get_dotnet_install_location_registry_path(arch, &hkeyHive, &sub_key, &value); if (trace::is_enabled()) trace::verbose(_X("Looking for architecture-specific registry value in '%s'."), registry_path_as_string(hkeyHive, sub_key, value).c_str()); diff --git a/src/native/corehost/hostmisc/utils.cpp b/src/native/corehost/hostmisc/utils.cpp index 519b2ecc583114..8cd226d8e3e03c 100644 --- a/src/native/corehost/hostmisc/utils.cpp +++ b/src/native/corehost/hostmisc/utils.cpp @@ -194,29 +194,57 @@ pal::string_t get_replaced_char(const pal::string_t& path, pal::char_t match, pa return out; } -const pal::char_t* get_arch() +namespace +{ + const pal::char_t* s_all_architectures[] = + { + _X("arm"), + _X("arm64"), + _X("armv6"), + _X("loongarch64"), + _X("ppc64le"), + _X("s390x"), + _X("x64"), + _X("x86") + }; + static_assert((sizeof(s_all_architectures) / sizeof(*s_all_architectures)) == static_cast(pal::architecture::__last), "Invalid known architectures count"); +} + +pal::architecture get_current_arch() { #if defined(TARGET_AMD64) - return _X("x64"); + return pal::architecture::x64; #elif defined(TARGET_X86) - return _X("x86"); + return pal::architecture::x86; #elif defined(TARGET_ARMV6) - return _X("armv6"); + return pal::architecture::armv6; #elif defined(TARGET_ARM) - return _X("arm"); + return pal::architecture::arm; #elif defined(TARGET_ARM64) - return _X("arm64"); + return pal::architecture::arm64; #elif defined(TARGET_LOONGARCH64) - return _X("loongarch64"); + return pal::architecture::loongarch64; #elif defined(TARGET_S390X) - return _X("s390x"); + return pal::architecture::s390X; #elif defined(TARGET_POWERPC64) - return _X("ppc64le"); + return pal::architecture::ppc64le; #else #error "Unknown target" #endif } +const pal::char_t* get_arch_name(pal::architecture arch) +{ + int idx = static_cast(arch); + assert(0 <= idx && idx < static_cast(pal::architecture::__last)); + return s_all_architectures[idx]; +} + +const pal::char_t* get_current_arch_name() +{ + return get_arch_name(get_current_arch()); +} + pal::string_t get_current_runtime_id(bool use_fallback) { pal::string_t rid; @@ -230,7 +258,7 @@ pal::string_t get_current_runtime_id(bool use_fallback) if (!rid.empty()) { rid.append(_X("-")); - rid.append(get_arch()); + rid.append(get_current_arch_name()); } return rid; @@ -368,10 +396,14 @@ bool try_stou(const pal::string_t& str, unsigned* num) return true; } +pal::string_t get_dotnet_root_env_var_for_arch(pal::architecture arch) +{ + return DOTNET_ROOT_ENV_VAR _X("_") + to_upper(get_arch_name(arch)); +} + bool get_dotnet_root_from_env(pal::string_t* dotnet_root_env_var_name, pal::string_t* recv) { - *dotnet_root_env_var_name = _X("DOTNET_ROOT_"); - dotnet_root_env_var_name->append(to_upper(get_arch())); + *dotnet_root_env_var_name = get_dotnet_root_env_var_for_arch(get_current_arch()); if (get_file_path_from_env(dotnet_root_env_var_name->c_str(), recv)) return true; @@ -386,7 +418,7 @@ bool get_dotnet_root_from_env(pal::string_t* dotnet_root_env_var_name, pal::stri // If no architecture-specific environment variable was set // fallback to the default DOTNET_ROOT. - *dotnet_root_env_var_name = _X("DOTNET_ROOT"); + *dotnet_root_env_var_name = DOTNET_ROOT_ENV_VAR; return get_file_path_from_env(dotnet_root_env_var_name->c_str(), recv); } @@ -465,7 +497,7 @@ pal::string_t get_download_url(const pal::char_t* framework_name, const pal::cha } url.append(_X("&arch=")); - url.append(get_arch()); + url.append(get_current_arch_name()); pal::string_t rid = get_current_runtime_id(true /*use_fallback*/); url.append(_X("&rid=")); url.append(rid); diff --git a/src/native/corehost/hostmisc/utils.h b/src/native/corehost/hostmisc/utils.h index 0260f52f599b8c..97d49763eb3617 100644 --- a/src/native/corehost/hostmisc/utils.h +++ b/src/native/corehost/hostmisc/utils.h @@ -16,10 +16,10 @@ #else #define DOTNET_CORE_INSTALL_PREREQUISITES_URL _X("https://go.microsoft.com/fwlink/?linkid=2063370") #endif -#define DOTNET_CORE_DOWNLOAD_URL _X("https://aka.ms/dotnet-download") +#define DOTNET_CORE_DOWNLOAD_URL _X("https://aka.ms/dotnet/download") #define DOTNET_CORE_APPLAUNCH_URL _X("https://aka.ms/dotnet-core-applaunch") -#define DOTNET_INFO_URL _X("https://aka.ms/dotnet/runtimes-sdk-info") +#define DOTNET_INFO_URL _X("https://aka.ms/dotnet/info") #define DOTNET_APP_LAUNCH_FAILED_URL _X("https://aka.ms/dotnet/app-launch-failed") #define DOTNET_SDK_NOT_FOUND_URL _X("https://aka.ms/dotnet/sdk-not-found") @@ -31,6 +31,8 @@ #define RUNTIME_STORE_DIRECTORY_NAME _X("store") +#define DOTNET_ROOT_ENV_VAR _X("DOTNET_ROOT") + bool ends_with(const pal::string_t& value, const pal::string_t& suffix, bool match_case); bool starts_with(const pal::string_t& value, const pal::string_t& prefix, bool match_case); @@ -69,7 +71,11 @@ bool coreclr_exists_in_dir(const pal::string_t& candidate); void remove_trailing_dir_separator(pal::string_t* dir); void replace_char(pal::string_t* path, pal::char_t match, pal::char_t repl); pal::string_t get_replaced_char(const pal::string_t& path, pal::char_t match, pal::char_t repl); -const pal::char_t* get_arch(); + +pal::architecture get_current_arch(); +const pal::char_t* get_arch_name(pal::architecture arch); +const pal::char_t* get_current_arch_name(); + pal::string_t get_current_runtime_id(bool use_fallback); bool get_env_shared_store_dirs(std::vector* dirs, const pal::string_t& arch, const pal::string_t& tfm); bool get_global_shared_store_dirs(std::vector* dirs, const pal::string_t& arch, const pal::string_t& tfm); @@ -78,7 +84,10 @@ void get_framework_and_sdk_locations(const pal::string_t& dotnet_dir, const bool bool get_file_path_from_env(const pal::char_t* env_key, pal::string_t* recv); size_t index_of_non_numeric(const pal::string_t& str, size_t i); bool try_stou(const pal::string_t& str, unsigned* num); + +pal::string_t get_dotnet_root_env_var_for_arch(pal::architecture arch); bool get_dotnet_root_from_env(pal::string_t* used_dotnet_root_env_var_name, pal::string_t* recv); + pal::string_t get_deps_from_app_binary(const pal::string_t& app_base, const pal::string_t& app); pal::string_t get_runtime_config_path(const pal::string_t& path, const pal::string_t& name); pal::string_t get_runtime_config_dev_path(const pal::string_t& path, const pal::string_t& name); diff --git a/src/native/corehost/hostpolicy/args.cpp b/src/native/corehost/hostpolicy/args.cpp index 01c5b48c40deed..1e80ddceba5e3a 100644 --- a/src/native/corehost/hostpolicy/args.cpp +++ b/src/native/corehost/hostpolicy/args.cpp @@ -36,14 +36,14 @@ void setup_shared_store_paths(const pal::string_t& tfm, host_mode_t host_mode,co } // Environment variable DOTNET_SHARED_STORE - (void) get_env_shared_store_dirs(&args->env_shared_store, get_arch(), tfm); + (void) get_env_shared_store_dirs(&args->env_shared_store, get_current_arch_name(), tfm); // "dotnet.exe" relative shared store folder if (host_mode == host_mode_t::muxer) { args->dotnet_shared_store = own_dir; append_path(&args->dotnet_shared_store, RUNTIME_STORE_DIRECTORY_NAME); - append_path(&args->dotnet_shared_store, get_arch()); + append_path(&args->dotnet_shared_store, get_current_arch_name()); append_path(&args->dotnet_shared_store, tfm.c_str()); } @@ -51,7 +51,7 @@ void setup_shared_store_paths(const pal::string_t& tfm, host_mode_t host_mode,co bool multilevel_lookup = multilevel_lookup_enabled(); if (multilevel_lookup) { - get_global_shared_store_dirs(&args->global_shared_stores, get_arch(), tfm); + get_global_shared_store_dirs(&args->global_shared_stores, get_current_arch_name(), tfm); } } @@ -114,7 +114,7 @@ bool set_root_from_app(const pal::string_t& managed_application_path, if (args.managed_application.empty()) { - // Managed app being empty by itself is not a failure. Host may be initialized from a config file. + // Managed app being empty by itself is not a failure. Host may be initialized from a config file. assert(args.host_mode != host_mode_t::apphost); return true; } diff --git a/src/native/corehost/hostpolicy/deps_resolver.cpp b/src/native/corehost/hostpolicy/deps_resolver.cpp index 8a0afa34c3d2a9..bc4fbbadc7a87e 100644 --- a/src/native/corehost/hostpolicy/deps_resolver.cpp +++ b/src/native/corehost/hostpolicy/deps_resolver.cpp @@ -229,7 +229,7 @@ void deps_resolver_t::setup_probe_config( if (pal::directory_exists(args.core_servicing)) { pal::string_t ext_ni = args.core_servicing; - append_path(&ext_ni, get_arch()); + append_path(&ext_ni, get_current_arch_name()); if (pal::directory_exists(ext_ni)) { // Servicing NI probe. diff --git a/src/native/corehost/hostpolicy/hostpolicy.cpp b/src/native/corehost/hostpolicy/hostpolicy.cpp index 9e74ab13f1eeb2..b3e608a1d09d8a 100644 --- a/src/native/corehost/hostpolicy/hostpolicy.cpp +++ b/src/native/corehost/hostpolicy/hostpolicy.cpp @@ -291,7 +291,7 @@ void trace_hostpolicy_entrypoint_invocation(const pal::string_t& entryPointName) _STRINGIFY(HOST_POLICY_PKG_NAME), _STRINGIFY(HOST_POLICY_PKG_VER), _STRINGIFY(HOST_POLICY_PKG_REL_DIR), - get_arch(), + get_current_arch_name(), entryPointName.c_str()); } From e5acd4dfd7b31ed790687e9f3da642fe1c964dc3 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Tue, 14 Jun 2022 10:14:23 +0200 Subject: [PATCH 099/337] [mono] Remove dead code. (#70671) A variable initialized to false and never modified means we can remove the variable and any code that depends on that variable not being false. This is a consequence of 15ab9f985ed45feaa619df70d288fbd0acd5c45f, where code that assigned the variable was removed. --- src/mono/mono/mini/mini-exceptions.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/mono/mono/mini/mini-exceptions.c b/src/mono/mono/mini/mini-exceptions.c index fef28e56fe33f7..2658058aa049ec 100644 --- a/src/mono/mono/mini/mini-exceptions.c +++ b/src/mono/mono/mini/mini-exceptions.c @@ -2272,11 +2272,7 @@ mono_handle_exception_internal (MonoContext *ctx, MonoObject *obj, gboolean resu mini_set_abort_threshold (&catch_frame); mono_unhandled_exception_internal (obj); } else { - gboolean unhandled = FALSE; - - if (unhandled) - mono_component_debugger ()->handle_exception ((MonoException *)obj, ctx, NULL, NULL); - else if (!ji || (jinfo_get_method (ji)->wrapper_type == MONO_WRAPPER_RUNTIME_INVOKE)) { + if (!ji || (jinfo_get_method (ji)->wrapper_type == MONO_WRAPPER_RUNTIME_INVOKE)) { if (last_mono_wrapper_runtime_invoke && !mono_thread_internal_current ()->threadpool_thread) { mono_component_debugger ()->handle_exception ((MonoException *)obj, ctx, NULL, NULL); if (mini_get_debug_options ()->top_runtime_invoke_unhandled) { From 3bb45af67b81933521f2f22745f3a9d5d3f3045c Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Tue, 14 Jun 2022 12:03:10 +0200 Subject: [PATCH 100/337] Avoid throwing Win32Exception from HTTP authentication (#70474) * Avoid throwing Win32Exception from HTTP authentication When server sends malformed NTLM challenge the NT authentication processing would throw an unexpected Win32Exception from HttpClientHandler.Send[Async] calls. This aligns the behavior to WinHTTP handler where the Unauthorized reply with challenge token is returned back to the client. Similarly, failure to validate the last MIC token in Negotiate scheme could result in Win32Exception. Handle it by throwing HttpRequestException instead. * Make the unit test more resilient * Add trace to Negotiate authentication * Dispose connection instead of draining the response * Remove outdated ActiveIssue --- .../src/System/Net/NTAuthentication.Common.cs | 8 ++- .../System/Net/NTAuthentication.Managed.cs | 70 +++++++++++++++---- .../HttpClientHandlerTest.Authentication.cs | 60 ++++++++++++++++ .../src/Resources/Strings.resx | 6 +- .../AuthenticationHelper.NtAuth.cs | 13 +++- .../HttpClientAuthenticationTest.cs | 1 - 6 files changed, 137 insertions(+), 21 deletions(-) diff --git a/src/libraries/Common/src/System/Net/NTAuthentication.Common.cs b/src/libraries/Common/src/System/Net/NTAuthentication.Common.cs index 2b5047e1080427..7d733b9f4912db 100644 --- a/src/libraries/Common/src/System/Net/NTAuthentication.Common.cs +++ b/src/libraries/Common/src/System/Net/NTAuthentication.Common.cs @@ -163,6 +163,11 @@ internal int MakeSignature(byte[] buffer, int offset, int count, [AllowNull] ref } internal string? GetOutgoingBlob(string? incomingBlob) + { + return GetOutgoingBlob(incomingBlob, throwOnError: true, out _); + } + + internal string? GetOutgoingBlob(string? incomingBlob, bool throwOnError, out SecurityStatusPal statusCode) { byte[]? decodedIncomingBlob = null; if (incomingBlob != null && incomingBlob.Length > 0) @@ -176,10 +181,11 @@ internal int MakeSignature(byte[] buffer, int offset, int count, [AllowNull] ref // we tried auth previously, now we got a null blob, we're done. this happens // with Kerberos & valid credentials on the domain but no ACLs on the resource _isCompleted = true; + statusCode = new SecurityStatusPal(SecurityStatusPalErrorCode.OK); } else { - decodedOutgoingBlob = GetOutgoingBlob(decodedIncomingBlob, true); + decodedOutgoingBlob = GetOutgoingBlob(decodedIncomingBlob, throwOnError, out statusCode); } string? outgoingBlob = null; diff --git a/src/libraries/Common/src/System/Net/NTAuthentication.Managed.cs b/src/libraries/Common/src/System/Net/NTAuthentication.Managed.cs index 6209eb56917f32..d3ed0a07df98f3 100644 --- a/src/libraries/Common/src/System/Net/NTAuthentication.Managed.cs +++ b/src/libraries/Common/src/System/Net/NTAuthentication.Managed.cs @@ -52,6 +52,14 @@ internal sealed partial class NTAuthentication private static readonly byte[] s_workstation = Encoding.Unicode.GetBytes(Environment.MachineName); + private static SecurityStatusPal SecurityStatusPalOk = new SecurityStatusPal(SecurityStatusPalErrorCode.OK); + private static SecurityStatusPal SecurityStatusPalContinueNeeded = new SecurityStatusPal(SecurityStatusPalErrorCode.ContinueNeeded); + private static SecurityStatusPal SecurityStatusPalInvalidToken = new SecurityStatusPal(SecurityStatusPalErrorCode.InvalidToken); + private static SecurityStatusPal SecurityStatusPalInternalError = new SecurityStatusPal(SecurityStatusPalErrorCode.InternalError); + private static SecurityStatusPal SecurityStatusPalPackageNotFound = new SecurityStatusPal(SecurityStatusPalErrorCode.PackageNotFound); + private static SecurityStatusPal SecurityStatusPalMessageAltered = new SecurityStatusPal(SecurityStatusPalErrorCode.MessageAltered); + private static SecurityStatusPal SecurityStatusPalLogonDenied = new SecurityStatusPal(SecurityStatusPalErrorCode.LogonDenied); + private const Flags s_requiredFlags = Flags.NegotiateNtlm2 | Flags.NegotiateNtlm | Flags.NegotiateUnicode | Flags.TargetName | Flags.NegotiateVersion | Flags.NegotiateKeyExchange | Flags.Negotiate128 | @@ -291,7 +299,12 @@ internal void CloseContext() IsCompleted = true; } - internal unsafe string? GetOutgoingBlob(string? incomingBlob) + internal string? GetOutgoingBlob(string? incomingBlob) + { + return GetOutgoingBlob(incomingBlob, throwOnError: true, out _); + } + + internal unsafe string? GetOutgoingBlob(string? incomingBlob, bool throwOnError, out SecurityStatusPal statusCode) { Debug.Assert(!IsCompleted); @@ -311,6 +324,7 @@ internal void CloseContext() CreateNtlmNegotiateMessage(_negotiateMessage); decodedOutgoingBlob = _isSpNego ? CreateSpNegoNegotiateMessage(_negotiateMessage) : _negotiateMessage; + statusCode = SecurityStatusPalContinueNeeded; } else { @@ -319,9 +333,12 @@ internal void CloseContext() if (!_isSpNego) { IsCompleted = true; + decodedOutgoingBlob = ProcessChallenge(decodedIncomingBlob, out statusCode); + } + else + { + decodedOutgoingBlob = ProcessSpNegoChallenge(decodedIncomingBlob, out statusCode); } - - decodedOutgoingBlob = _isSpNego ? ProcessSpNegoChallenge(decodedIncomingBlob) : ProcessChallenge(decodedIncomingBlob); } string? outgoingBlob = null; @@ -604,7 +621,7 @@ private static byte[] DeriveKey(ReadOnlySpan exportedSessionKey, ReadOnlyS } // This gets decoded byte blob and returns response in binary form. - private unsafe byte[]? ProcessChallenge(byte[] blob) + private unsafe byte[]? ProcessChallenge(byte[] blob, out SecurityStatusPal statusCode) { // TODO: Validate size and offsets @@ -615,6 +632,7 @@ private static byte[] DeriveKey(ReadOnlySpan exportedSessionKey, ReadOnlyS if (challengeMessage.Header.MessageType != MessageType.Challenge || !NtlmHeader.SequenceEqual(asBytes.Slice(0, NtlmHeader.Length))) { + statusCode = SecurityStatusPalInvalidToken; return null; } @@ -627,6 +645,7 @@ private static byte[] DeriveKey(ReadOnlySpan exportedSessionKey, ReadOnlyS // that is used for MIC. if ((flags & s_requiredFlags) != s_requiredFlags) { + statusCode = SecurityStatusPalInvalidToken; return null; } @@ -638,6 +657,7 @@ private static byte[] DeriveKey(ReadOnlySpan exportedSessionKey, ReadOnlyS // Confidentiality is TRUE, then return STATUS_LOGON_FAILURE ([MS-ERREF] section 2.3.1). if (!hasNbNames && (flags & (Flags.NegotiateSign | Flags.NegotiateSeal)) != 0) { + statusCode = SecurityStatusPalInvalidToken; return null; } @@ -733,6 +753,7 @@ private static byte[] DeriveKey(ReadOnlySpan exportedSessionKey, ReadOnlyS Debug.Assert(payloadOffset == responseBytes.Length); + statusCode = SecurityStatusPalOk; return responseBytes; } @@ -834,7 +855,7 @@ private unsafe byte[] CreateSpNegoNegotiateMessage(ReadOnlySpan ntlmNegoti return writer.Encode(); } - private unsafe byte[] ProcessSpNegoChallenge(byte[] challenge) + private unsafe byte[]? ProcessSpNegoChallenge(byte[] challenge, out SecurityStatusPal statusCode) { NegState state = NegState.Unknown; string? mech = null; @@ -894,9 +915,10 @@ private unsafe byte[] ProcessSpNegoChallenge(byte[] challenge) challengeReader.ThrowIfNotEmpty(); } - catch (AsnContentException e) + catch (AsnContentException) { - throw new Win32Exception(NTE_FAIL, e.Message); + statusCode = SecurityStatusPalInvalidToken; + return null; } if (blob?.Length > 0) @@ -905,11 +927,19 @@ private unsafe byte[] ProcessSpNegoChallenge(byte[] challenge) // message with the challenge blob. if (!NtlmOid.Equals(mech)) { - throw new Win32Exception(NTE_FAIL, SR.Format(SR.net_nego_mechanism_not_supported, mech)); + if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(this, $"Server requested unknown mechanism {mech}"); + statusCode = SecurityStatusPalPackageNotFound; + return null; } // Process decoded NTLM blob. - byte[]? response = ProcessChallenge(blob); + byte[]? response = ProcessChallenge(blob, out statusCode); + + if (statusCode.ErrorCode != SecurityStatusPalErrorCode.OK) + { + return null; + } + if (response?.Length > 0) { AsnWriter writer = new AsnWriter(AsnEncodingRules.DER); @@ -930,21 +960,35 @@ private unsafe byte[] ProcessSpNegoChallenge(byte[] challenge) } } + statusCode = state == NegState.RequestMic ? SecurityStatusPalContinueNeeded : SecurityStatusPalOk; return writer.Encode(); } } if (mechListMIC != null) { - if (_spnegoMechList == null || state != NegState.AcceptCompleted || !VerifyMIC(_spnegoMechList, mechListMIC)) + if (_spnegoMechList == null || state != NegState.AcceptCompleted) { - throw new Win32Exception(NTE_FAIL); + statusCode = SecurityStatusPalInternalError; + return null; + } + + if (!VerifyMIC(_spnegoMechList, mechListMIC)) + { + statusCode = SecurityStatusPalMessageAltered; + return null; } } IsCompleted = state == NegState.AcceptCompleted || state == NegState.Reject; - - return Array.Empty(); + statusCode = state switch { + NegState.AcceptCompleted => SecurityStatusPalOk, + NegState.AcceptIncomplete => SecurityStatusPalContinueNeeded, + NegState.Reject => SecurityStatusPalLogonDenied, + _ => SecurityStatusPalInternalError + }; + + return null; } } } diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Authentication.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Authentication.cs index 7d0a476dd1a951..4d7e95ee255630 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Authentication.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Authentication.cs @@ -6,6 +6,7 @@ using System.Net.Sockets; using System.Net.Test.Common; using System.Text; +using System.Threading; using System.Threading.Tasks; using Microsoft.DotNet.XUnitExtensions; @@ -689,5 +690,64 @@ await LoopbackServerFactory.CreateClientAndServerAsync( _output.WriteLine(authHeaderValue); }); } + + [ConditionalFact(nameof(IsNtlmInstalled))] + public async Task Credentials_BrokenNtlmFromServer() + { + if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value) + { + return; + } + + await LoopbackServer.CreateClientAndServerAsync( + async uri => + { + using (HttpClientHandler handler = CreateHttpClientHandler()) + using (HttpClient client = CreateHttpClient(handler)) + { + handler.Credentials = new NetworkCredential("username", "password"); + var response = await client.GetAsync(uri); + Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); + } + }, + async server => + { + var responseHeader = new HttpHeaderData[] { new HttpHeaderData("WWW-Authenticate", "NTLM") }; + HttpRequestData requestData = await server.HandleRequestAsync(HttpStatusCode.Unauthorized, responseHeader); + Assert.Equal(0, requestData.GetHeaderValueCount("Authorization")); + + // Establish a session connection + using var connection = await server.EstablishConnectionAsync(); + requestData = await connection.ReadRequestDataAsync(); + string authHeaderValue = requestData.GetSingleHeaderValue("Authorization"); + Assert.Contains("NTLM", authHeaderValue); + _output.WriteLine(authHeaderValue); + + // Incorrect NTLMv1 challenge from server (generated by Cyrus HTTP) + responseHeader = new HttpHeaderData[] { + new HttpHeaderData("WWW-Authenticate", "NTLM TlRMTVNTUAACAAAAHAAcADAAAACV/wIAUwCrhitz1vsAAAAAAAAAAAAAAAAAAAAASgAuAEUATQBDAEwASQBFAE4AVAAuAEMATwBNAA=="), + new HttpHeaderData("Connection", "keep-alive") + }; + await connection.SendResponseAsync(HttpStatusCode.Unauthorized, responseHeader); + connection.CompleteRequestProcessing(); + + // Wait for the client to close the connection + try + { + CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(1000); + await connection.WaitForCloseAsync(cancellationTokenSource.Token); + } + catch (OperationCanceledException) + { + // On Linux the GSSAPI NTLM provider may try to continue with the authentication, so go along with it + requestData = await connection.ReadRequestDataAsync(); + authHeaderValue = requestData.GetSingleHeaderValue("Authorization"); + Assert.Contains("NTLM", authHeaderValue); + _output.WriteLine(authHeaderValue); + await connection.SendResponseAsync(HttpStatusCode.Unauthorized); + connection.CompleteRequestProcessing(); + } + }); + } } } diff --git a/src/libraries/System.Net.Http/src/Resources/Strings.resx b/src/libraries/System.Net.Http/src/Resources/Strings.resx index e575e8ada9f7f8..d5ff73663f8206 100644 --- a/src/libraries/System.Net.Http/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Http/src/Resources/Strings.resx @@ -441,15 +441,15 @@ Authentication failed because the connection could not be reused. + + Authentication validation failed with error - {0}. + Server implementation is not supported Requested protection level is not supported with the GSSAPI implementation currently installed. - - The security package '{0}' is not supported. - Insufficient buffer space. Required: {0} Actual: {1}. diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.NtAuth.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.NtAuth.cs index 58155ea59b6cae..90b7c081df2179 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.NtAuth.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.NtAuth.cs @@ -172,8 +172,9 @@ private static async Task SendWithNtAuthAsync(HttpRequestMe { while (true) { - string? challengeResponse = authContext.GetOutgoingBlob(challengeData); - if (challengeResponse == null) + SecurityStatusPal statusCode; + string? challengeResponse = authContext.GetOutgoingBlob(challengeData, throwOnError: false, out statusCode); + if (statusCode.ErrorCode > SecurityStatusPalErrorCode.TryAgain || challengeResponse == null) { // Response indicated denial even after login, so stop processing and return current response. break; @@ -195,7 +196,13 @@ private static async Task SendWithNtAuthAsync(HttpRequestMe if (!IsAuthenticationChallenge(response, isProxyAuth)) { // Tail response for Negoatiate on successful authentication. Validate it before we proceed. - authContext.GetOutgoingBlob(challengeData); + authContext.GetOutgoingBlob(challengeData, throwOnError: false, out statusCode); + if (statusCode.ErrorCode != SecurityStatusPalErrorCode.OK) + { + isNewConnection = false; + connection.Dispose(); + throw new HttpRequestException(SR.Format(SR.net_http_authvalidationfailure, statusCode.ErrorCode), null, HttpStatusCode.Unauthorized); + } break; } diff --git a/src/libraries/System.Net.Http/tests/EnterpriseTests/HttpClientAuthenticationTest.cs b/src/libraries/System.Net.Http/tests/EnterpriseTests/HttpClientAuthenticationTest.cs index c2c78d2a4fedd0..7395f8d6005a2c 100644 --- a/src/libraries/System.Net.Http/tests/EnterpriseTests/HttpClientAuthenticationTest.cs +++ b/src/libraries/System.Net.Http/tests/EnterpriseTests/HttpClientAuthenticationTest.cs @@ -38,7 +38,6 @@ public void HttpClient_ValidAuthentication_Success(string url, bool useDomain, b }, url, useAltPort ? "true" : "" , useDomain ? "true" : "").Dispose(); } - [ActiveIssue("https://github.com/dotnet/runtime/issues/416")] [Fact] public async Task HttpClient_InvalidAuthentication_Failure() { From 84f7cad00ad834c365b5cd1297e1166525146b50 Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Tue, 14 Jun 2022 12:05:19 +0200 Subject: [PATCH 101/337] Fix usage of GSS_KRB5_CRED_NO_CI_FLAGS_X (#70447) * Fix build detection of GSS_KRB5_CRED_NO_CI_FLAGS_X * Don't use GSS_KRB5_CRED_NO_CI_FLAGS_X on NTLM * Handle GSS_S_UNAVAILABLE error from gss_set_cred_option (NTLM wrapped in Negotiate) * Make the GSSAPI shim work with krb5 1.13 * Preserve the gss_acquire_cred minor status --- .../System.Net.Security.Native/pal_gssapi.c | 70 +++++++++++++++---- src/native/libs/configure.cmake | 13 ++++ 2 files changed, 68 insertions(+), 15 deletions(-) diff --git a/src/native/libs/System.Net.Security.Native/pal_gssapi.c b/src/native/libs/System.Net.Security.Native/pal_gssapi.c index 6206fa0fa0ce42..9d0c2fce2c4a56 100644 --- a/src/native/libs/System.Net.Security.Native/pal_gssapi.c +++ b/src/native/libs/System.Net.Security.Native/pal_gssapi.c @@ -58,7 +58,21 @@ static gss_OID_desc gss_mech_ntlm_OID_desc = {.length = STRING_LENGTH(gss_ntlm_o #if defined(GSS_SHIM) -#define FOR_ALL_GSS_FUNCTIONS \ +#if HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X + +#define FOR_ALL_OPTIONAL_GSS_FUNCTIONS \ + PER_FUNCTION_BLOCK(gss_set_cred_option) \ + PER_FUNCTION_BLOCK(GSS_KRB5_CRED_NO_CI_FLAGS_X) + +#define GSS_KRB5_CRED_NO_CI_FLAGS_X_AVAILABLE (gss_set_cred_option_ptr != NULL && GSS_KRB5_CRED_NO_CI_FLAGS_X_ptr != NULL) + +#else + +#define FOR_ALL_OPTIONAL_GSS_FUNCTIONS + +#endif //HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X + +#define FOR_ALL_REQUIRED_GSS_FUNCTIONS \ PER_FUNCTION_BLOCK(gss_accept_sec_context) \ PER_FUNCTION_BLOCK(gss_acquire_cred) \ PER_FUNCTION_BLOCK(gss_acquire_cred_with_password) \ @@ -78,14 +92,11 @@ static gss_OID_desc gss_mech_ntlm_OID_desc = {.length = STRING_LENGTH(gss_ntlm_o PER_FUNCTION_BLOCK(gss_unwrap) \ PER_FUNCTION_BLOCK(gss_wrap) \ PER_FUNCTION_BLOCK(GSS_C_NT_USER_NAME) \ - PER_FUNCTION_BLOCK(GSS_C_NT_HOSTBASED_SERVICE) - -#if HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X + PER_FUNCTION_BLOCK(GSS_C_NT_HOSTBASED_SERVICE) \ -#define FOR_ALL_GSS_FUNCTIONS FOR_ALL_GSS_FUNCTIONS \ - PER_FUNCTION_BLOCK(gss_set_cred_option) - -#endif //HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X +#define FOR_ALL_GSS_FUNCTIONS \ + FOR_ALL_REQUIRED_GSS_FUNCTIONS \ + FOR_ALL_OPTIONAL_GSS_FUNCTIONS // define indirection pointers for all functions, like // static TYPEOF(gss_accept_sec_context)* gss_accept_sec_context_ptr; @@ -118,6 +129,7 @@ static void* volatile s_gssLib = NULL; #if HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X #define gss_set_cred_option(...) gss_set_cred_option_ptr(__VA_ARGS__) +#define GSS_KRB5_CRED_NO_CI_FLAGS_X (*GSS_KRB5_CRED_NO_CI_FLAGS_X_ptr) #endif //HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X @@ -138,19 +150,27 @@ static int32_t ensure_gss_shim_initialized() dlclose(lib); } - // initialize indirection pointers for all functions, like: + // initialize indirection pointers for all required functions, like: // gss_accept_sec_context_ptr = (TYPEOF(gss_accept_sec_context)*)dlsym(s_gssLib, "gss_accept_sec_context"); // if (gss_accept_sec_context_ptr == NULL) { fprintf(stderr, "Cannot get symbol %s from %s \nError: %s\n", "gss_accept_sec_context", gss_lib_name, dlerror()); return -1; } #define PER_FUNCTION_BLOCK(fn) \ fn##_ptr = (TYPEOF(fn)*)dlsym(s_gssLib, #fn); \ if (fn##_ptr == NULL) { fprintf(stderr, "Cannot get symbol " #fn " from %s \nError: %s\n", gss_lib_name, dlerror()); return -1; } - - FOR_ALL_GSS_FUNCTIONS +FOR_ALL_REQUIRED_GSS_FUNCTIONS +#undef PER_FUNCTION_BLOCK + // for optional functions skip the error check +#define PER_FUNCTION_BLOCK(fn) \ + fn##_ptr = (TYPEOF(fn)*)dlsym(s_gssLib, #fn); +FOR_ALL_OPTIONAL_GSS_FUNCTIONS #undef PER_FUNCTION_BLOCK return 0; } +#else // GSS_SHIM + +#define GSS_KRB5_CRED_NO_CI_FLAGS_X_AVAILABLE 1 + #endif // GSS_SHIM // transfers ownership of the underlying data from gssBuffer to PAL_GssBuffer @@ -183,10 +203,20 @@ static uint32_t AcquireCredSpNego(uint32_t* minorStatus, // call gss_set_cred_option with GSS_KRB5_CRED_NO_CI_FLAGS_X to support Kerberos Sign Only option from *nix client against a windows server #if HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X - if (majorStatus == GSS_S_COMPLETE) + if (majorStatus == GSS_S_COMPLETE && GSS_KRB5_CRED_NO_CI_FLAGS_X_AVAILABLE) { GssBuffer emptyBuffer = GSS_C_EMPTY_BUFFER; - majorStatus = gss_set_cred_option(minorStatus, outputCredHandle, GSS_KRB5_CRED_NO_CI_FLAGS_X, &emptyBuffer); + uint32_t tempMinorStatus; + majorStatus = gss_set_cred_option(&tempMinorStatus, outputCredHandle, GSS_KRB5_CRED_NO_CI_FLAGS_X, &emptyBuffer); + if (majorStatus == GSS_S_UNAVAILABLE || majorStatus == GSS_S_COMPLETE) + { + // preserve the original majorStatus/minorStatus from gss_acquire_cred + majorStatus = GSS_S_COMPLETE; + } + else + { + *minorStatus = tempMinorStatus; + } } #endif @@ -606,10 +636,20 @@ static uint32_t AcquireCredWithPassword(uint32_t* minorStatus, // call gss_set_cred_option with GSS_KRB5_CRED_NO_CI_FLAGS_X to support Kerberos Sign Only option from *nix client against a windows server #if HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X - if (majorStatus == GSS_S_COMPLETE) + if (!isNtlm && majorStatus == GSS_S_COMPLETE && GSS_KRB5_CRED_NO_CI_FLAGS_X_AVAILABLE) { GssBuffer emptyBuffer = GSS_C_EMPTY_BUFFER; - majorStatus = gss_set_cred_option(minorStatus, outputCredHandle, GSS_KRB5_CRED_NO_CI_FLAGS_X, &emptyBuffer); + uint32_t tempMinorStatus; + majorStatus = gss_set_cred_option(&tempMinorStatus, outputCredHandle, GSS_KRB5_CRED_NO_CI_FLAGS_X, &emptyBuffer); + if (majorStatus == GSS_S_UNAVAILABLE || majorStatus == GSS_S_COMPLETE) + { + // preserve the original majorStatus/minorStatus from gss_acquire_cred_with_password + majorStatus = GSS_S_COMPLETE; + } + else + { + *minorStatus = tempMinorStatus; + } } #endif diff --git a/src/native/libs/configure.cmake b/src/native/libs/configure.cmake index 8567842366bc5a..4559017946f488 100644 --- a/src/native/libs/configure.cmake +++ b/src/native/libs/configure.cmake @@ -1030,6 +1030,17 @@ check_include_files( GSS/GSS.h HAVE_GSSFW_HEADERS) +if (HAVE_GSSFW_HEADERS) + find_library(LIBGSS NAMES GSS) +elseif (HAVE_HEIMDAL_HEADERS) + find_library(LIBGSS NAMES gssapi) +else () + find_library(LIBGSS NAMES gssapi_krb5) +endif () + +set (PREVIOUS_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}) +set (CMAKE_REQUIRED_LIBRARIES ${LIBGSS}) + if (HAVE_GSSFW_HEADERS) check_symbol_exists( GSS_SPNEGO_MECHANISM @@ -1054,6 +1065,8 @@ else () HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X) endif () +set (CMAKE_REQUIRED_LIBRARIES ${PREVIOUS_CMAKE_REQUIRED_LIBRARIES}) + check_symbol_exists(getauxval sys/auxv.h HAVE_GETAUXVAL) check_include_files(crt_externs.h HAVE_CRT_EXTERNS_H) From a361f7f84ac627b34a611be89b52d9dc75293bbf Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Tue, 14 Jun 2022 08:21:36 -0400 Subject: [PATCH 102/337] Use IndexOf in WebUtility (#70700) The IndexOfHtmlDecodingChars method was iterating character by character looking for either a `&` or a surrogate, but then the slow path if one of those is found doesn't special-case surrogates. So, we can just collapse this to a vectorized `IndexOf('&')`, which makes the fast path of detecting whether there's anything to decode much faster if there's any meaningful amount of input prior to a `&`. (I experimented with also using `IndexOf('&')` in the main routine, but it made cases with lots of entities slower, and so I'm not including that here.) --- .../src/System/Net/WebUtility.cs | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Net/WebUtility.cs b/src/libraries/System.Private.CoreLib/src/System/Net/WebUtility.cs index 398873d249a506..257b0e1e633cec 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Net/WebUtility.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Net/WebUtility.cs @@ -185,7 +185,7 @@ private static void HtmlEncode(ReadOnlySpan input, ref ValueStringBuilder ReadOnlySpan valueSpan = value.AsSpan(); - int index = IndexOfHtmlDecodingChars(valueSpan); + int index = valueSpan.IndexOf('&'); if (index < 0) { return value; @@ -215,7 +215,7 @@ public static void HtmlDecode(string? value, TextWriter output) ReadOnlySpan valueSpan = value.AsSpan(); - int index = IndexOfHtmlDecodingChars(valueSpan); + int index = valueSpan.IndexOf('&'); if (index == -1) { output.Write(value); @@ -701,21 +701,6 @@ private static bool ValidateUrlEncodingParameters(byte[]? bytes, int offset, int return true; } - private static int IndexOfHtmlDecodingChars(ReadOnlySpan input) - { - // this string requires html decoding if it contains '&' or a surrogate character - for (int i = 0; i < input.Length; i++) - { - char c = input[i]; - if (c == '&' || char.IsSurrogate(c)) - { - return i; - } - } - - return -1; - } - #endregion // Internal struct to facilitate URL decoding -- keeps char buffer and byte buffer, allows appending of either chars or bytes From 4fc6287e79b439cdb799d105583ca67779705013 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Tue, 14 Jun 2022 07:00:12 -0700 Subject: [PATCH 103/337] Hoist the invariants out of multi-level nested loops (#68061) * first working version * Skip check of VN hoisting * Account for duplicate blocks * clean up * wip * isCommaTree && hasExcep * revert lsra changes * Update hoisting condition - Only update if node to be hoisted has side-effects and the sibling that is before that throws exception * Change to BasicBlockList * organize preheaders * update hoistedInCurLoop and hoistedInSiblingLoop * Reverse the loop order * cleanup and jit-format * Revert "Minor fix to display IG01 weight correctly" This reverts commit 757120e863b2da188db2593da1b7142fd1ecf191. * simplify code * Remove m_hoistedVNInSiblingLoop * Add back ResetHoistedInCurLoop Fix igWeight * Remove reversal of loop processing order * jit format * Experimental: Also generate PerfScore: * review feedback * fix the superpmi script * Revert superpmi asmdiffs change * Rename method * Add a comment --- src/coreclr/jit/compiler.h | 37 +++--- src/coreclr/jit/optimizer.cpp | 209 ++++++++++++++++++++++++++-------- 2 files changed, 183 insertions(+), 63 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 8df241aacce85d..e8b10c5c55c1b2 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -5931,13 +5931,11 @@ class Compiler VNSet* m_pHoistedInCurLoop; public: - // Value numbers of expressions that have been hoisted in parent loops in the loop nest. - VNSet m_hoistedInParentLoops; - // Value numbers of expressions that have been hoisted in the current (or most recent) loop in the nest. // Previous decisions on loop-invariance of value numbers in the current loop. VNSet m_curLoopVnInvariantCache; + // Get the VN cache for current loop VNSet* GetHoistedInCurLoop(Compiler* comp) { if (m_pHoistedInCurLoop == nullptr) @@ -5947,35 +5945,35 @@ class Compiler return m_pHoistedInCurLoop; } - VNSet* ExtractHoistedInCurLoop() + // Return the so far collected VNs in cache for current loop and reset it. + void ResetHoistedInCurLoop() { - VNSet* res = m_pHoistedInCurLoop; m_pHoistedInCurLoop = nullptr; - return res; + JITDUMP("Resetting m_pHoistedInCurLoop\n"); } LoopHoistContext(Compiler* comp) - : m_pHoistedInCurLoop(nullptr) - , m_hoistedInParentLoops(comp->getAllocatorLoopHoist()) - , m_curLoopVnInvariantCache(comp->getAllocatorLoopHoist()) + : m_pHoistedInCurLoop(nullptr), m_curLoopVnInvariantCache(comp->getAllocatorLoopHoist()) { } }; - // Do hoisting for loop "lnum" (an index into the optLoopTable), and all loops nested within it. - // Tracks the expressions that have been hoisted by containing loops by temporarily recording their - // value numbers in "m_hoistedInParentLoops". This set is not modified by the call. + // Do hoisting of all loops nested within loop "lnum" (an index into the optLoopTable), followed + // by the loop "lnum" itself. + // + // "m_pHoistedInCurLoop" helps a lot in eliminating duplicate expressions getting hoisted + // and reducing the count of total expressions hoisted out of loop. When calculating the + // profitability, we compare this with number of registers and hence, lower the number of expressions + // getting hoisted, better chances that they will get enregistered and CSE considering them. + // void optHoistLoopNest(unsigned lnum, LoopHoistContext* hoistCtxt); // Do hoisting for a particular loop ("lnum" is an index into the optLoopTable.) - // Assumes that expressions have been hoisted in containing loops if their value numbers are in - // "m_hoistedInParentLoops". - // - void optHoistThisLoop(unsigned lnum, LoopHoistContext* hoistCtxt); + // Returns the new preheaders created. + void optHoistThisLoop(unsigned lnum, LoopHoistContext* hoistCtxt, BasicBlockList* existingPreHeaders); // Hoist all expressions in "blocks" that are invariant in loop "loopNum" (an index into the optLoopTable) - // outside of that loop. Exempt expressions whose value number is in "m_hoistedInParentLoops"; add VN's of hoisted - // expressions to "hoistInLoop". + // outside of that loop. void optHoistLoopBlocks(unsigned loopNum, ArrayStack* blocks, LoopHoistContext* hoistContext); // Return true if the tree looks profitable to hoist out of loop 'lnum'. @@ -6358,6 +6356,9 @@ class Compiler // A loop contains itself. bool optLoopContains(unsigned l1, unsigned l2) const; + // Returns the lpEntry for given preheader block of a loop + BasicBlock* optLoopEntry(BasicBlock* preHeader); + // Updates the loop table by changing loop "loopInd", whose head is required // to be "from", to be "to". Also performs this transformation for any // loop nested in "loopInd" that shares the same head as "loopInd". diff --git a/src/coreclr/jit/optimizer.cpp b/src/coreclr/jit/optimizer.cpp index b848d6400bca88..4cf5db0a250d05 100644 --- a/src/coreclr/jit/optimizer.cpp +++ b/src/coreclr/jit/optimizer.cpp @@ -3151,6 +3151,22 @@ bool Compiler::optLoopContains(unsigned l1, unsigned l2) const } } +//----------------------------------------------------------------------------- +// optLoopEntry: For a given preheader of a loop, returns the lpEntry. +// +// Arguments: +// preHeader -- preheader of a loop +// +// Returns: +// Corresponding loop entry block. +// +BasicBlock* Compiler::optLoopEntry(BasicBlock* preHeader) +{ + assert((preHeader->bbFlags & BBF_LOOP_PREHEADER) != 0); + + return (preHeader->bbJumpDest == nullptr) ? preHeader->bbNext : preHeader->bbJumpDest; +} + //----------------------------------------------------------------------------- // optUpdateLoopHead: Replace the `head` block of a loop in the loop table. // Considers all child loops that might share the same head (recursively). @@ -5992,6 +6008,7 @@ void Compiler::optPerformHoistExpr(GenTree* origExpr, BasicBlock* exprBb, unsign { printf("\nHoisting a copy of "); printTreeID(origExpr); + printf(" " FMT_VN, origExpr->gtVNPair.GetLiberal()); printf(" from " FMT_BB " into PreHeader " FMT_BB " for loop " FMT_LP " <" FMT_BB ".." FMT_BB ">:\n", exprBb->bbNum, optLoopTable[lnum].lpHead->bbNum, lnum, optLoopTable[lnum].lpTop->bbNum, optLoopTable[lnum].lpBottom->bbNum); @@ -6262,46 +6279,51 @@ void Compiler::optHoistLoopNest(unsigned lnum, LoopHoistContext* hoistCtxt) m_loopsConsidered++; #endif // LOOP_HOIST_STATS - optHoistThisLoop(lnum, hoistCtxt); - - VNSet* hoistedInCurLoop = hoistCtxt->ExtractHoistedInCurLoop(); + BasicBlockList* preHeadersOfChildLoops = nullptr; + BasicBlockList* firstPreHeader = nullptr; if (optLoopTable[lnum].lpChild != BasicBlock::NOT_IN_LOOP) { - // Add the ones hoisted in "lnum" to "hoistedInParents" for any nested loops. - // TODO-Cleanup: we should have a set abstraction for loops. - if (hoistedInCurLoop != nullptr) - { - for (VNSet::KeyIterator keys = hoistedInCurLoop->Begin(); !keys.Equal(hoistedInCurLoop->End()); ++keys) - { -#ifdef DEBUG - bool b; - assert(!hoistCtxt->m_hoistedInParentLoops.Lookup(keys.Get(), &b)); -#endif - hoistCtxt->m_hoistedInParentLoops.Set(keys.Get(), true); - } - } + BitVecTraits m_visitedTraits(fgBBNumMax * 2, this); + BitVec m_visited(BitVecOps::MakeEmpty(&m_visitedTraits)); for (unsigned child = optLoopTable[lnum].lpChild; child != BasicBlock::NOT_IN_LOOP; child = optLoopTable[child].lpSibling) { optHoistLoopNest(child, hoistCtxt); - } - // Now remove them. - // TODO-Cleanup: we should have a set abstraction for loops. - if (hoistedInCurLoop != nullptr) - { - for (VNSet::KeyIterator keys = hoistedInCurLoop->Begin(); !keys.Equal(hoistedInCurLoop->End()); ++keys) + if (optLoopTable[child].lpFlags & LPFLG_HAS_PREHEAD) { - // Note that we asserted when we added these that they hadn't been members, so removing is appropriate. - hoistCtxt->m_hoistedInParentLoops.Remove(keys.Get()); + // If any preheaders were found, add them to the tracking list + + BasicBlock* preHeaderBlock = optLoopTable[child].lpHead; + if (!BitVecOps::IsMember(&m_visitedTraits, m_visited, preHeaderBlock->bbNum)) + { + BitVecOps::AddElemD(&m_visitedTraits, m_visited, preHeaderBlock->bbNum); + JITDUMP(" PREHEADER: " FMT_BB "\n", preHeaderBlock->bbNum); + + // Here, we are arranging the blocks in reverse execution order, so when they are pushed + // on the stack that hoist these blocks further sees them in execution order. + if (firstPreHeader == nullptr) + { + preHeadersOfChildLoops = new (this, CMK_LoopHoist) BasicBlockList(preHeaderBlock, nullptr); + firstPreHeader = preHeadersOfChildLoops; + } + else + { + preHeadersOfChildLoops->next = + new (this, CMK_LoopHoist) BasicBlockList(preHeaderBlock, nullptr); + preHeadersOfChildLoops = preHeadersOfChildLoops->next; + } + } } } } + + optHoistThisLoop(lnum, hoistCtxt, firstPreHeader); } -void Compiler::optHoistThisLoop(unsigned lnum, LoopHoistContext* hoistCtxt) +void Compiler::optHoistThisLoop(unsigned lnum, LoopHoistContext* hoistCtxt, BasicBlockList* existingPreHeaders) { LoopDsc* pLoopDsc = &optLoopTable[lnum]; @@ -6413,24 +6435,61 @@ void Compiler::optHoistThisLoop(unsigned lnum, LoopHoistContext* hoistCtxt) // or side-effect dependent things. // // We really should consider hoisting from conditionally executed blocks, if they are frequently executed - // and it is safe to evaluate the tree early. - // - // In particular if we have a loop nest, when scanning the outer loop we should consider hoisting from blocks - // in enclosed loops. However, this is likely to scale poorly, and we really should instead start - // hoisting inner to outer. + // and it is safe to evaluate the tree early // ArrayStack defExec(getAllocatorLoopHoist()); + + bool pushAllPreheaders = false; + if (pLoopDsc->lpExitCnt == 1) { assert(pLoopDsc->lpExit != nullptr); - JITDUMP(" Only considering hoisting in blocks that dominate exit block " FMT_BB "\n", pLoopDsc->lpExit->bbNum); - BasicBlock* cur = pLoopDsc->lpExit; + JITDUMP(" Considering hoisting in blocks that either dominate exit block " FMT_BB + " or preheaders of nested loops, if any:\n", + pLoopDsc->lpExit->bbNum); + // Push dominators, until we reach "entry" or exit the loop. + // Also push the preheaders that were added for the nested loops, + // if any, along the way such that in the final list, the dominating + // blocks are visited before the dominated blocks. + // + // TODO-CQ: In future, we should create preheaders upfront before building + // dominators so we don't have to do this extra work here. + BasicBlock* cur = pLoopDsc->lpExit; + BasicBlockList* preHeadersList = existingPreHeaders; + while (cur != nullptr && pLoopDsc->lpContains(cur) && cur != pLoopDsc->lpEntry) { + JITDUMP(" -- " FMT_BB " (dominate exit block)\n", cur->bbNum); defExec.Push(cur); cur = cur->bbIDom; + + if (preHeadersList != nullptr) + { + BasicBlock* preHeaderBlock = preHeadersList->block; + BasicBlock* lpEntry = optLoopEntry(preHeaderBlock); + if (cur->bbNum < lpEntry->bbNum) + { + JITDUMP(" -- " FMT_BB " (preheader of " FMT_LP ")\n", preHeaderBlock->bbNum, + lpEntry->bbNatLoopNum); + + defExec.Push(preHeaderBlock); + preHeadersList = preHeadersList->next; + } + } + } + + // Push the remaining preheaders, if any. This usually will happen if entry + // and exit blocks of lnum is same. + while (preHeadersList != nullptr) + { + BasicBlock* preHeaderBlock = preHeadersList->block; + JITDUMP(" -- " FMT_BB " (preheader of " FMT_LP ")\n", preHeaderBlock->bbNum, + optLoopEntry(preHeaderBlock)->bbNatLoopNum); + defExec.Push(preHeaderBlock); + preHeadersList = preHeadersList->next; } + // If we didn't reach the entry block, give up and *just* push the entry block. if (cur != pLoopDsc->lpEntry) { @@ -6438,17 +6497,37 @@ void Compiler::optHoistThisLoop(unsigned lnum, LoopHoistContext* hoistCtxt) "block " FMT_BB "\n", pLoopDsc->lpEntry->bbNum); defExec.Reset(); + pushAllPreheaders = true; } - defExec.Push(pLoopDsc->lpEntry); } else // More than one exit { - JITDUMP(" only considering hoisting in entry block " FMT_BB "\n", pLoopDsc->lpEntry->bbNum); // We'll assume that only the entry block is definitely executed. // We could in the future do better. - defExec.Push(pLoopDsc->lpEntry); + + JITDUMP(" Considering hoisting in entry block " FMT_BB " because " FMT_LP " has more than one exit\n", + pLoopDsc->lpEntry->bbNum, lnum); + pushAllPreheaders = true; + } + + if (pushAllPreheaders) + { + // We will still push all the preheaders found. + BasicBlockList* preHeadersList = existingPreHeaders; + + while (preHeadersList != nullptr) + { + BasicBlock* preHeaderBlock = preHeadersList->block; + JITDUMP(" -- " FMT_BB " (preheader of " FMT_LP ")\n", preHeaderBlock->bbNum, + optLoopEntry(preHeaderBlock)->bbNatLoopNum); + defExec.Push(preHeaderBlock); + preHeadersList = preHeadersList->next; + } } + JITDUMP(" -- " FMT_BB " (entry block)\n", pLoopDsc->lpEntry->bbNum); + defExec.Push(pLoopDsc->lpEntry); + optHoistLoopBlocks(lnum, &defExec, hoistCtxt); } @@ -6765,6 +6844,24 @@ void Compiler::optHoistLoopBlocks(unsigned loopNum, ArrayStack* blo return vnIsInvariant; } + bool IsHoistableOverExcepSibling(GenTree* node, bool siblingHasExcep) + { + JITDUMP(" [%06u]", dspTreeID(node)); + + if ((node->gtFlags & GTF_ALL_EFFECT) != 0) + { + // If the hoistable node has any side effects, make sure + // we don't hoist it past a sibling that throws any exception. + if (siblingHasExcep) + { + JITDUMP(" not hoistable: cannot move past node that throws exception.\n"); + return false; + } + } + JITDUMP(" hoistable\n"); + return true; + } + //------------------------------------------------------------------------ // IsTreeLoopMemoryInvariant: determine if the value number of tree // is dependent on the tree being executed within the current loop @@ -6868,6 +6965,7 @@ void Compiler::optHoistLoopBlocks(unsigned loopNum, ArrayStack* blo fgWalkResult PostOrderVisit(GenTree** use, GenTree* user) { GenTree* tree = *use; + JITDUMP("----- PostOrderVisit for [%06u]\n", dspTreeID(tree)); if (tree->OperIsLocal()) { @@ -7174,6 +7272,15 @@ void Compiler::optHoistLoopBlocks(unsigned loopNum, ArrayStack* blo // cctor dependent node is initially not hoistable and may become hoistable later, // when its parent comma node is visited. // + // TODO-CQ: Ideally, we should be hoisting all the nodes having side-effects in execution + // order as well as the ones that don't have side-effects at all. However, currently, we + // just restrict hoisting a node(s) (that are children of `comma`) if one of the siblings + // (which is executed before the given node) has side-effects (exceptions). "Descendants + // of ancestors might have side-effects and we might hoist nodes past them. This needs + // to be addressed properly. + bool visitedCurr = false; + bool isCommaTree = tree->OperIs(GT_COMMA); + bool hasExcep = false; for (int i = 0; i < m_valueStack.Height(); i++) { Value& value = m_valueStack.BottomRef(i); @@ -7182,17 +7289,32 @@ void Compiler::optHoistLoopBlocks(unsigned loopNum, ArrayStack* blo { assert(value.Node() != tree); + if (IsHoistableOverExcepSibling(value.Node(), hasExcep)) + { + m_compiler->optHoistCandidate(value.Node(), m_currentBlock, m_loopNum, m_hoistContext); + } + // Don't hoist this tree again. value.m_hoistable = false; value.m_invariant = false; - - m_compiler->optHoistCandidate(value.Node(), m_currentBlock, m_loopNum, m_hoistContext); } else if (value.Node() != tree) { + if (visitedCurr && isCommaTree) + { + // If we have visited current tree, now we are visiting children. + // For GT_COMMA nodes, we want to track if any children throws and + // should not hoist further children past it. + hasExcep = (tree->gtFlags & GTF_EXCEPT) != 0; + } JITDUMP(" [%06u] not %s: %s\n", dspTreeID(value.Node()), value.m_invariant ? "invariant" : "hoistable", value.m_failReason); } + else + { + visitedCurr = true; + JITDUMP(" [%06u] not hoistable : current node\n", dspTreeID(value.Node())); + } } } @@ -7236,6 +7358,8 @@ void Compiler::optHoistLoopBlocks(unsigned loopNum, ArrayStack* blo visitor.HoistBlock(block); } + + hoistContext->ResetHoistedInCurLoop(); } void Compiler::optHoistCandidate(GenTree* tree, BasicBlock* treeBb, unsigned lnum, LoopHoistContext* hoistCtxt) @@ -7249,17 +7373,12 @@ void Compiler::optHoistCandidate(GenTree* tree, BasicBlock* treeBb, unsigned lnu return; } - if (hoistCtxt->m_hoistedInParentLoops.Lookup(tree->gtVNPair.GetLiberal())) - { - JITDUMP(" ... already hoisted same VN in parent\n"); - // already hoisted in a parent loop, so don't hoist this expression. - return; - } - if (hoistCtxt->GetHoistedInCurLoop(this)->Lookup(tree->gtVNPair.GetLiberal())) { - JITDUMP(" ... already hoisted same VN in current\n"); // already hoisted this expression in the current loop, so don't hoist this expression. + + JITDUMP(" [%06u] ... already hoisted " FMT_VN " in " FMT_LP "\n ", dspTreeID(tree), + tree->gtVNPair.GetLiberal(), lnum); return; } From b85f6b34c80ed7e292fe630120eefb977c000297 Mon Sep 17 00:00:00 2001 From: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> Date: Tue, 14 Jun 2022 17:27:40 +0300 Subject: [PATCH 104/337] Delete GTF_ASSERTION_PROP_LONG (#70521) --- src/coreclr/jit/assertionprop.cpp | 30 ++---------------------------- src/coreclr/jit/gentree.h | 5 ----- 2 files changed, 2 insertions(+), 33 deletions(-) diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index 5ea3ba568406a3..280d1fef56dc07 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -1431,9 +1431,6 @@ AssertionIndex Compiler::optCreateAssertion(GenTree* op1, assertion.op2.vn = ValueNumStore::VNForNull(); assertion.op2.u1.iconVal = 0; assertion.op2.u1.iconFlags = GTF_EMPTY; -#ifdef TARGET_64BIT - assertion.op2.u1.iconFlags |= GTF_ASSERTION_PROP_LONG; // Signify that this is really TYP_LONG -#endif // TARGET_64BIT } // // Are we making an assertion about a local variable? @@ -1568,13 +1565,6 @@ AssertionIndex Compiler::optCreateAssertion(GenTree* op1, #endif // TARGET_ARM assertion.op2.u1.iconVal = op2->AsIntCon()->gtIconVal; assertion.op2.u1.iconFlags = op2->GetIconHandleFlag(); -#ifdef TARGET_64BIT - if (op2->TypeGet() == TYP_LONG || op2->TypeGet() == TYP_BYREF) - { - assertion.op2.u1.iconFlags |= - GTF_ASSERTION_PROP_LONG; // Signify that this is really TYP_LONG - } -#endif // TARGET_64BIT } else if (op2->gtOper == GT_CNS_LNG) { @@ -1731,12 +1721,6 @@ AssertionIndex Compiler::optCreateAssertion(GenTree* op1, /* iconFlags should only contain bits in GTF_ICON_HDL_MASK */ assert((iconFlags & ~GTF_ICON_HDL_MASK) == 0); assertion.op2.u1.iconFlags = iconFlags; -#ifdef TARGET_64BIT - if (op2->AsOp()->gtOp1->TypeGet() == TYP_LONG) - { - assertion.op2.u1.iconFlags |= GTF_ASSERTION_PROP_LONG; // Signify that this is really TYP_LONG - } -#endif // TARGET_64BIT } // JIT case else if (optIsTreeKnownIntValue(!optLocalAssertionProp, op2, &cnsValue, &iconFlags)) @@ -1749,12 +1733,6 @@ AssertionIndex Compiler::optCreateAssertion(GenTree* op1, /* iconFlags should only contain bits in GTF_ICON_HDL_MASK */ assert((iconFlags & ~GTF_ICON_HDL_MASK) == 0); assertion.op2.u1.iconFlags = iconFlags; -#ifdef TARGET_64BIT - if (op2->TypeGet() == TYP_LONG) - { - assertion.op2.u1.iconFlags |= GTF_ASSERTION_PROP_LONG; // Signify that this is really TYP_LONG - } -#endif // TARGET_64BIT } else { @@ -2047,13 +2025,9 @@ void Compiler::optDebugCheckAssertion(AssertionDsc* assertion) case O2K_IND_CNS_INT: case O2K_CONST_INT: { -// The only flags that can be set are those in the GTF_ICON_HDL_MASK, or GTF_ASSERTION_PROP_LONG, which is -// used to indicate a long constant. -#ifdef TARGET_64BIT - assert((assertion->op2.u1.iconFlags & ~(GTF_ICON_HDL_MASK | GTF_ASSERTION_PROP_LONG)) == 0); -#else + // The only flags that can be set are those in the GTF_ICON_HDL_MASK. assert((assertion->op2.u1.iconFlags & ~GTF_ICON_HDL_MASK) == 0); -#endif + switch (assertion->op1.kind) { case O1K_EXACT_TYPE: diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index b4057c9d033ed7..578fb725e40777 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -605,11 +605,6 @@ enum GenTreeFlags : unsigned int GTF_SIMDASHW_OP = 0x80000000, // GT_HWINTRINSIC -- Indicates that the structHandle should be gotten from gtGetStructHandleForSIMD // rather than from gtGetStructHandleForHWSIMD. - - // Flag used by assertion prop to indicate that a type is a TYP_LONG -#ifdef TARGET_64BIT - GTF_ASSERTION_PROP_LONG = 0x00000001, -#endif // TARGET_64BIT }; inline constexpr GenTreeFlags operator ~(GenTreeFlags a) From 021dc5f0ac9509c03ae0fa330d6fe0305d8492d2 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Tue, 14 Jun 2022 22:55:38 +0800 Subject: [PATCH 105/337] Convert exception help context parsing to managed (#70251) * Move help link parsing to managed * Cleanup wtoi and nativeIsDigit * Fix metasig declaration * Guard GetHelpContext under FEATURE_COMINTEROP * Remove definition of GetHelpLink and guard more methods under cominterop * DWORD should be uint * Add help context marshaling test * Adjust marshaling test * Fix #ifdef with ILLink * Fix method signature mismatch * Specify string marshaling * Throwing test should not test successful HRESULT * Implement ISupportErrorInfo * Test interface in InterfaceSupportsErrorInfo --- .../src/System/Exception.CoreCLR.cs | 27 ++++ src/coreclr/vm/comutilnative.cpp | 141 +----------------- src/coreclr/vm/corelib.h | 5 +- src/coreclr/vm/metasig.h | 3 + src/coreclr/vm/util.cpp | 17 --- src/coreclr/vm/util.hpp | 1 - .../COM/NETClients/Primitives/ErrorTests.cs | 27 ++-- .../COM/NETServer/ErrorMarshalTesting.cs | 9 ++ .../NativeClients/Primitives/ErrorTests.cpp | 39 +++++ .../COM/NativeServer/ErrorMarshalTesting.h | 30 +++- .../COM/ServerContracts/Server.Contracts.cs | 2 + .../COM/ServerContracts/Server.Contracts.h | 4 + 12 files changed, 141 insertions(+), 164 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs index 2189ef31c7f894..ac33b4fe8e9a20 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Exception.CoreCLR.cs @@ -274,5 +274,32 @@ private bool CanSetRemoteStackTrace() return true; } + + // used by vm + internal string? GetHelpContext(out uint helpContext) + { + helpContext = 0; + string? helpFile = HelpLink; + + int poundPos, digitEnd; + + if (helpFile is null || (poundPos = helpFile.LastIndexOf('#')) == -1) + { + return helpFile; + } + + for (digitEnd = poundPos + 1; digitEnd < helpFile.Length; digitEnd++) + { + if (char.IsWhiteSpace(helpFile[digitEnd])) + break; + } + + if (uint.TryParse(helpFile.AsSpan(poundPos + 1, digitEnd - poundPos - 1), out helpContext)) + { + helpFile = helpFile.Substring(0, poundPos); + } + + return helpFile; + } } } diff --git a/src/coreclr/vm/comutilnative.cpp b/src/coreclr/vm/comutilnative.cpp index 6f81a31311026c..36852e1a965bbd 100644 --- a/src/coreclr/vm/comutilnative.cpp +++ b/src/coreclr/vm/comutilnative.cpp @@ -41,69 +41,6 @@ #include "arraynative.inl" -/*===================================IsDigit==================================== -**Returns a bool indicating whether the character passed in represents a ** -**digit. -==============================================================================*/ -bool IsDigit(WCHAR c, int radix, int *result) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(CheckPointer(result)); - } - CONTRACTL_END; - - if (IS_DIGIT(c)) { - *result = DIGIT_TO_INT(c); - } - else if (c>='A' && c<='Z') { - //+10 is necessary because A is actually 10, etc. - *result = c-'A'+10; - } - else if (c>='a' && c<='z') { - //+10 is necessary because a is actually 10, etc. - *result = c-'a'+10; - } - else { - *result = -1; - } - - if ((*result >=0) && (*result < radix)) - return true; - - return false; -} - -INT32 wtoi(_In_reads_(length) WCHAR* wstr, DWORD length) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(CheckPointer(wstr)); - PRECONDITION(length >= 0); - } - CONTRACTL_END; - - DWORD i = 0; - int value; - INT32 result = 0; - - while ( (i < length) && (IsDigit(wstr[i], 10 ,&value)) ) { - //Read all of the digits and convert to a number - result = result*10 + value; - i++; - } - - return result; -} - - - // // // EXCEPTION NATIVE @@ -371,79 +308,17 @@ static void GetExceptionHelp(OBJECTREF objException, BSTR *pbstrHelpFile, DWORD GCPROTECT_BEGIN(objException); - // read Exception.HelpLink property - MethodDescCallSite getHelpLink(METHOD__EXCEPTION__GET_HELP_LINK, &objException); + // call managed code to parse help context + MethodDescCallSite getHelpContext(METHOD__EXCEPTION__GET_HELP_CONTEXT, &objException); - ARG_SLOT GetHelpLinkArgs[] = { ObjToArgSlot(objException)}; - *pbstrHelpFile = BStrFromString(getHelpLink.Call_RetSTRINGREF(GetHelpLinkArgs)); + ARG_SLOT GetHelpContextArgs[] = + { + ObjToArgSlot(objException), + PtrToArgSlot(pdwHelpContext) + }; + *pbstrHelpFile = BStrFromString(getHelpContext.Call_RetSTRINGREF(GetHelpContextArgs)); GCPROTECT_END(); - - // parse the help file to check for the presence of helpcontext - int len = SysStringLen(*pbstrHelpFile); - int pos = len; - WCHAR *pwstr = *pbstrHelpFile; - if (pwstr) { - BOOL fFoundPound = FALSE; - - for (pos = len - 1; pos >= 0; pos--) { - if (pwstr[pos] == W('#')) { - fFoundPound = TRUE; - break; - } - } - - if (fFoundPound) { - int PoundPos = pos; - int NumberStartPos = -1; - BOOL bNumberStarted = FALSE; - BOOL bNumberFinished = FALSE; - BOOL bInvalidDigitsFound = FALSE; - - _ASSERTE(pwstr[pos] == W('#')); - - // Check to see if the string to the right of the pound a valid number. - for (pos++; pos < len; pos++) { - if (bNumberFinished) { - if (!COMCharacter::nativeIsWhiteSpace(pwstr[pos])) { - bInvalidDigitsFound = TRUE; - break; - } - } - else if (bNumberStarted) { - if (COMCharacter::nativeIsWhiteSpace(pwstr[pos])) { - bNumberFinished = TRUE; - } - else if (!COMCharacter::nativeIsDigit(pwstr[pos])) { - bInvalidDigitsFound = TRUE; - break; - } - } - else { - if (COMCharacter::nativeIsDigit(pwstr[pos])) { - NumberStartPos = pos; - bNumberStarted = TRUE; - } - else if (!COMCharacter::nativeIsWhiteSpace(pwstr[pos])) { - bInvalidDigitsFound = TRUE; - break; - } - } - } - - if (bNumberStarted && !bInvalidDigitsFound) { - // Grab the help context and remove it from the help file. - *pdwHelpContext = (DWORD)wtoi(&pwstr[NumberStartPos], len - NumberStartPos); - - // Allocate a new help file string of the right length. - BSTR strOld = *pbstrHelpFile; - *pbstrHelpFile = SysAllocStringLen(strOld, PoundPos); - SysFreeString(strOld); - if (!*pbstrHelpFile) - COMPlusThrowOM(); - } - } - } } // NOTE: caller cleans up any partially initialized BSTRs in pED diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index eeeb76769f9301..54eaf1c0d6f60e 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -330,11 +330,12 @@ DEFINE_FIELD_U(_xptrs, ExceptionObject, _xptrs) DEFINE_FIELD_U(_xcode, ExceptionObject, _xcode) DEFINE_FIELD_U(_HResult, ExceptionObject, _HResult) DEFINE_CLASS(EXCEPTION, System, Exception) +DEFINE_METHOD(EXCEPTION, INTERNAL_PRESERVE_STACK_TRACE, InternalPreserveStackTrace, IM_RetVoid) +// Following Exception members are only used when FEATURE_COMINTEROP DEFINE_METHOD(EXCEPTION, GET_CLASS_NAME, GetClassName, IM_RetStr) DEFINE_PROPERTY(EXCEPTION, MESSAGE, Message, Str) DEFINE_PROPERTY(EXCEPTION, SOURCE, Source, Str) -DEFINE_PROPERTY(EXCEPTION, HELP_LINK, HelpLink, Str) -DEFINE_METHOD(EXCEPTION, INTERNAL_PRESERVE_STACK_TRACE, InternalPreserveStackTrace, IM_RetVoid) +DEFINE_METHOD(EXCEPTION, GET_HELP_CONTEXT, GetHelpContext, IM_RefUInt_RetStr) DEFINE_CLASS(SYSTEM_EXCEPTION, System, SystemException) diff --git a/src/coreclr/vm/metasig.h b/src/coreclr/vm/metasig.h index 56570b28ee9d7d..f1e7b7fce43eed 100644 --- a/src/coreclr/vm/metasig.h +++ b/src/coreclr/vm/metasig.h @@ -543,6 +543,9 @@ DEFINE_METASIG(SM(Str_RetArrStr, s, a(s))) // Execution Context DEFINE_METASIG_T(SM(SyncCtx_ArrIntPtr_Bool_Int_RetInt, C(SYNCHRONIZATION_CONTEXT) a(I) F i, i)) +// Exception +DEFINE_METASIG(IM(RefUInt_RetStr, r(K), s)) + #ifdef FEATURE_COMINTEROP // The signature of the method System.Runtime.InteropServices.ICustomQueryInterface.GetInterface DEFINE_METASIG_T(IM(RefGuid_OutIntPtr_RetCustomQueryInterfaceResult, r(g(GUID)) r(I), g(CUSTOMQUERYINTERFACERESULT))) diff --git a/src/coreclr/vm/util.cpp b/src/coreclr/vm/util.cpp index 5422fdaa71bd84..53ce3a32edbddc 100644 --- a/src/coreclr/vm/util.cpp +++ b/src/coreclr/vm/util.cpp @@ -1982,23 +1982,6 @@ BOOL COMCharacter::nativeIsWhiteSpace(WCHAR c) #endif // !TARGET_UNIX } -/*================================nativeIsDigit================================= -**The locally available version of IsDigit. Designed to be called by other -**native methods. The work is mostly done by GetCharacterInfoHelper -**Args: c -- the character to check. -**Returns: true if c is whitespace, false otherwise. -**Exceptions: Only those thrown by GetCharacterInfoHelper. -==============================================================================*/ -BOOL COMCharacter::nativeIsDigit(WCHAR c) -{ - WRAPPER_NO_CONTRACT; -#ifndef TARGET_UNIX - return((GetCharacterInfoHelper(c, CT_CTYPE1) & C1_DIGIT)!=0); -#else // !TARGET_UNIX - return iswdigit(c); -#endif // !TARGET_UNIX -} - BOOL RuntimeFileNotFound(HRESULT hr) { LIMITED_METHOD_CONTRACT; diff --git a/src/coreclr/vm/util.hpp b/src/coreclr/vm/util.hpp index 949f9bd6559d3f..f72212595e87db 100644 --- a/src/coreclr/vm/util.hpp +++ b/src/coreclr/vm/util.hpp @@ -799,7 +799,6 @@ class COMCharacter { public: //These are here for support from native code. They are never called from our managed classes. static BOOL nativeIsWhiteSpace(WCHAR c); - static BOOL nativeIsDigit(WCHAR c); }; // ====================================================================================== diff --git a/src/tests/Interop/COM/NETClients/Primitives/ErrorTests.cs b/src/tests/Interop/COM/NETClients/Primitives/ErrorTests.cs index b741416ba56b1b..17c5a41674f8a0 100644 --- a/src/tests/Interop/COM/NETClients/Primitives/ErrorTests.cs +++ b/src/tests/Interop/COM/NETClients/Primitives/ErrorTests.cs @@ -19,6 +19,7 @@ public void Run() { this.VerifyExpectedException(); this.VerifyReturnHResult(); + this.VerifyHelpLink(); } private void VerifyExpectedException() @@ -40,15 +41,15 @@ private void VerifyReturnHResult() var hrs = new[] { - unchecked((int)0x80004001), - unchecked((int)0x80004003), - unchecked((int)0x80070005), - unchecked((int)0x80070057), - unchecked((int)0x8000ffff), - -1, - 1, - 2 - }; + unchecked((int)0x80004001), + unchecked((int)0x80004003), + unchecked((int)0x80070005), + unchecked((int)0x80070057), + unchecked((int)0x8000ffff), + -1, + 1, + 2 + }; foreach (var hr in hrs) { @@ -56,5 +57,13 @@ private void VerifyReturnHResult() Assert.Equal(hr, this.server.Return_As_HResult_Struct(hr).hr); } } + + private void VerifyHelpLink() + { + string helpLink = "X:\\NotA\\RealPath\\dummy.hlp"; + uint helpContext = 5678; + var ex = Assert.Throws(() => { this.server.Throw_HResult_HelpLink(unchecked((int)-1), helpLink, helpContext); }); + Assert.Equal($"{helpLink}#{helpContext}", ex.HelpLink); + } } } diff --git a/src/tests/Interop/COM/NETServer/ErrorMarshalTesting.cs b/src/tests/Interop/COM/NETServer/ErrorMarshalTesting.cs index 37a3fbdbfaf4e8..3d0a43a5813e54 100644 --- a/src/tests/Interop/COM/NETServer/ErrorMarshalTesting.cs +++ b/src/tests/Interop/COM/NETServer/ErrorMarshalTesting.cs @@ -30,4 +30,13 @@ public Server.Contract.HResult Return_As_HResult_Struct(int hresultToReturn) { return new Server.Contract.HResult { hr = hresultToReturn }; } + + public void Throw_HResult_HelpLink(int hresultToReturn, string helpLink, uint helpContext) + { + Marshal.GetExceptionForHR(hresultToReturn); + + Exception e = Marshal.GetExceptionForHR(hresultToReturn); + e.HelpLink = $"{helpLink}#{helpContext}"; + throw e; + } } diff --git a/src/tests/Interop/COM/NativeClients/Primitives/ErrorTests.cpp b/src/tests/Interop/COM/NativeClients/Primitives/ErrorTests.cpp index 99639a40e052a7..bd8cdc0e9bdc8d 100644 --- a/src/tests/Interop/COM/NativeClients/Primitives/ErrorTests.cpp +++ b/src/tests/Interop/COM/NativeClients/Primitives/ErrorTests.cpp @@ -75,6 +75,44 @@ namespace THROW_FAIL_IF_FALSE(hr == hrMaybe); } } + + void VerifyHelpContext(_In_ IErrorMarshalTesting *et) + { + ::printf("Verify expected helplink and context\n"); + + HRESULT hrs[] = + { + E_NOTIMPL, + E_POINTER, + E_ACCESSDENIED, + E_OUTOFMEMORY, + E_INVALIDARG, + E_UNEXPECTED, + HRESULT{-1} + }; + + LPCWSTR helpLink = L"X:\\NotA\\RealPath\\dummy.hlp"; + + for (int i = 0; i < ARRAY_SIZE(hrs); ++i) + { + HRESULT hr = hrs[i]; + DWORD helpContext = (DWORD)(i + 0x1234); + HRESULT hrMaybe = et->Throw_HResult_HelpLink(hr, helpLink, helpContext); + THROW_FAIL_IF_FALSE(hr == hrMaybe); + + ComSmartPtr pErrInfo; + THROW_IF_FAILED(GetErrorInfo(0, &pErrInfo)); + + BSTR helpLinkMaybe; + THROW_IF_FAILED(pErrInfo->GetHelpFile(&helpLinkMaybe)); + THROW_FAIL_IF_FALSE(TP_wcmp_s(helpLink, helpLinkMaybe) == 0); + SysFreeString(helpLinkMaybe); + + DWORD helpContextMaybe; + THROW_IF_FAILED(pErrInfo->GetHelpContext(&helpContextMaybe)); + THROW_FAIL_IF_FALSE(helpContext == helpContextMaybe); + } + } } void Run_ErrorTests() @@ -89,4 +127,5 @@ void Run_ErrorTests() VerifyExpectedException(errorMarshal); VerifyReturnHResult(errorMarshal); VerifyReturnHResultStruct(errorMarshal); + VerifyHelpContext(errorMarshal); } diff --git a/src/tests/Interop/COM/NativeServer/ErrorMarshalTesting.h b/src/tests/Interop/COM/NativeServer/ErrorMarshalTesting.h index 46884b594f1dd6..b9c48a95565ea8 100644 --- a/src/tests/Interop/COM/NativeServer/ErrorMarshalTesting.h +++ b/src/tests/Interop/COM/NativeServer/ErrorMarshalTesting.h @@ -5,7 +5,7 @@ #include "Servers.h" -class ErrorMarshalTesting : public UnknownImpl, public IErrorMarshalTesting +class ErrorMarshalTesting : public UnknownImpl, public IErrorMarshalTesting, public ISupportErrorInfo { public: // IErrorMarshalTesting DEF_FUNC(Throw_HResult)( @@ -26,12 +26,38 @@ class ErrorMarshalTesting : public UnknownImpl, public IErrorMarshalTesting return hresultToReturn; } + DEF_FUNC(Throw_HResult_HelpLink)( + /*[in]*/ int hresultToReturn, + /*[in]*/ LPCWSTR helpLink, + /*[in]*/ DWORD helpContext) + { + HRESULT hr; + + ComSmartPtr pCreateErrInfo; + BSTR bstrHelpLink = SysAllocString(helpLink); + RETURN_IF_FAILED(::CreateErrorInfo(&pCreateErrInfo)); + RETURN_IF_FAILED(pCreateErrInfo->SetHelpFile(bstrHelpLink)); + RETURN_IF_FAILED(pCreateErrInfo->SetHelpContext(helpContext)); + + ComSmartPtr pErrInfo; + RETURN_IF_FAILED(pCreateErrInfo->QueryInterface(IID_IErrorInfo, (void**)&pErrInfo)); + RETURN_IF_FAILED(SetErrorInfo(0, pErrInfo)); + + return HRESULT{ hresultToReturn }; + } + + DEF_FUNC(InterfaceSupportsErrorInfo)( + /* [in] */ __RPC__in REFIID riid) + { + return riid == IID_IErrorMarshalTesting ? S_OK : S_FALSE; + } + public: // IUnknown STDMETHOD(QueryInterface)( /* [in] */ REFIID riid, /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject) { - return DoQueryInterface(riid, ppvObject, static_cast(this)); + return DoQueryInterface(riid, ppvObject, static_cast(this), static_cast(this)); } DEFINE_REF_COUNTING(); diff --git a/src/tests/Interop/COM/ServerContracts/Server.Contracts.cs b/src/tests/Interop/COM/ServerContracts/Server.Contracts.cs index 30c428ca5b5d14..758c200acaabae 100644 --- a/src/tests/Interop/COM/ServerContracts/Server.Contracts.cs +++ b/src/tests/Interop/COM/ServerContracts/Server.Contracts.cs @@ -201,6 +201,8 @@ public interface IErrorMarshalTesting [PreserveSig] HResult Return_As_HResult_Struct(int hresultToReturn); + + void Throw_HResult_HelpLink(int hresultToReturn, [MarshalAs(UnmanagedType.LPWStr)] string helpLink, uint helpContext); } public enum IDispatchTesting_Exception diff --git a/src/tests/Interop/COM/ServerContracts/Server.Contracts.h b/src/tests/Interop/COM/ServerContracts/Server.Contracts.h index 8b705a94d28cae..3c9a1fcb06cbe1 100644 --- a/src/tests/Interop/COM/ServerContracts/Server.Contracts.h +++ b/src/tests/Interop/COM/ServerContracts/Server.Contracts.h @@ -375,6 +375,10 @@ IErrorMarshalTesting : IUnknown /*[in]*/ int hresultToReturn ) = 0; virtual int STDMETHODCALLTYPE Return_As_HResult_Struct ( /*[in]*/ int hresultToReturn ) = 0; + virtual HRESULT STDMETHODCALLTYPE Throw_HResult_HelpLink ( + /*[in]*/ int hresultToReturn, + /*[in]*/ LPCWSTR helpLink, + /*[in]*/ DWORD helpContext ) = 0; }; enum IDispatchTesting_Exception From 1615e78acbeab81e4381621e7cc8a1579d39e219 Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Tue, 14 Jun 2022 09:16:08 -0600 Subject: [PATCH 106/337] Delete tests for .NET Framework Xsltc.exe tool (#70706) * Use regex matching for Xsltc test baseline files * Delete xsltc.exe tests entirely --- .../TestData/xsltc/baseline/2-(1)cnt19.xsl | 9 - .../TestData/xsltc/baseline/bft 25.xsl | 9 - .../TestData/xsltc/baseline/bft1.txt | 1 - .../TestData/xsltc/baseline/bft1.xsl | 9 - .../TestData/xsltc/baseline/bft10.txt | 1 - .../TestData/xsltc/baseline/bft10a.xsl | 9 - .../TestData/xsltc/baseline/bft10b.xsl | 9 - .../TestData/xsltc/baseline/bft11.txt | 1 - .../TestData/xsltc/baseline/bft11a.xsl | 9 - .../TestData/xsltc/baseline/bft11b.xsl | 9 - .../TestData/xsltc/baseline/bft11c.xsl | 9 - .../TestData/xsltc/baseline/bft12.txt | 1 - .../TestData/xsltc/baseline/bft12a.xsl | 9 - .../TestData/xsltc/baseline/bft12b.xsl | 9 - .../TestData/xsltc/baseline/bft12c.xsl | 9 - .../TestData/xsltc/baseline/bft12d.xsl | 9 - .../TestData/xsltc/baseline/bft12e.xsl | 9 - .../TestData/xsltc/baseline/bft12f.xsl | 9 - .../TestData/xsltc/baseline/bft12g.xsl | 9 - .../TestData/xsltc/baseline/bft12h.xsl | 9 - .../TestData/xsltc/baseline/bft12i.xsl | 9 - .../TestData/xsltc/baseline/bft12j.xsl | 9 - .../TestData/xsltc/baseline/bft12k.xsl | 9 - .../TestData/xsltc/baseline/bft12l.xsl | 9 - .../TestData/xsltc/baseline/bft12m.xsl | 9 - .../TestData/xsltc/baseline/bft12n.xsl | 9 - .../TestData/xsltc/baseline/bft12o.xsl | 9 - .../TestData/xsltc/baseline/bft12p.xsl | 9 - .../TestData/xsltc/baseline/bft12q.xsl | 9 - .../TestData/xsltc/baseline/bft12r.xsl | 9 - .../TestData/xsltc/baseline/bft12s.xsl | 9 - .../TestData/xsltc/baseline/bft12t.xsl | 9 - .../TestData/xsltc/baseline/bft12u.xsl | 9 - .../TestData/xsltc/baseline/bft12v.xsl | 9 - .../TestData/xsltc/baseline/bft12w.xsl | 9 - .../TestData/xsltc/baseline/bft12x.xsl | 9 - .../TestData/xsltc/baseline/bft12y.xsl | 9 - .../TestData/xsltc/baseline/bft12z.xsl | 9 - .../TestData/xsltc/baseline/bft13.txt | 1 - .../TestData/xsltc/baseline/bft13.xsl | 9 - .../TestData/xsltc/baseline/bft14.txt | 1 - .../TestData/xsltc/baseline/bft14a.xsl | 9 - .../TestData/xsltc/baseline/bft15.txt | 6 - .../TestData/xsltc/baseline/bft15a.xsl | 11 - .../TestData/xsltc/baseline/bft15b.xsl | 11 - .../TestData/xsltc/baseline/bft16.txt | 5 - .../TestData/xsltc/baseline/bft16.xsl | 9 - .../TestData/xsltc/baseline/bft16.xslt | 9 - .../TestData/xsltc/baseline/bft17.txt | 1 - .../TestData/xsltc/baseline/bft18.txt | 6 - .../TestData/xsltc/baseline/bft18a.xsl | 11 - .../TestData/xsltc/baseline/bft18b.xsl | 11 - .../TestData/xsltc/baseline/bft19.txt | 1 - .../TestData/xsltc/baseline/bft19.xsl | 13 - .../TestData/xsltc/baseline/bft19a.xsl | 11 - .../TestData/xsltc/baseline/bft2.txt | 1 - .../TestData/xsltc/baseline/bft2.xsl | 9 - .../TestData/xsltc/baseline/bft20.txt | 1 - .../TestData/xsltc/baseline/bft20.xsl | 13 - .../TestData/xsltc/baseline/bft20a.xsl | 11 - .../TestData/xsltc/baseline/bft21.txt | 4 - .../TestData/xsltc/baseline/bft21.xsl | 18 - .../TestData/xsltc/baseline/bft21a.xml | 8 - .../TestData/xsltc/baseline/bft22.txt | 1 - .../TestData/xsltc/baseline/bft22.xsl | 9 - .../TestData/xsltc/baseline/bft23.txt | 1 - .../TestData/xsltc/baseline/bft23.xsl | 9 - .../TestData/xsltc/baseline/bft24.txt | 6 - .../TestData/xsltc/baseline/bft24a.xsl | 11 - .../TestData/xsltc/baseline/bft24b.xsl | 11 - .../TestData/xsltc/baseline/bft25.txt | 1 - .../TestData/xsltc/baseline/bft26.txt | 1 - .../TestData/xsltc/baseline/bft26.xsl | 9 - .../TestData/xsltc/baseline/bft27.txt | 5 - .../TestData/xsltc/baseline/bft28.txt | 5 - .../TestData/xsltc/baseline/bft29.txt | 30 - .../TestData/xsltc/baseline/bft3.txt | 1 - .../TestData/xsltc/baseline/bft3.xsl | 9 - .../TestData/xsltc/baseline/bft30.txt | 30 - .../TestData/xsltc/baseline/bft31.txt | 1 - .../TestData/xsltc/baseline/bft31.xsl | 9 - .../TestData/xsltc/baseline/bft32.txt | 5 - .../TestData/xsltc/baseline/bft33.txt | 1 - .../TestData/xsltc/baseline/bft34.txt | 5 - .../TestData/xsltc/baseline/bft35.txt | 5 - .../TestData/xsltc/baseline/bft36.txt | 5 - .../TestData/xsltc/baseline/bft37.txt | 5 - .../TestData/xsltc/baseline/bft38.txt | 5 - .../TestData/xsltc/baseline/bft4.xsl | 9 - .../TestData/xsltc/baseline/bft5.txt | 5 - .../TestData/xsltc/baseline/bft6.txt | 5 - .../TestData/xsltc/baseline/bft7.txt | 5 - .../TestData/xsltc/baseline/bft8.txt | 5 - .../TestData/xsltc/baseline/bft9.txt | 5 - .../TestData/xsltc/baseline/cct1.txt | 2 - .../TestData/xsltc/baseline/cnt1.txt | 1 - .../TestData/xsltc/baseline/cnt1.xsl | 9 - .../TestData/xsltc/baseline/cnt10.txt | 2 - .../TestData/xsltc/baseline/cnt10a.xsl | 9 - .../TestData/xsltc/baseline/cnt10b.xsl | 10 - .../TestData/xsltc/baseline/cnt11.txt | 1 - .../TestData/xsltc/baseline/cnt11a.xsl | 9 - .../TestData/xsltc/baseline/cnt11b.xsl | 10 - .../TestData/xsltc/baseline/cnt12.txt | 1 - .../TestData/xsltc/baseline/cnt12a.xsl | 9 - .../TestData/xsltc/baseline/cnt12b.xsl | 10 - .../TestData/xsltc/baseline/cnt13.txt | 5 - .../TestData/xsltc/baseline/cnt13.xsl | 9 - .../TestData/xsltc/baseline/cnt14.txt | 1 - .../TestData/xsltc/baseline/cnt14.xsl | 9 - .../TestData/xsltc/baseline/cnt14b.xsl | 9 - .../TestData/xsltc/baseline/cnt15.txt | 5 - .../TestData/xsltc/baseline/cnt15a.xsl | 9 - .../TestData/xsltc/baseline/cnt15b.xsl | 9 - .../TestData/xsltc/baseline/cnt16.txt | 1 - .../TestData/xsltc/baseline/cnt17.txt | 1 - .../TestData/xsltc/baseline/cnt18.txt | 5 - .../TestData/xsltc/baseline/cnt18.xsl | 9 - .../TestData/xsltc/baseline/cnt18.xslt | 9 - .../TestData/xsltc/baseline/cnt19.txt | 1 - .../TestData/xsltc/baseline/cnt2.txt | 1 - .../TestData/xsltc/baseline/cnt2.xsl | 9 - .../TestData/xsltc/baseline/cnt20.txt | 6 - .../TestData/xsltc/baseline/cnt20.xsl | 9 - .../TestData/xsltc/baseline/cnt21.txt | 1 - .../TestData/xsltc/baseline/cnt21.xsl | 9 - .../TestData/xsltc/baseline/cnt22.txt | 1 - .../TestData/xsltc/baseline/cnt22.xsl | 9 - .../TestData/xsltc/baseline/cnt23.txt | 1 - .../TestData/xsltc/baseline/cnt23.xsl | 9 - .../TestData/xsltc/baseline/cnt24.txt | 5 - .../TestData/xsltc/baseline/cnt25.txt | 1 - .../TestData/xsltc/baseline/cnt25a.xsl | 9 - .../TestData/xsltc/baseline/cnt25b.xsl | 10 - .../TestData/xsltc/baseline/cnt26.txt | 1 - .../TestData/xsltc/baseline/cnt26a.xsl | 9 - .../TestData/xsltc/baseline/cnt26b.xsl | 10 - .../TestData/xsltc/baseline/cnt27.txt | 1 - .../TestData/xsltc/baseline/cnt27a.xsl | 9 - .../TestData/xsltc/baseline/cnt27b.xsl | 10 - .../TestData/xsltc/baseline/cnt28.txt | 1 - .../TestData/xsltc/baseline/cnt28a.xsl | 9 - .../TestData/xsltc/baseline/cnt28b.xsl | 10 - .../TestData/xsltc/baseline/cnt29.txt | 1 - .../TestData/xsltc/baseline/cnt29a.xsl | 9 - .../TestData/xsltc/baseline/cnt29b.xsl | 10 - .../TestData/xsltc/baseline/cnt3.txt | 5 - .../TestData/xsltc/baseline/cnt3.xsl | 9 - .../TestData/xsltc/baseline/cnt4.txt | 1 - .../TestData/xsltc/baseline/cnt4.xsl | 9 - .../TestData/xsltc/baseline/cnt5.txt | 1 - .../TestData/xsltc/baseline/cnt5.xsl | 9 - .../TestData/xsltc/baseline/cnt6.txt | 1 - .../TestData/xsltc/baseline/cnt6.xsl | 9 - .../TestData/xsltc/baseline/cnt7.txt | 1 - .../TestData/xsltc/baseline/cnt7.xsl | 9 - .../TestData/xsltc/baseline/cnt8.txt | 1 - .../TestData/xsltc/baseline/cnt8a.xsl | 9 - .../TestData/xsltc/baseline/cnt8b.xsl | 10 - .../TestData/xsltc/baseline/cnt9.txt | 1 - .../TestData/xsltc/baseline/cnt9a.xsl | 9 - .../TestData/xsltc/baseline/cnt9b.xsl | 10 - .../TestData/xsltc/baseline/dft1.txt | 1 - .../TestData/xsltc/baseline/dft1.xsl | 9 - .../TestData/xsltc/baseline/dft10.txt | 1 - .../TestData/xsltc/baseline/dft10.xsl | 9 - .../TestData/xsltc/baseline/dft11.txt | 1 - .../TestData/xsltc/baseline/dft11.xsl | 9 - .../TestData/xsltc/baseline/dft12.txt | 1 - .../TestData/xsltc/baseline/dft12.xsl | 9 - .../TestData/xsltc/baseline/dft13.txt | 1 - .../TestData/xsltc/baseline/dft13.xsl | 9 - .../TestData/xsltc/baseline/dft14.txt | 1 - .../TestData/xsltc/baseline/dft14.xsl | 9 - .../TestData/xsltc/baseline/dft15.txt | 5 - .../TestData/xsltc/baseline/dft15.xsl | 9 - .../TestData/xsltc/baseline/dft16.txt | 5 - .../TestData/xsltc/baseline/dft16.xsl | 9 - .../TestData/xsltc/baseline/dft17.txt | 5 - .../TestData/xsltc/baseline/dft17.xsl | 9 - .../TestData/xsltc/baseline/dft18.txt | 5 - .../TestData/xsltc/baseline/dft18.xsl | 9 - .../TestData/xsltc/baseline/dft19.txt | 5 - .../TestData/xsltc/baseline/dft19.xsl | 9 - .../TestData/xsltc/baseline/dft2.txt | 1 - .../TestData/xsltc/baseline/dft2.xsl | 9 - .../TestData/xsltc/baseline/dft20.txt | 5 - .../TestData/xsltc/baseline/dft20.xsl | 9 - .../TestData/xsltc/baseline/dft21.txt | 5 - .../TestData/xsltc/baseline/dft21.xsl | 9 - .../TestData/xsltc/baseline/dft22.txt | 1 - .../TestData/xsltc/baseline/dft22.xsl | 9 - .../TestData/xsltc/baseline/dft23.txt | 1 - .../TestData/xsltc/baseline/dft23.xsl | 9 - .../TestData/xsltc/baseline/dft3.txt | 5 - .../TestData/xsltc/baseline/dft3.xsl | 9 - .../TestData/xsltc/baseline/dft4.txt | 5 - .../TestData/xsltc/baseline/dft4.xsl | 9 - .../TestData/xsltc/baseline/dft5.txt | 5 - .../TestData/xsltc/baseline/dft5.xsl | 9 - .../TestData/xsltc/baseline/dft6.txt | 1 - .../TestData/xsltc/baseline/dft6.xsl | 9 - .../TestData/xsltc/baseline/dft7.txt | 5 - .../TestData/xsltc/baseline/dft7.xsl | 9 - .../TestData/xsltc/baseline/dft8.txt | 1 - .../TestData/xsltc/baseline/dft8.xsl | 9 - .../TestData/xsltc/baseline/dft9.txt | 1 - .../TestData/xsltc/baseline/dft9.xsl | 9 - .../TestData/xsltc/baseline/fft10.txt | 5 - .../TestData/xsltc/baseline/fft10.xsl | 9 - .../TestData/xsltc/baseline/fft11.txt | 1 - .../TestData/xsltc/baseline/fft11.xsl | 9 - .../TestData/xsltc/baseline/fft12.txt | 5 - .../TestData/xsltc/baseline/fft12.xsl | 9 - .../TestData/xsltc/baseline/fft13.txt | 1 - .../TestData/xsltc/baseline/fft13.xsl | 9 - .../TestData/xsltc/baseline/fft14.txt | 5 - .../TestData/xsltc/baseline/fft14.xsl | 9 - .../TestData/xsltc/baseline/fft15.txt | 5 - .../TestData/xsltc/baseline/fft15.xsl | 9 - .../TestData/xsltc/baseline/fft16.txt | 1 - .../TestData/xsltc/baseline/fft16.xsl | 9 - .../TestData/xsltc/baseline/fft17.txt | 1 - .../TestData/xsltc/baseline/fft17.xsl | 9 - .../TestData/xsltc/baseline/fft18.txt | 1 - .../TestData/xsltc/baseline/fft18.xsl | 9 - .../TestData/xsltc/baseline/fft19.txt | 5 - .../TestData/xsltc/baseline/fft2.txt | 1 - .../TestData/xsltc/baseline/fft2.xsl | 9 - .../TestData/xsltc/baseline/fft20.txt | 5 - .../TestData/xsltc/baseline/fft21.txt | 5 - .../TestData/xsltc/baseline/fft3.txt | 1 - .../TestData/xsltc/baseline/fft3.xsl | 9 - .../TestData/xsltc/baseline/fft4.txt | 1 - .../TestData/xsltc/baseline/fft4.xsl | 9 - .../TestData/xsltc/baseline/fft5.txt | 7 - .../TestData/xsltc/baseline/fft6.txt | 1 - .../TestData/xsltc/baseline/fft6.xsl | 9 - .../TestData/xsltc/baseline/fft7.txt | 1 - .../TestData/xsltc/baseline/fft7a.xsl | 9 - .../TestData/xsltc/baseline/fft7b.xsl | 9 - .../TestData/xsltc/baseline/fft8.txt | 1 - .../TestData/xsltc/baseline/fft8a.xsl | 9 - .../TestData/xsltc/baseline/fft8b.xsl | 9 - .../TestData/xsltc/baseline/fft8c.xsl | 9 - .../TestData/xsltc/baseline/fft8d.xsl | 9 - .../TestData/xsltc/baseline/fft9.txt | 5 - .../TestData/xsltc/baseline/fft9.xsl | 9 - .../TestData/xsltc/baseline/help.txt | 30 - .../TestData/xsltc/baseline/identity.xsl | 7 - .../TestData/xsltc/baseline/infft10.txt | 1 - .../TestData/xsltc/baseline/infft10b.txt | 1 - .../TestData/xsltc/baseline/infft10c.txt | 1 - .../TestData/xsltc/baseline/infft11.txt | 1 - .../TestData/xsltc/baseline/infft11a.txt | 1 - .../TestData/xsltc/baseline/infft11b.txt | 1 - .../TestData/xsltc/baseline/infft12.txt | 1 - .../TestData/xsltc/baseline/infft12b.txt | 1 - .../TestData/xsltc/baseline/infft12c.txt | 1 - .../TestData/xsltc/baseline/infft13.txt | 1 - .../TestData/xsltc/baseline/infft13a.txt | 1 - .../TestData/xsltc/baseline/infft13b.txt | 1 - .../TestData/xsltc/baseline/infft14.txt | 1 - .../TestData/xsltc/baseline/infft14b.txt | 1 - .../TestData/xsltc/baseline/infft14c.txt | 1 - .../TestData/xsltc/baseline/infft15.txt | 1 - .../TestData/xsltc/baseline/infft15b.txt | 1 - .../TestData/xsltc/baseline/infft15c.txt | 1 - .../TestData/xsltc/baseline/infft16---.txt | Bin 20 -> 0 bytes .../TestData/xsltc/baseline/infft17.txt | 3 - .../TestData/xsltc/baseline/infft18.txt | 1 - .../TestData/xsltc/baseline/infft2.txt | Bin 18 -> 0 bytes .../TestData/xsltc/baseline/infft3.txt | 1 - .../TestData/xsltc/baseline/infft4.txt | 1 - .../TestData/xsltc/baseline/infft5.txt | 1 - .../TestData/xsltc/baseline/infft6.txt | 1 - .../TestData/xsltc/baseline/infft7a.txt | 1 - .../TestData/xsltc/baseline/infft7b.txt | 1 - .../TestData/xsltc/baseline/infft8a.txt | 1 - .../TestData/xsltc/baseline/infft8b.txt | 1 - .../TestData/xsltc/baseline/infft8c.txt | 1 - .../TestData/xsltc/baseline/infft9.txt | 1 - .../TestData/xsltc/baseline/mail.xml | 4 - .../TestData/xsltc/baseline/multith.txt | 1 - .../TestData/xsltc/baseline/ns1..cnt17.xsl | 9 - .../TestData/xsltc/baseline/ns1.ns2.cnt16.xsl | 9 - .../TestData/xsltc/baseline/oft1.txt | 1 - .../TestData/xsltc/baseline/oft1.xsl | 9 - .../TestData/xsltc/baseline/oft10.txt | 1 - .../TestData/xsltc/baseline/oft10.xsl | 9 - .../TestData/xsltc/baseline/oft11.txt | 5 - .../TestData/xsltc/baseline/oft11.xsl | 9 - .../TestData/xsltc/baseline/oft12.txt | 1 - .../TestData/xsltc/baseline/oft12.xsl | 9 - .../TestData/xsltc/baseline/oft13.txt | 1 - .../TestData/xsltc/baseline/oft13.xsl | 9 - .../TestData/xsltc/baseline/oft14.txt | 1 - .../TestData/xsltc/baseline/oft14.xsl | 9 - .../TestData/xsltc/baseline/oft15.txt | 1 - .../TestData/xsltc/baseline/oft15.xsl | 9 - .../TestData/xsltc/baseline/oft16.txt | 1 - .../TestData/xsltc/baseline/oft16.xsl | 9 - .../TestData/xsltc/baseline/oft17.txt | 1 - .../TestData/xsltc/baseline/oft17.xsl | 9 - .../TestData/xsltc/baseline/oft18.txt | 5 - .../TestData/xsltc/baseline/oft18.xsl | 9 - .../TestData/xsltc/baseline/oft19.txt | 5 - .../TestData/xsltc/baseline/oft19.xsl | 9 - .../TestData/xsltc/baseline/oft2.txt | 5 - .../TestData/xsltc/baseline/oft2.xsl | 9 - .../TestData/xsltc/baseline/oft20.txt | 5 - .../TestData/xsltc/baseline/oft20.xsl | 9 - .../TestData/xsltc/baseline/oft21.txt | 5 - .../TestData/xsltc/baseline/oft21.xsl | 9 - .../TestData/xsltc/baseline/oft22.txt | 1 - .../TestData/xsltc/baseline/oft22.xsl | 9 - .../TestData/xsltc/baseline/oft23.txt | 1 - .../TestData/xsltc/baseline/oft23.xsl | 9 - .../TestData/xsltc/baseline/oft25.txt | 1 - .../TestData/xsltc/baseline/oft25.xsl | 9 - .../TestData/xsltc/baseline/oft27.txt | 1 - .../TestData/xsltc/baseline/oft27.xsl | 9 - .../TestData/xsltc/baseline/oft28.txt | 1 - .../TestData/xsltc/baseline/oft28.xsl | 9 - .../TestData/xsltc/baseline/oft29.txt | 5 - .../TestData/xsltc/baseline/oft29.xsl | 9 - .../TestData/xsltc/baseline/oft3.txt | 1 - .../TestData/xsltc/baseline/oft3.xsl | 9 - .../TestData/xsltc/baseline/oft30.txt | 5 - .../TestData/xsltc/baseline/oft30.xsl | 9 - .../TestData/xsltc/baseline/oft31.txt | 5 - .../TestData/xsltc/baseline/oft31.xsl | 9 - .../TestData/xsltc/baseline/oft4.txt | 1 - .../TestData/xsltc/baseline/oft4a.xsl | 9 - .../TestData/xsltc/baseline/oft4b.xsl | 10 - .../TestData/xsltc/baseline/oft5.txt | 1 - .../TestData/xsltc/baseline/oft5a.xsl | 9 - .../TestData/xsltc/baseline/oft5b.xsl | 10 - .../TestData/xsltc/baseline/oft6.txt | 1 - .../TestData/xsltc/baseline/oft6a.xsl | 9 - .../TestData/xsltc/baseline/oft6b.xsl | 10 - .../TestData/xsltc/baseline/oft7.txt | 1 - .../TestData/xsltc/baseline/oft7.xsl | 9 - .../TestData/xsltc/baseline/oft8.txt | 1 - .../TestData/xsltc/baseline/oft8.xsl | 9 - .../TestData/xsltc/baseline/oft9.txt | 1 - .../TestData/xsltc/baseline/oft9.xsl | 9 - .../TestData/xsltc/baseline/pft1.txt | 1 - .../TestData/xsltc/baseline/pft1.xsl | 9 - .../TestData/xsltc/baseline/pft10.txt | 1 - .../TestData/xsltc/baseline/pft10.xsl | 9 - .../TestData/xsltc/baseline/pft11.txt | 5 - .../TestData/xsltc/baseline/pft11.xsl | 9 - .../TestData/xsltc/baseline/pft12.txt | 5 - .../TestData/xsltc/baseline/pft12.xsl | 9 - .../TestData/xsltc/baseline/pft13.txt | 5 - .../TestData/xsltc/baseline/pft13.xsl | 9 - .../TestData/xsltc/baseline/pft14.txt | 5 - .../TestData/xsltc/baseline/pft14.xsl | 9 - .../TestData/xsltc/baseline/pft15.txt | 5 - .../TestData/xsltc/baseline/pft15.xsl | 9 - .../TestData/xsltc/baseline/pft16.txt | 5 - .../TestData/xsltc/baseline/pft16.xsl | 9 - .../TestData/xsltc/baseline/pft17.txt | 1 - .../TestData/xsltc/baseline/pft17.xsl | 9 - .../TestData/xsltc/baseline/pft18.txt | 1 - .../TestData/xsltc/baseline/pft18.xsl | 9 - .../TestData/xsltc/baseline/pft19.txt | 1 - .../TestData/xsltc/baseline/pft19.xsl | 9 - .../TestData/xsltc/baseline/pft2.txt | 5 - .../TestData/xsltc/baseline/pft2.xsl | 9 - .../TestData/xsltc/baseline/pft20.txt | 1 - .../TestData/xsltc/baseline/pft20.xsl | 9 - .../TestData/xsltc/baseline/pft3.txt | 1 - .../TestData/xsltc/baseline/pft3.xsl | 9 - .../TestData/xsltc/baseline/pft4.txt | 5 - .../TestData/xsltc/baseline/pft4.xsl | 9 - .../TestData/xsltc/baseline/pft7.txt | 1 - .../TestData/xsltc/baseline/pft7.xsl | 9 - .../TestData/xsltc/baseline/pft8.dll | Bin 0 -> 4096 bytes .../TestData/xsltc/baseline/pft8.txt | 1 - .../TestData/xsltc/baseline/pft8.xsl | 9 - .../TestData/xsltc/baseline/pft9.txt | 1 - .../TestData/xsltc/baseline/pft9.xsl | 9 - .../TestData/xsltc/baseline/sft1.txt | 3 - .../TestData/xsltc/baseline/sft1.xml | 4 - .../TestData/xsltc/baseline/sft1.xsl | 13 - .../TestData/xsltc/baseline/sft10.txt | 2 - .../TestData/xsltc/baseline/sft10.xsl | 21 - .../TestData/xsltc/baseline/sft11.txt | 1 - .../TestData/xsltc/baseline/sft11.xsl | 7 - .../TestData/xsltc/baseline/sft13.txt | 1 - .../TestData/xsltc/baseline/sft13.xsl | 7 - .../TestData/xsltc/baseline/sft14.txt | 5 - .../TestData/xsltc/baseline/sft14.xsl | 9 - .../TestData/xsltc/baseline/sft15.txt | 5 - .../TestData/xsltc/baseline/sft15.xsl | 9 - .../TestData/xsltc/baseline/sft2.txt | 5 - .../TestData/xsltc/baseline/sft2.xsl | 13 - .../TestData/xsltc/baseline/sft27.txt | 3 - .../TestData/xsltc/baseline/sft27.xsl | 3 - .../TestData/xsltc/baseline/sft27a.xsl | 13 - .../TestData/xsltc/baseline/sft28.txt | 5 - .../TestData/xsltc/baseline/sft28.xsl | 3 - .../TestData/xsltc/baseline/sft28a.xsl | 13 - .../TestData/xsltc/baseline/sft29.txt | 2 - .../TestData/xsltc/baseline/sft29.xsl | 3 - .../TestData/xsltc/baseline/sft29a.xsl | 21 - .../TestData/xsltc/baseline/sft3.txt | 2 - .../TestData/xsltc/baseline/sft3.xsl | 21 - .../TestData/xsltc/baseline/sft30.txt | 5 - .../TestData/xsltc/baseline/sft30.xsl | 3 - .../TestData/xsltc/baseline/sft30a.xsl | 21 - .../TestData/xsltc/baseline/sft31.txt | 1 - .../TestData/xsltc/baseline/sft31.xsl | 3 - .../TestData/xsltc/baseline/sft31a.xsl | 7 - .../TestData/xsltc/baseline/sft32.txt | 5 - .../TestData/xsltc/baseline/sft32.xsl | 3 - .../TestData/xsltc/baseline/sft32a.xsl | 7 - .../TestData/xsltc/baseline/sft33.txt | 3 - .../TestData/xsltc/baseline/sft33.xsl | 3 - .../TestData/xsltc/baseline/sft33a.xsl | 13 - .../TestData/xsltc/baseline/sft34.txt | 5 - .../TestData/xsltc/baseline/sft34.xsl | 3 - .../TestData/xsltc/baseline/sft34a.xsl | 13 - .../TestData/xsltc/baseline/sft35.txt | 2 - .../TestData/xsltc/baseline/sft35.xsl | 3 - .../TestData/xsltc/baseline/sft35a.xsl | 21 - .../TestData/xsltc/baseline/sft36.dll | Bin 0 -> 5120 bytes .../TestData/xsltc/baseline/sft36.txt | 5 - .../TestData/xsltc/baseline/sft36.xsl | 3 - .../TestData/xsltc/baseline/sft36a.xsl | 21 - .../TestData/xsltc/baseline/sft37.txt | 1 - .../TestData/xsltc/baseline/sft37.xsl | 3 - .../TestData/xsltc/baseline/sft37a.xsl | 7 - .../TestData/xsltc/baseline/sft38.txt | 5 - .../TestData/xsltc/baseline/sft38.xsl | 3 - .../TestData/xsltc/baseline/sft38a.xsl | 7 - .../TestData/xsltc/baseline/sft4.txt | 5 - .../TestData/xsltc/baseline/sft4.xsl | 21 - .../TestData/xsltc/baseline/sft41.txt | 5 - .../TestData/xsltc/baseline/sft41.xsl | 9 - .../TestData/xsltc/baseline/sft42.txt | 5 - .../TestData/xsltc/baseline/sft42.xsl | 9 - .../TestData/xsltc/baseline/sft43.txt | 5 - .../TestData/xsltc/baseline/sft43.xsl | 9 - .../TestData/xsltc/baseline/sft44.txt | 5 - .../TestData/xsltc/baseline/sft44.xsl | 9 - .../TestData/xsltc/baseline/sft45.txt | 5 - .../TestData/xsltc/baseline/sft45.xsl | 9 - .../TestData/xsltc/baseline/sft46.txt | 5 - .../TestData/xsltc/baseline/sft46.xsl | 9 - .../TestData/xsltc/baseline/sft47.txt | 5 - .../TestData/xsltc/baseline/sft47.xsl | 9 - .../TestData/xsltc/baseline/sft48.txt | 5 - .../TestData/xsltc/baseline/sft48.xsl | 9 - .../TestData/xsltc/baseline/sft49.txt | 5 - .../TestData/xsltc/baseline/sft49.xsl | 9 - .../TestData/xsltc/baseline/sft5.txt | 1 - .../TestData/xsltc/baseline/sft5.xsl | 7 - .../TestData/xsltc/baseline/sft50.txt | 5 - .../TestData/xsltc/baseline/sft50.xsl | 9 - .../TestData/xsltc/baseline/sft6.txt | 5 - .../TestData/xsltc/baseline/sft6.xsl | 7 - .../TestData/xsltc/baseline/sft7.txt | 5 - .../TestData/xsltc/baseline/sft7.xsl | 9 - .../TestData/xsltc/baseline/sft8.txt | 1 - .../TestData/xsltc/baseline/sft8.xsl | 9 - .../TestData/xsltc/baseline/sft9.txt | 3 - .../TestData/xsltc/baseline/sft9.xsl | 13 - .../xsltc/precompiled/Scripting28.xsl | Bin 5996 -> 0 bytes .../TestData/xsltc/precompiled/sft1.xml | 4 - .../XsltCompiler/ApiTests/XsltcApiTest.cs | 52 -- .../XsltcTestBasicFunctionality.cs | 45 -- .../CommonScenarios/XsltcTestCaseBase.cs | 347 --------- .../CommonScenarios/XsltcTestFile.cs | 76 -- .../CommonScenarios/XsltcTestPlatform.cs | 103 --- .../CommonScenarios/XsltcTestSettings.cs | 70 -- .../tests/Xslt/XsltCompiler/Identity.xslt | 11 - .../Xslt/XsltCompiler/IdentityTransform.xslt | 11 - .../Xslt/XsltCompiler/TestStylesheet.xslt | 13 - .../tests/Xslt/XsltCompiler/XsltCommon.cs | 674 ------------------ .../XsltCompiler/XsltCompiler.Tests.csproj | 35 - .../tests/Xslt/XsltCompiler/XsltcModule.cs | 44 -- 484 files changed, 4376 deletions(-) delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/2-(1)cnt19.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft 25.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft1.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft1.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft10.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft10a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft10b.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft11.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft11a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft11b.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft11c.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12b.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12c.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12d.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12e.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12f.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12g.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12h.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12i.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12j.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12k.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12l.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12m.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12n.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12o.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12p.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12q.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12r.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12s.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12t.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12u.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12v.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12w.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12x.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12y.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12z.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft13.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft13.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft14.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft14a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft15.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft15a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft15b.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft16.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft16.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft16.xslt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft17.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft18.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft18a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft18b.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft19.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft19.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft19a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft2.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft2.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft20.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft20.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft20a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft21.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft21.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft21a.xml delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft22.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft22.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft23.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft23.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft24.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft24a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft24b.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft25.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft26.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft26.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft27.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft28.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft29.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft3.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft3.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft30.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft31.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft31.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft32.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft33.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft34.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft35.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft36.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft37.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft38.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft4.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft5.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft6.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft7.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft8.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft9.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cct1.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt1.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt1.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt10.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt10a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt10b.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt11.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt11a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt11b.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt12.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt12a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt12b.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt13.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt13.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt14.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt14.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt14b.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt15.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt15a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt15b.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt16.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt17.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt18.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt18.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt18.xslt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt19.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt2.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt2.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt20.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt20.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt21.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt21.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt22.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt22.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt23.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt23.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt24.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt25.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt25a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt25b.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt26.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt26a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt26b.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt27.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt27a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt27b.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt28.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt28a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt28b.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt29.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt29a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt29b.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt3.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt3.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt4.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt4.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt5.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt5.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt6.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt6.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt7.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt7.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt8.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt8a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt8b.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt9.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt9a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt9b.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft1.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft1.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft10.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft10.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft11.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft11.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft12.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft12.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft13.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft13.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft14.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft14.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft15.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft15.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft16.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft16.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft17.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft17.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft18.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft18.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft19.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft19.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft2.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft2.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft20.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft20.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft21.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft21.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft22.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft22.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft23.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft23.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft3.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft3.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft4.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft4.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft5.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft5.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft6.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft6.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft7.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft7.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft8.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft8.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft9.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft9.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft10.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft10.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft11.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft11.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft12.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft12.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft13.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft13.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft14.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft14.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft15.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft15.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft16.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft16.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft17.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft17.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft18.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft18.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft19.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft2.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft2.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft20.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft21.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft3.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft3.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft4.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft4.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft5.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft6.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft6.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft7.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft7a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft7b.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft8.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft8a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft8b.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft8c.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft8d.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft9.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft9.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/help.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/identity.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft10.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft10b.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft10c.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft11.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft11a.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft11b.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft12.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft12b.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft12c.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft13.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft13a.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft13b.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft14.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft14b.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft14c.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft15.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft15b.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft15c.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft16---.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft17.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft18.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft2.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft3.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft4.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft5.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft6.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft7a.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft7b.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft8a.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft8b.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft8c.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft9.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/mail.xml delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/multith.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/ns1..cnt17.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/ns1.ns2.cnt16.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft1.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft1.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft10.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft10.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft11.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft11.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft12.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft12.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft13.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft13.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft14.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft14.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft15.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft15.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft16.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft16.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft17.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft17.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft18.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft18.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft19.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft19.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft2.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft2.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft20.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft20.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft21.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft21.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft22.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft22.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft23.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft23.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft25.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft25.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft27.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft27.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft28.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft28.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft29.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft29.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft3.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft3.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft30.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft30.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft31.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft31.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft4.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft4a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft4b.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft5.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft5a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft5b.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft6.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft6a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft6b.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft7.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft7.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft8.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft8.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft9.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft9.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft1.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft1.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft10.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft10.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft11.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft11.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft12.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft12.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft13.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft13.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft14.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft14.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft15.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft15.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft16.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft16.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft17.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft17.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft18.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft18.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft19.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft19.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft2.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft2.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft20.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft20.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft3.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft3.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft4.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft4.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft7.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft7.xsl create mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft8.dll delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft8.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft8.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft9.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft9.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft1.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft1.xml delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft1.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft10.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft10.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft11.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft11.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft13.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft13.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft14.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft14.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft15.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft15.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft2.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft2.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft27.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft27.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft27a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft28.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft28.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft28a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft29.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft29.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft29a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft3.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft3.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft30.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft30.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft30a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft31.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft31.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft31a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft32.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft32.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft32a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft33.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft33.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft33a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft34.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft34.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft34a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft35.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft35.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft35a.xsl create mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft36.dll delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft36.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft36.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft36a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft37.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft37.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft37a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft38.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft38.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft38a.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft4.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft4.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft41.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft41.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft42.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft42.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft43.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft43.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft44.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft44.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft45.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft45.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft46.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft46.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft47.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft47.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft48.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft48.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft49.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft49.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft5.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft5.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft50.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft50.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft6.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft6.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft7.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft7.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft8.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft8.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft9.txt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft9.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/precompiled/Scripting28.xsl delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/precompiled/sft1.xml delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/ApiTests/XsltcApiTest.cs delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/CommonScenarios/XsltcTestBasicFunctionality.cs delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/CommonScenarios/XsltcTestCaseBase.cs delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/CommonScenarios/XsltcTestFile.cs delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/CommonScenarios/XsltcTestPlatform.cs delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/CommonScenarios/XsltcTestSettings.cs delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/Identity.xslt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/IdentityTransform.xslt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/TestStylesheet.xslt delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/XsltCommon.cs delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/XsltCompiler.Tests.csproj delete mode 100644 src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/XsltcModule.cs diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/2-(1)cnt19.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/2-(1)cnt19.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/2-(1)cnt19.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft 25.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft 25.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft 25.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft1.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft1.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft1.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft1.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft1.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft1.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft10.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft10.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft10.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft10a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft10a.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft10a.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft10b.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft10b.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft10b.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft11.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft11.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft11.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft11a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft11a.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft11a.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft11b.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft11b.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft11b.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft11c.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft11c.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft11c.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12a.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12a.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12b.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12b.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12b.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12c.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12c.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12c.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12d.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12d.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12d.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12e.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12e.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12e.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12f.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12f.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12f.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12g.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12g.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12g.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12h.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12h.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12h.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12i.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12i.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12i.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12j.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12j.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12j.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12k.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12k.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12k.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12l.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12l.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12l.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12m.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12m.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12m.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12n.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12n.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12n.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12o.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12o.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12o.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12p.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12p.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12p.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12q.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12q.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12q.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12r.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12r.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12r.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12s.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12s.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12s.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12t.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12t.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12t.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12u.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12u.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12u.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12v.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12v.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12v.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12w.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12w.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12w.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12x.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12x.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12x.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12y.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12y.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12y.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12z.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12z.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft12z.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft13.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft13.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft13.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft13.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft13.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft13.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft14.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft14.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft14.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft14a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft14a.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft14a.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft15.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft15.txt deleted file mode 100644 index 9e6f68234ffed0..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft15.txt +++ /dev/null @@ -1,6 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.60220 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All rights reserved. - -bft15b.xsl(3,18) : error : Stylesheet 'bft15a.xsl' cannot directly or indirectly include or import itself. -bft15a.xsl(3,18) : error : Stylesheet 'bft15b.xsl' cannot directly or indirectly include or import itself. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft15a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft15a.xsl deleted file mode 100644 index 4d3de0bb3fb08b..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft15a.xsl +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft15b.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft15b.xsl deleted file mode 100644 index cd8f400ac0ff3c..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft15b.xsl +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft16.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft16.txt deleted file mode 100644 index 1f2d70094bed97..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft16.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.60220 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All rights reserved. - -error : Duplicate class name 'bft16'. Specify a different class name with /class option. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft16.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft16.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft16.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft16.xslt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft16.xslt deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft16.xslt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft17.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft17.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft17.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft18.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft18.txt deleted file mode 100644 index 7f9616f23c48f7..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft18.txt +++ /dev/null @@ -1,6 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.60220 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All rights reserved. - -bft18b.xsl(3,17) : error : Stylesheet 'bft18a.xsl' cannot directly or indirectly include or import itself. -bft18a.xsl(3,17) : error : Stylesheet 'bft18b.xsl' cannot directly or indirectly include or import itself. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft18a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft18a.xsl deleted file mode 100644 index 81ca6ffc979a69..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft18a.xsl +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft18b.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft18b.xsl deleted file mode 100644 index 80dab9c1060673..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft18b.xsl +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft19.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft19.txt deleted file mode 100644 index 958f463d3897b5..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft19.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft19.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft19.xsl deleted file mode 100644 index 64adb9f1ae4f7c..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft19.xsl +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft19a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft19a.xsl deleted file mode 100644 index d2907e1dfbabc9..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft19a.xsl +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft2.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft2.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft2.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft2.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft2.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft2.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft20.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft20.txt deleted file mode 100644 index 958f463d3897b5..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft20.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft20.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft20.xsl deleted file mode 100644 index b874691fb39aed..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft20.xsl +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft20a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft20a.xsl deleted file mode 100644 index d2907e1dfbabc9..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft20a.xsl +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft21.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft21.txt deleted file mode 100644 index feda708575c884..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft21.txt +++ /dev/null @@ -1,4 +0,0 @@ - - -

Foo Listing

John - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft21.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft21.xsl deleted file mode 100644 index 58b41946188e50..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft21.xsl +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - -

Foo Listing

- - - - - - - -
- -
- diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft21a.xml b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft21a.xml deleted file mode 100644 index 31f2f1043101ab..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft21a.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - 1 - John - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft22.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft22.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft22.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft22.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft22.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft22.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft23.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft23.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft23.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft23.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft23.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft23.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft24.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft24.txt deleted file mode 100644 index 958048bc78c511..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft24.txt +++ /dev/null @@ -1,6 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.60220 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All rights reserved. - -bft24b.xsl(3,18) : error : Stylesheet 'bft24a.xsl' cannot directly or indirectly include or import itself. -bft24a.xsl(3,17) : error : Stylesheet 'bft24b.xsl' cannot directly or indirectly include or import itself. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft24a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft24a.xsl deleted file mode 100644 index 003ef979cb7769..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft24a.xsl +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft24b.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft24b.xsl deleted file mode 100644 index 3b52404f373241..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft24b.xsl +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft25.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft25.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft25.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft26.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft26.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft26.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft26.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft26.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft26.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft27.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft27.txt deleted file mode 100644 index 849cbc2a2d4c07..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft27.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.60609 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All rights reserved. - -fatal error : Unrecognized option: '/'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft28.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft28.txt deleted file mode 100644 index 9f5caf3cfdfcb9..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft28.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.60609 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All rights reserved. - -fatal error : No filename specified with option '/out:'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft29.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft29.txt deleted file mode 100644 index bb2c135b849e52..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft29.txt +++ /dev/null @@ -1,30 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.60609 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All rights reserved. - -xsltc [options] [/class:] [[/class:] ]... - - XSLT Compiler Options - - - OUTPUT FILES - -/out: Specify name of binary output file (default: name of the first file) -/platform: Limit which platforms this code can run on: x86, Itanium, x64, or anycpu, which is the default - - - RESOURCES - -/win32res: Specify a Win32 resource file (.res) - - - CODE GENERATION - -/class: Specify name of the class for compiled stylesheet (short form: /c) -/namespace: Specify namespace for the following stylesheets -/debug[+|-] Emit debugging information -/visibleto: Make generated classes visible to the given assembly only - - - ERRORS AND WARNINGS - -/warn: Set warning level (0-4) (short form: /w) -/fullpaths Use fully qualified paths in error messages -/exstack Display call stack in case of unhandled exception (short form: /es) - - - MISCELLANEOUS - -@ Insert command-line settings from a text file -/help Display this usage message (short form: /?) -/nologo Suppress compiler copyright message diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft3.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft3.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft3.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft3.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft3.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft3.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft30.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft30.txt deleted file mode 100644 index bb2c135b849e52..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft30.txt +++ /dev/null @@ -1,30 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.60609 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All rights reserved. - -xsltc [options] [/class:] [[/class:] ]... - - XSLT Compiler Options - - - OUTPUT FILES - -/out: Specify name of binary output file (default: name of the first file) -/platform: Limit which platforms this code can run on: x86, Itanium, x64, or anycpu, which is the default - - - RESOURCES - -/win32res: Specify a Win32 resource file (.res) - - - CODE GENERATION - -/class: Specify name of the class for compiled stylesheet (short form: /c) -/namespace: Specify namespace for the following stylesheets -/debug[+|-] Emit debugging information -/visibleto: Make generated classes visible to the given assembly only - - - ERRORS AND WARNINGS - -/warn: Set warning level (0-4) (short form: /w) -/fullpaths Use fully qualified paths in error messages -/exstack Display call stack in case of unhandled exception (short form: /es) - - - MISCELLANEOUS - -@ Insert command-line settings from a text file -/help Display this usage message (short form: /?) -/nologo Suppress compiler copyright message diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft31.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft31.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft31.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft31.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft31.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft31.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft32.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft32.txt deleted file mode 100644 index da2b5e943d62c1..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft32.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61016 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -fatal error : No input sources specified. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft33.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft33.txt deleted file mode 100644 index 327c1e815f6ec1..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft33.txt +++ /dev/null @@ -1 +0,0 @@ -fatal error : Unrecognized option: '/foo'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft34.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft34.txt deleted file mode 100644 index 17817cfa616d52..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft34.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61016 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -error : Source file 'nul/bft34.xsl' could not be found. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft35.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft35.txt deleted file mode 100644 index 6198402c0bd3f3..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft35.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61016 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -fatal error : Source file 'nul.xsl' could not be found. ---> Win32 device names are not allowed. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft36.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft36.txt deleted file mode 100644 index c3eb1a8f2e867c..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft36.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61016 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -error : Source file '..\' could not be found. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft37.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft37.txt deleted file mode 100644 index da2b5e943d62c1..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft37.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61016 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -fatal error : No input sources specified. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft38.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft38.txt deleted file mode 100644 index da2b5e943d62c1..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft38.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61016 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -fatal error : No input sources specified. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft4.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft4.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft4.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft5.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft5.txt deleted file mode 100644 index da2b5e943d62c1..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft5.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61016 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -fatal error : No input sources specified. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft6.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft6.txt deleted file mode 100644 index 9ab7492575537d..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft6.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.60220 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.60306 -Copyright (C) Microsoft Corporation 2006. All rights reserved. - -fatal error : Unrecognized option: '/thisisinvalid'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft7.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft7.txt deleted file mode 100644 index 71741603c68dd3..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft7.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.60220 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.60306 -Copyright (C) Microsoft Corporation 2006. All rights reserved. - -error : Source file 'mystylesheet' could not be found. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft8.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft8.txt deleted file mode 100644 index ac1a3d8ddffbba..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft8.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.60220 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.60306 -Copyright (C) Microsoft Corporation 2006. All rights reserved. - -error : Source file 'mystylesheet,xsl' could not be found. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft9.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft9.txt deleted file mode 100644 index 8583a6d0371df7..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/bft9.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61220 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -fatal error : Source file '*.xsl' could not be found. ---> Illegal characters in path. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cct1.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cct1.txt deleted file mode 100644 index 3d0b723a92086d..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cct1.txt +++ /dev/null @@ -1,2 +0,0 @@ - - Script Result: Hello Foo \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt1.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt1.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt1.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt1.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt1.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt1.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt10.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt10.txt deleted file mode 100644 index 57d923614b1397..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt10.txt +++ /dev/null @@ -1,2 +0,0 @@ - DIFFERENT - Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt10a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt10a.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt10a.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt10b.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt10b.xsl deleted file mode 100644 index 5705c4ff25e3e5..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt10b.xsl +++ /dev/null @@ -1,10 +0,0 @@ - - - - - DIFFERENT - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt11.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt11.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt11.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt11a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt11a.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt11a.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt11b.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt11b.xsl deleted file mode 100644 index 5705c4ff25e3e5..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt11b.xsl +++ /dev/null @@ -1,10 +0,0 @@ - - - - - DIFFERENT - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt12.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt12.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt12.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt12a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt12a.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt12a.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt12b.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt12b.xsl deleted file mode 100644 index 5705c4ff25e3e5..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt12b.xsl +++ /dev/null @@ -1,10 +0,0 @@ - - - - - DIFFERENT - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt13.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt13.txt deleted file mode 100644 index 8bc5a7f7b9b954..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt13.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.60220 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All rights reserved. - -fatal error : Unrecognized option: '/class'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt13.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt13.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt13.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt14.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt14.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt14.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt14.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt14.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt14.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt14b.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt14b.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt14b.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt15.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt15.txt deleted file mode 100644 index 8f86a0e1975399..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt15.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.60220 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All rights reserved. - -error : Duplicate class name 'cnt15a'. Specify a different class name with /class option. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt15a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt15a.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt15a.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt15b.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt15b.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt15b.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt16.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt16.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt16.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt17.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt17.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt17.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt18.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt18.txt deleted file mode 100644 index 7846b782de9461..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt18.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.60220 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All rights reserved. - -error : Duplicate class name 'cnt18'. Specify a different class name with /class option. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt18.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt18.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt18.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt18.xslt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt18.xslt deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt18.xslt +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt19.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt19.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt19.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt2.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt2.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt2.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt2.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt2.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt2.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt20.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt20.txt deleted file mode 100644 index 173975e3e08cc2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt20.txt +++ /dev/null @@ -1,6 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.60220 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All rights reserved. - -fatal error : Type name was too long. The fully qualified type name must be less than 1,024 characters. -Parameter name: fullname diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt20.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt20.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt20.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt21.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt21.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt21.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt21.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt21.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt21.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt22.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt22.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt22.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt22.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt22.xsl deleted file mode 100644 index d0df9a8b4bbd1a..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt22.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt23.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt23.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt23.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt23.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt23.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt23.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt24.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt24.txt deleted file mode 100644 index 66041859ae9b25..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt24.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 4.0.20914 -[Microsoft (R) .NET Framework version 4.0.20914] -Copyright (C) Microsoft Corporation. All rights reserved. - -fatal error : Class name 'A' must be specified before the corresponding source file. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt25.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt25.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt25.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt25a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt25a.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt25a.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt25b.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt25b.xsl deleted file mode 100644 index 6f929b5265dfc2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt25b.xsl +++ /dev/null @@ -1,10 +0,0 @@ - - - - - MORE HERE - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt26.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt26.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt26.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt26a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt26a.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt26a.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt26b.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt26b.xsl deleted file mode 100644 index 6f929b5265dfc2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt26b.xsl +++ /dev/null @@ -1,10 +0,0 @@ - - - - - MORE HERE - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt27.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt27.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt27.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt27a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt27a.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt27a.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt27b.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt27b.xsl deleted file mode 100644 index 6f929b5265dfc2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt27b.xsl +++ /dev/null @@ -1,10 +0,0 @@ - - - - - MORE HERE - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt28.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt28.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt28.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt28a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt28a.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt28a.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt28b.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt28b.xsl deleted file mode 100644 index 6f929b5265dfc2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt28b.xsl +++ /dev/null @@ -1,10 +0,0 @@ - - - - - MORE HERE - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt29.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt29.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt29.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt29a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt29a.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt29a.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt29b.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt29b.xsl deleted file mode 100644 index 6f929b5265dfc2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt29b.xsl +++ /dev/null @@ -1,10 +0,0 @@ - - - - - MORE HERE - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt3.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt3.txt deleted file mode 100644 index 3b185caae853e6..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt3.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.60220 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All rights reserved. - -fatal error : Class name cannot be empty. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt3.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt3.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt3.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt4.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt4.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt4.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt4.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt4.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt4.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt5.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt5.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt5.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt5.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt5.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt5.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt6.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt6.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt6.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt6.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt6.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt6.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt7.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt7.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt7.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt7.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt7.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt7.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt8.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt8.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt8.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt8a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt8a.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt8a.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt8b.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt8b.xsl deleted file mode 100644 index 5705c4ff25e3e5..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt8b.xsl +++ /dev/null @@ -1,10 +0,0 @@ - - - - - DIFFERENT - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt9.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt9.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt9.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt9a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt9a.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt9a.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt9b.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt9b.xsl deleted file mode 100644 index 5705c4ff25e3e5..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/cnt9b.xsl +++ /dev/null @@ -1,10 +0,0 @@ - - - - - DIFFERENT - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft1.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft1.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft1.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft1.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft1.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft1.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft10.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft10.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft10.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft10.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft10.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft10.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft11.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft11.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft11.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft11.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft11.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft11.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft12.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft12.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft12.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft12.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft12.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft12.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft13.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft13.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft13.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft13.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft13.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft13.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft14.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft14.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft14.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft14.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft14.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft14.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft15.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft15.txt deleted file mode 100644 index 7f5d1218982d72..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft15.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -fatal error : Error saving assembly 'a:\dft15.dll'. ---> Invalid directory, 'a:\'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft15.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft15.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft15.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft16.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft16.txt deleted file mode 100644 index 8c99251f7ce1d0..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft16.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -fatal error : The path 'nul.dll' is not valid. ---> Win32 device names are not allowed. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft16.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft16.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft16.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft17.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft17.txt deleted file mode 100644 index 7dfee6cabaa58e..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft17.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.60220 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All rights reserved. - -fatal error : Unrecognized option: '/debug+-'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft17.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft17.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft17.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft18.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft18.txt deleted file mode 100644 index 913529919e95d4..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft18.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.60220 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All rights reserved. - -fatal error : Unrecognized option: '/debug-+'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft18.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft18.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft18.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft19.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft19.txt deleted file mode 100644 index bd83f2312f6c55..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft19.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.60220 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All rights reserved. - -fatal error : Unrecognized option: '/debug+-+'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft19.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft19.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft19.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft2.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft2.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft2.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft2.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft2.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft2.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft20.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft20.txt deleted file mode 100644 index 5127363555d123..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft20.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.60220 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All rights reserved. - -fatal error : Unrecognized option: '/debug-+-'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft20.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft20.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft20.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft21.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft21.txt deleted file mode 100644 index da7517efe7fe3f..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft21.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -fatal error : The path 'dft2101234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789.dll' is not valid. ---> The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft21.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft21.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft21.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft22.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft22.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft22.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft22.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft22.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft22.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft23.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft23.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft23.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft23.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft23.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft23.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft3.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft3.txt deleted file mode 100644 index 14cd40e9b277cd..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft3.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.60220 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All rights reserved. - -fatal error : Unrecognized option: '/debug~'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft3.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft3.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft3.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft4.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft4.txt deleted file mode 100644 index 4e743cf1454da5..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft4.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -fatal error : Error saving assembly 'D:\OASys\Working\dft4.dll'. ---> Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)) diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft4.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft4.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft4.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft5.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft5.txt deleted file mode 100644 index ec66703720dd92..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft5.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -fatal error : Error saving assembly 'D:\OASys\Working\dft5.dll'. ---> Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)) diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft5.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft5.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft5.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft6.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft6.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft6.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft6.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft6.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft6.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft7.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft7.txt deleted file mode 100644 index 8459c0cbb44018..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft7.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.60220 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All rights reserved. - -fatal error : No file extension specified with option '/out:dft7'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft7.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft7.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft7.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft8.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft8.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft8.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft8.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft8.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft8.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft9.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft9.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft9.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft9.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft9.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/dft9.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft10.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft10.txt deleted file mode 100644 index 4fa33c4ab353b1..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft10.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.51103 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All right reserved. - -error : Response file 'infft10.txt' included multiple times. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft10.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft10.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft10.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft11.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft11.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft11.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft11.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft11.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft11.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft12.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft12.txt deleted file mode 100644 index befb99ac0fc8b1..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft12.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.51103 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All right reserved. - -error : Response file './infft12.txt' included multiple times. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft12.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft12.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft12.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft13.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft13.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft13.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft13.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft13.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft13.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft14.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft14.txt deleted file mode 100644 index 8454244a79bea5..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft14.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.51103 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All right reserved. - -error : Response file '.\infft14.txt' included multiple times. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft14.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft14.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft14.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft15.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft15.txt deleted file mode 100644 index 439abd83499040..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft15.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.51103 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All right reserved. - -error : Response file 'iNFFt15.txt' included multiple times. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft15.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft15.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft15.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft16.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft16.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft16.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft16.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft16.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft16.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft17.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft17.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft17.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft17.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft17.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft17.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft18.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft18.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft18.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft18.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft18.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft18.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft19.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft19.txt deleted file mode 100644 index 184db426b4a39f..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft19.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61016 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -fatal error : Response file '*.txt' could not be found. ---> Illegal characters in path. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft2.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft2.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft2.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft2.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft2.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft2.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft20.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft20.txt deleted file mode 100644 index 0c398111bef197..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft20.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61016 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -error : No filename specified with option '@'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft21.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft21.txt deleted file mode 100644 index 6d15628239c146..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft21.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61016 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -error : Response file 'IDontExist' could not be found. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft3.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft3.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft3.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft3.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft3.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft3.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft4.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft4.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft4.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft4.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft4.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft4.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft5.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft5.txt deleted file mode 100644 index a7420f478af971..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft5.txt +++ /dev/null @@ -1,7 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.51103 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All right reserved. - -error : Source file 'some' could not be found. -error : Source file 'text' could not be found. -fatal error : Unrecognized option: '/allwrong'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft6.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft6.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft6.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft6.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft6.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft6.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft7.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft7.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft7.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft7a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft7a.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft7a.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft7b.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft7b.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft7b.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft8.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft8.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft8.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft8a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft8a.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft8a.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft8b.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft8b.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft8b.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft8c.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft8c.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft8c.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft8d.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft8d.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft8d.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft9.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft9.txt deleted file mode 100644 index 8d18e2ea978f77..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft9.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.51103 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All right reserved. - -error : Response file 'infft9.txt' included multiple times. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft9.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft9.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/fft9.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/help.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/help.txt deleted file mode 100644 index 1d0710434da6bd..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/help.txt +++ /dev/null @@ -1,30 +0,0 @@ -Microsoft (R) XSLT Compiler version 4.0.20914 -[Microsoft (R) .NET Framework version 4.0.20914] -Copyright (C) Microsoft Corporation. All rights reserved. - -xsltc [options] [/class:] [[/class:] ...] - - XSLT Compiler Options - - - OUTPUT FILES - -/out: Specify name of binary output file (default: name of the first source file) -/version: Specify an assembly version -/delaysign[+|-] Delay-sign the assembly using only the public portion of the strong name key -/keyfile: Specify a strong name key file -/keycontainer: Specify a strong name key container -/platform: Limit which platforms this code can run on: x86, Itanium, x64, or anycpu, which is the default - - - RESOURCES - -/win32res: Specify a Win32 resource file (.res) - - - CODE GENERATION - -/class: Specify name of the class for compiled stylesheet (short form: /c) -/debug[+|-] Emit debugging information -/debug:{full|pdbonly} Specify debugging type ('full' is default and enables attaching a debugger) -/settings: Specify security settings in the format (dtd|document|script)[+|-],... - Dtd enables DTDs in stylesheets, document enables document() function, script enables element - - - MISCELLANEOUS - -@ Insert command-line settings from a text file -/help Display this usage message (short form: /?) -/nologo Suppress compiler copyright message diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/identity.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/identity.xsl deleted file mode 100644 index 19ca293c95a2cc..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/identity.xsl +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft10.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft10.txt deleted file mode 100644 index 54de401bd120c4..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft10.txt +++ /dev/null @@ -1 +0,0 @@ -fft10.xsl @infft10b.txt \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft10b.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft10b.txt deleted file mode 100644 index c69772b5c526e1..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft10b.txt +++ /dev/null @@ -1 +0,0 @@ -@infft10c.txt \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft10c.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft10c.txt deleted file mode 100644 index 6e588307330824..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft10c.txt +++ /dev/null @@ -1 +0,0 @@ -@infft10.txt \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft11.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft11.txt deleted file mode 100644 index f8536e74ad8046..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft11.txt +++ /dev/null @@ -1 +0,0 @@ -@.\infft11a.txt \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft11a.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft11a.txt deleted file mode 100644 index ca7220fe0c98d8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft11a.txt +++ /dev/null @@ -1 +0,0 @@ -@.\infft11b.txt \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft11b.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft11b.txt deleted file mode 100644 index 82b80bc4f9b2f5..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft11b.txt +++ /dev/null @@ -1 +0,0 @@ -fft11.xsl \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft12.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft12.txt deleted file mode 100644 index b0fa1cf04f7505..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft12.txt +++ /dev/null @@ -1 +0,0 @@ -fft12.xsl @infft12b.txt \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft12b.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft12b.txt deleted file mode 100644 index f52117fc169f76..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft12b.txt +++ /dev/null @@ -1 +0,0 @@ -@infft12c.txt \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft12c.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft12c.txt deleted file mode 100644 index 5ea66280f05a0f..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft12c.txt +++ /dev/null @@ -1 +0,0 @@ -@./infft12.txt \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft13.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft13.txt deleted file mode 100644 index d092ee21b1f7c3..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft13.txt +++ /dev/null @@ -1 +0,0 @@ -@.\infft13a.txt \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft13a.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft13a.txt deleted file mode 100644 index df8c7fb6da3946..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft13a.txt +++ /dev/null @@ -1 +0,0 @@ -@infft13b.txt \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft13b.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft13b.txt deleted file mode 100644 index ec03228d36464d..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft13b.txt +++ /dev/null @@ -1 +0,0 @@ -fft13.xsl \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft14.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft14.txt deleted file mode 100644 index 4a7308aaa50c14..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft14.txt +++ /dev/null @@ -1 +0,0 @@ -fft14.xsl @infft14b.txt \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft14b.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft14b.txt deleted file mode 100644 index 76e9136a9c2cdf..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft14b.txt +++ /dev/null @@ -1 +0,0 @@ -@.\infft14c.txt \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft14c.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft14c.txt deleted file mode 100644 index 7d08f3479a6fca..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft14c.txt +++ /dev/null @@ -1 +0,0 @@ -@.\infft14.txt \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft15.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft15.txt deleted file mode 100644 index 5e54658da55095..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft15.txt +++ /dev/null @@ -1 +0,0 @@ -fft15.xsl @inFFT15b.txt \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft15b.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft15b.txt deleted file mode 100644 index 88524d0fa49464..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft15b.txt +++ /dev/null @@ -1 +0,0 @@ -@inffT15c.txt \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft15c.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft15c.txt deleted file mode 100644 index 288919921d94c6..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft15c.txt +++ /dev/null @@ -1 +0,0 @@ -@iNFFt15.txt \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft16---.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft16---.txt deleted file mode 100644 index a591e79f93bb311731a52427d69baf6798069312..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20 bcmezWFO4CMp@hMZ!HhwVp@N~9A%_6~MhXQg diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft17.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft17.txt deleted file mode 100644 index 6291d7bc575da0..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft17.txt +++ /dev/null @@ -1,3 +0,0 @@ -#This is some comment #More -fft17.xsl #Here -#More Comments \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft18.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft18.txt deleted file mode 100644 index ba5ea677e8cf63..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft18.txt +++ /dev/null @@ -1 +0,0 @@ -/class:AB#CD fft18.xsl \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft2.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft2.txt deleted file mode 100644 index de682b54f4f74590ab04b46ed48d3753ee600d8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18 ZcmezWFO4CMp@hMRL64z=p_n0u0RTN31oZ#_ diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft3.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft3.txt deleted file mode 100644 index e73e5b55a42dde..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft3.txt +++ /dev/null @@ -1 +0,0 @@ -fft3.xsl \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft4.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft4.txt deleted file mode 100644 index 8b9d5bca3cae87..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft4.txt +++ /dev/null @@ -1 +0,0 @@ -"/debug+" """fft4.xsl""" \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft5.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft5.txt deleted file mode 100644 index bf95a85a28384f..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft5.txt +++ /dev/null @@ -1 +0,0 @@ -/out:out.dll some text /allwrong \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft6.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft6.txt deleted file mode 100644 index 9269a0b64ffe41..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft6.txt +++ /dev/null @@ -1 +0,0 @@ -/class:fft6 /out:fft6.dll fft6.xsl \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft7a.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft7a.txt deleted file mode 100644 index 41b6a96d3b18f5..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft7a.txt +++ /dev/null @@ -1 +0,0 @@ -/class:fft7a fft7a.xsl \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft7b.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft7b.txt deleted file mode 100644 index 7ca93b62698f8d..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft7b.txt +++ /dev/null @@ -1 +0,0 @@ -/class:fft7b fft7b.xsl \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft8a.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft8a.txt deleted file mode 100644 index ae67b3d201796f..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft8a.txt +++ /dev/null @@ -1 +0,0 @@ -/class:fft88 fft8a.xsl \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft8b.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft8b.txt deleted file mode 100644 index b05372e3bcc252..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft8b.txt +++ /dev/null @@ -1 +0,0 @@ -/class:fft8888b fft8b.xsl \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft8c.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft8c.txt deleted file mode 100644 index 07c583eae72a36..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft8c.txt +++ /dev/null @@ -1 +0,0 @@ -/class:fft8c fft8c.xsl \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft9.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft9.txt deleted file mode 100644 index 83fccce0db8d75..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/infft9.txt +++ /dev/null @@ -1 +0,0 @@ -fft9.xsl @infft9.txt \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/mail.xml b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/mail.xml deleted file mode 100644 index 1b8b29950314ad..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/mail.xml +++ /dev/null @@ -1,4 +0,0 @@ - - John Doe -
johndoe@msft.com
-
\ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/multith.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/multith.txt deleted file mode 100644 index cbef23cf722c74..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/multith.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/ns1..cnt17.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/ns1..cnt17.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/ns1..cnt17.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/ns1.ns2.cnt16.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/ns1.ns2.cnt16.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/ns1.ns2.cnt16.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft1.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft1.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft1.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft1.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft1.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft1.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft10.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft10.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft10.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft10.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft10.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft10.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft11.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft11.txt deleted file mode 100644 index d599dd94d74cf4..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft11.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -fatal error : The path 'oft1101234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789.dll' is not valid. ---> The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft11.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft11.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft11.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft12.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft12.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft12.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft12.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft12.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft12.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft13.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft13.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft13.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft13.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft13.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft13.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft14.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft14.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft14.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft14.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft14.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft14.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft15.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft15.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft15.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft15.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft15.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft15.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft16.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft16.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft16.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft16.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft16.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft16.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft17.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft17.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft17.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft17.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft17.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft17.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft18.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft18.txt deleted file mode 100644 index 2e6a233a9b459e..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft18.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -fatal error : Error saving assembly 'a:\oft18.dll'. ---> Invalid directory, 'a:\'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft18.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft18.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft18.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft19.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft19.txt deleted file mode 100644 index 8c99251f7ce1d0..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft19.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -fatal error : The path 'nul.dll' is not valid. ---> Win32 device names are not allowed. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft19.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft19.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft19.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft2.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft2.txt deleted file mode 100644 index 59692794563682..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft2.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.60220 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All rights reserved. - -fatal error : No filename specified with option '/out:'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft2.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft2.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft2.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft20.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft20.txt deleted file mode 100644 index e06ee67f488d14..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft20.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -fatal error : The path 'oft|20.dll' is not valid. ---> Illegal characters in path. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft20.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft20.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft20.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft21.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft21.txt deleted file mode 100644 index 902db9bfe88913..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft21.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -fatal error : The path 'COM1.dll' is not valid. ---> Win32 device names are not allowed. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft21.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft21.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft21.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft22.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft22.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft22.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft22.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft22.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft22.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft23.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft23.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft23.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft23.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft23.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft23.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft25.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft25.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft25.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft25.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft25.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft25.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft27.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft27.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft27.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft27.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft27.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft27.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft28.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft28.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft28.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft28.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft28.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft28.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft29.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft29.txt deleted file mode 100644 index f27dab90fe1025..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft29.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61016 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -fatal error : Error saving assembly 'd:\nul\oft29.dll'. ---> Invalid directory, 'd:\nul\'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft29.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft29.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft29.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft3.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft3.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft3.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft3.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft3.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft3.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft30.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft30.txt deleted file mode 100644 index a99a1317b9ea64..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft30.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61016 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -fatal error : No directory specified with option '/out:\\foo\bar.dll'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft30.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft30.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft30.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft31.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft31.txt deleted file mode 100644 index c1860af411e11d..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft31.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61016 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -fatal error : Error saving assembly '\\foo\foo\bar.dll'. ---> Invalid directory, '\\foo\foo\'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft31.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft31.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft31.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft4.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft4.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft4.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft4a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft4a.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft4a.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft4b.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft4b.xsl deleted file mode 100644 index 5705c4ff25e3e5..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft4b.xsl +++ /dev/null @@ -1,10 +0,0 @@ - - - - - DIFFERENT - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft5.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft5.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft5.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft5a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft5a.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft5a.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft5b.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft5b.xsl deleted file mode 100644 index 5705c4ff25e3e5..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft5b.xsl +++ /dev/null @@ -1,10 +0,0 @@ - - - - - DIFFERENT - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft6.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft6.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft6.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft6a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft6a.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft6a.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft6b.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft6b.xsl deleted file mode 100644 index 5705c4ff25e3e5..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft6b.xsl +++ /dev/null @@ -1,10 +0,0 @@ - - - - - DIFFERENT - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft7.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft7.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft7.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft7.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft7.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft7.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft8.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft8.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft8.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft8.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft8.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft8.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft9.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft9.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft9.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft9.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft9.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/oft9.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft1.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft1.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft1.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft1.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft1.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft1.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft10.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft10.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft10.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft10.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft10.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft10.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft11.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft11.txt deleted file mode 100644 index 72a1f6a14cbe73..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft11.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.60220 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All rights reserved. - -fatal error : Unrecognized option: '/platform'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft11.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft11.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft11.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft12.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft12.txt deleted file mode 100644 index b7dc7b77494a92..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft12.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -error : Invalid value '' for option /platform; must be x86, Itanium, x64, or anycpu. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft12.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft12.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft12.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft13.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft13.txt deleted file mode 100644 index 523650727f5f85..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft13.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -error : Invalid value '*' for option /platform; must be x86, Itanium, x64, or anycpu. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft13.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft13.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft13.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft14.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft14.txt deleted file mode 100644 index eadcb72b20de6b..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft14.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -error : Invalid value 'x86x64' for option /platform; must be x86, Itanium, x64, or anycpu. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft14.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft14.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft14.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft15.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft15.txt deleted file mode 100644 index ae9bbd6d54b718..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft15.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -error : Invalid value 'x86,x64' for option /platform; must be x86, Itanium, x64, or anycpu. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft15.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft15.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft15.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft16.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft16.txt deleted file mode 100644 index cd6942251cbba3..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft16.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -error : Invalid value 'x86;x64' for option /platform; must be x86, Itanium, x64, or anycpu. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft16.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft16.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft16.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft17.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft17.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft17.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft17.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft17.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft17.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft18.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft18.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft18.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft18.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft18.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft18.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft19.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft19.txt deleted file mode 100644 index ffbc3412cbfb58..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft19.txt +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft19.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft19.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft19.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft2.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft2.txt deleted file mode 100644 index b7dc7b77494a92..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft2.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -error : Invalid value '' for option /platform; must be x86, Itanium, x64, or anycpu. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft2.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft2.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft2.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft20.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft20.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft20.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft20.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft20.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft20.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft3.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft3.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft3.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft3.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft3.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft3.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft4.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft4.txt deleted file mode 100644 index f7fb1690c54992..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft4.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -error : Invalid value 'foo' for option /platform; must be x86, Itanium, x64, or anycpu. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft4.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft4.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft4.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft7.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft7.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft7.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft7.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft7.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft7.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft8.dll b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft8.dll new file mode 100644 index 0000000000000000000000000000000000000000..2a006367788b705e7fd7cff46138144cb6fe6684 GIT binary patch literal 4096 zcmeHKU2GiH6+ZXQdUrF4x7jsz617praU88(ymb^1ww0ugf8w~{*oh682pZ4sUfWa6 z&TMC9Q*WvUgFvV%RG_M=)Tj2T4+zvsh@w6q9za4uY5RcMhpJN4H&7oD52)09=gy3? zkO;vG4~V;-bI&>VJLjHz&b@cW3zwfKgNQPCc6NwfL(gqe)6XZ{7%m+7OMzb5bEE$? z@xYD#l}#tKnt{I&*bS>@d!8RzRb>S&&vHC#W^vhS_;pq3?lzAlu9s$s9uNkZfBQo< zo$V&c{=H%^kqHe4hIV}j#KJR)hlzzw?hdCgqU~4@igissO|)PC-RcvO0cfM}dw3x2^=rw{T7oN}?`V@mQyrpa*Ep|e9Gj#rdbgkG(HxP`+AmLfMh*Hl%wS)X;~aoA ze8g;ybKr8=@Uh#>Vd@zbglS@28M-X%Bn>i(ZObUUX=ckPpDAUzh^|~>(gkd`+yizP z*q+f0&7+5h)TSizMj7*G_vL+n&AjX@XVLeSF`-!!Wz@wSKLDdF1mxfJvC&MQH{962 zcXoDSzj=BV5JZvsHGJgV?3;uy>Ko$(^-g>XR2u)ki=)jBk39zQK#Z$e{{!U8#CM@8 z38UN%TTF+HnB!OnNeHlx*E9AXOgna@)A|?Mnk$_(ZpAmu`8^0FMvF)0o`X9v_;(1I z@?CJYjnrj^r7&7u)TiSkUM5`Yhm(e4 zP;Vk5WPN72PkEw84Cb+9oXO)j5|_xK0zE;`!`JWWPoQsW`cF;Y2QARY7%fmvFs4^9 zW)L(>_lo17-`8|T(|NHfvb3f7>zckGUe*)FvvSU!5c~B}>;f;ShygC~3B;O%)R2Qz zq-$~r^l5oFEm<6GkzN-j&|8W0SJ4CM*+k079%Sf^MA{<{As+|(VFtS;NL}>DSUR{a z`-$@;=pUH3lS(>@B(tVS&&d;Xh<+vS1O2T$P5tycIR*YjIS2k#c|W3kQ(gppM_vYf z7nrkjQ~r>K=zUoQ@8FNu%hR873L&*r}5jt+12L2Q@ZJIZJLN8$6IjYc$ zs6d7G(hZsh{S9K`o5`TZ=}CG9m7qzEGqX*fX&qO&9uag{_c%AZO`zu7KCK(MgKkXg zG&!~4*ITYSL(TPQjETHB#QEf#kHDKk8->6Lcji%$OfL536X!C-7)!DEkKS*Kl zSJ5K`?qW*??Mp2$avHmSG$3>q`PTuiT~z!gL*pc6YhUD!A&@R7g6{ zsnIz{x%Kn5S9h^KRci%K)Lsc}FKpTY;KV`3|GqmjC*wl;niBq_b*`w^YOzywm!bWuC2VMn#i(?`E|^voCZ zg`hdq*p1z6y6utFS$KvjwHlY;%9Sv(Bd5l@hB{bP1lTs#biOc70FLhKjBv zHI4N;*f|wlup25V<8+`9v$ngyUj=M4oy5buE*CwFtg85y)`$yfwUYrmh_r9EnBBtm z@N73NIO}HAy4`Xkj(yp01vM3Wob~G3Y~FJs$9A1-DlRP_r%K)BcLf=iK5GBEeD1x0 zwKo@kS%2%L#cShU!M;|(L&&{9b@jC0~AFfSND&|Onmb!8I3nN?HC$rzlWDl3_ z?XsjO6uK+{bjG5X^uoJt`w+sOUy2DdF86Ler9-DzwP z?QZ&8NTSu`dx;a`F>f(C-AqSx#<EhTYnpV4c7C`624RhJ^>}h8?^uc literal 0 HcmV?d00001 diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft8.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft8.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft8.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft8.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft8.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft8.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft9.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft9.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft9.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft9.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft9.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/pft9.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft1.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft1.txt deleted file mode 100644 index f4a4ae7c4eae1c..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft1.txt +++ /dev/null @@ -1,3 +0,0 @@ - - Let's see if we can resolve entities: RESOLVED_ENTITY - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft1.xml b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft1.xml deleted file mode 100644 index 2a2b4612e61160..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft1.xml +++ /dev/null @@ -1,4 +0,0 @@ - -Dagon his Name, Sea Monster - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft1.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft1.xsl deleted file mode 100644 index 5519836cd23f87..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft1.xsl +++ /dev/null @@ -1,13 +0,0 @@ - -]> - - - - - - Let's see if we can resolve entities: &myent; - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft10.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft10.txt deleted file mode 100644 index 3d0b723a92086d..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft10.txt +++ /dev/null @@ -1,2 +0,0 @@ - - Script Result: Hello Foo \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft10.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft10.xsl deleted file mode 100644 index a257f37437d0a0..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft10.xsl +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - Script Result: - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft11.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft11.txt deleted file mode 100644 index 8dbf4feb3c2e40..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft11.txt +++ /dev/null @@ -1 +0,0 @@ -John Doe \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft11.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft11.xsl deleted file mode 100644 index e542ade05e632a..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft11.xsl +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft13.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft13.txt deleted file mode 100644 index 8dbf4feb3c2e40..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft13.txt +++ /dev/null @@ -1 +0,0 @@ -John Doe \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft13.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft13.xsl deleted file mode 100644 index e542ade05e632a..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft13.xsl +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft14.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft14.txt deleted file mode 100644 index d7e87d53ccca7c..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft14.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -fatal error : Unrecognized option: '/SETTINGS:SCRIPT+'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft14.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft14.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft14.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft15.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft15.txt deleted file mode 100644 index 5b99a8980042f8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft15.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -error : Invalid setting 'script+-'; must be dtd[+|-], document[+|-] or script[+|-]. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft15.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft15.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft15.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft2.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft2.txt deleted file mode 100644 index 81f1f32706cbb7..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft2.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -sft2.xsl(0,0) : fatal error : Processing DTDs is prohibited. For trusted stylesheets use /settings:dtd option to enable this feature. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft2.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft2.xsl deleted file mode 100644 index 5519836cd23f87..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft2.xsl +++ /dev/null @@ -1,13 +0,0 @@ - -]> - - - - - - Let's see if we can resolve entities: &myent; - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft27.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft27.txt deleted file mode 100644 index f4a4ae7c4eae1c..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft27.txt +++ /dev/null @@ -1,3 +0,0 @@ - - Let's see if we can resolve entities: RESOLVED_ENTITY - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft27.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft27.xsl deleted file mode 100644 index 6537792970f842..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft27.xsl +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft27a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft27a.xsl deleted file mode 100644 index 5519836cd23f87..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft27a.xsl +++ /dev/null @@ -1,13 +0,0 @@ - -]> - - - - - - Let's see if we can resolve entities: &myent; - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft28.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft28.txt deleted file mode 100644 index 9316aa7b5b9d11..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft28.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -sft28a.xsl(0,0) : fatal error : Processing DTDs is prohibited. For trusted stylesheets use /settings:dtd option to enable this feature. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft28.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft28.xsl deleted file mode 100644 index 68752bfac13cc8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft28.xsl +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft28a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft28a.xsl deleted file mode 100644 index 5519836cd23f87..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft28a.xsl +++ /dev/null @@ -1,13 +0,0 @@ - -]> - - - - - - Let's see if we can resolve entities: &myent; - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft29.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft29.txt deleted file mode 100644 index 3d0b723a92086d..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft29.txt +++ /dev/null @@ -1,2 +0,0 @@ - - Script Result: Hello Foo \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft29.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft29.xsl deleted file mode 100644 index 4403a6155719d1..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft29.xsl +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft29a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft29a.xsl deleted file mode 100644 index a257f37437d0a0..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft29a.xsl +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - Script Result: - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft3.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft3.txt deleted file mode 100644 index 3d0b723a92086d..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft3.txt +++ /dev/null @@ -1,2 +0,0 @@ - - Script Result: Hello Foo \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft3.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft3.xsl deleted file mode 100644 index a257f37437d0a0..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft3.xsl +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - Script Result: - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft30.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft30.txt deleted file mode 100644 index 28106a80024e44..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft30.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -sft30a.xsl(17,22) : warning : Execution of scripts is prohibited and will cause a runtime error. For trusted stylesheets use /settings:script option to enable this feature. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft30.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft30.xsl deleted file mode 100644 index e9dcd57fc929d4..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft30.xsl +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft30a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft30a.xsl deleted file mode 100644 index a257f37437d0a0..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft30a.xsl +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - Script Result: - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft31.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft31.txt deleted file mode 100644 index 8dbf4feb3c2e40..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft31.txt +++ /dev/null @@ -1 +0,0 @@ -John Doe \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft31.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft31.xsl deleted file mode 100644 index 738c7c85817450..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft31.xsl +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft31a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft31a.xsl deleted file mode 100644 index e542ade05e632a..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft31a.xsl +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft32.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft32.txt deleted file mode 100644 index 9a0991dce52816..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft32.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -sft32a.xsl(4,5) : warning : Execution of the document() function is prohibited and will cause a runtime error. For trusted stylesheets use /settings:document option to enable this feature. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft32.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft32.xsl deleted file mode 100644 index a0b64b49f87125..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft32.xsl +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft32a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft32a.xsl deleted file mode 100644 index e542ade05e632a..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft32a.xsl +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft33.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft33.txt deleted file mode 100644 index f4a4ae7c4eae1c..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft33.txt +++ /dev/null @@ -1,3 +0,0 @@ - - Let's see if we can resolve entities: RESOLVED_ENTITY - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft33.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft33.xsl deleted file mode 100644 index c12defba7ef0ef..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft33.xsl +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft33a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft33a.xsl deleted file mode 100644 index 5519836cd23f87..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft33a.xsl +++ /dev/null @@ -1,13 +0,0 @@ - -]> - - - - - - Let's see if we can resolve entities: &myent; - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft34.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft34.txt deleted file mode 100644 index 49b81712ff3c81..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft34.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -sft34a.xsl(0,0) : fatal error : Processing DTDs is prohibited. For trusted stylesheets use /settings:dtd option to enable this feature. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft34.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft34.xsl deleted file mode 100644 index 8342f120d9d659..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft34.xsl +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft34a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft34a.xsl deleted file mode 100644 index 5519836cd23f87..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft34a.xsl +++ /dev/null @@ -1,13 +0,0 @@ - -]> - - - - - - Let's see if we can resolve entities: &myent; - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft35.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft35.txt deleted file mode 100644 index 3d0b723a92086d..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft35.txt +++ /dev/null @@ -1,2 +0,0 @@ - - Script Result: Hello Foo \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft35.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft35.xsl deleted file mode 100644 index 3616ee620f27a3..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft35.xsl +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft35a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft35a.xsl deleted file mode 100644 index a257f37437d0a0..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft35a.xsl +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - Script Result: - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft36.dll b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft36.dll new file mode 100644 index 0000000000000000000000000000000000000000..9dbdcf65983d5bbb866c1a99dce5c51057e6b4f1 GIT binary patch literal 5120 zcmeHKPi!1l8UJR+UOSuGWY>*TL#mA97#64A*l}p$RTDX0JBh(g+^mzj$RU}XeYU5b zo!QR3alNfdT}4POrBZ-Y>Y)fB4hV?@Qb4T`QaKa}RcaLpaRNkC!2xmW1&9jf_r005 zH%=6l3-r)8JKy{M|9fxe&CGoD8W}{?f_r0w=q=1V#uU6iSckZC-!D4pXFJ~OeM_5u zuXk?Q3C&vIF9lZBv@Or`rCAnc5P7EKnG@$qX4S8Vd`Cz6K;n9Kl4x2p=)?DaRBlAO zMSAZ}Z6}YG^8r!U*f)rFso&O|kgR}V!tYmN^xp6a z(F6CE+@EU_wKr+BgFe$l=cQPapk)UDWU5xw(>zR~EBUZuNsDNO1!K5b2PHL+F`{4P z1L691lIs;nSucybX^at#H<1dR<-THYZaTHn#D1bbq=_`e{qI57kU^h=8SFFqC@-LH z_{b$a$_eQMhL7Er9-yuvO_i+la&1JZ&+9peQUe5;PW`OSK3JAcr*hqxbUn8RQ|=)K zDJZ9MJwRas8-p%vvkBn5mcuHfQ^5|P!EUC3fi5w=Jl;VzsjQ5i~9r4uX}{j9dn$SuKZEOpo$X>L3t5F8$aC8yg$P_BC6-qO5thrVRf< zDEcT^_1d5za8=&j95-E1{<`&CE0n(lpfQ%#ySc6DIy0VTFu;99yOr&}l~<9w)_)U@ zT5_L-;yRY7WnjGY<#CNQFgW_^k^E48WN2h~lsT>B0=@&yzONI(9hu0WuOtJY`Yx2{CYFb{ci-s?QxlkPf&Pf;an~lDpUj?y%T|5+zprSHJk59tOxybFGoZUWEJp8z}QZ%X=4 zh40W4h2WcIiFvJe^Rx z^?iu@=Y%>4S&Gd4O7o$M`WFbx0>AGdr~APSJ+B|79=fU@2mGd9q+YtFp8@=VJ_Gnu zy#)BSK98#2)h_}51^UC(Zj=H0jZ2Ug0EcM`oL+j;Sfo)}F;?Jh-KfzNy=p{&*Nx`@ zzh@Nbar&|G0`zYvtGAWa`^Hszl0JZRnEnAyomyL7qHiO&GUe&_SiwB)q~B2y@cXET zpQi?0qwmt|L}OfG%Q|fvye{!Ri3J+*-)%cDcMsm7d+-X1r@&(~ekF3n2?`hG$fI=N zWDr>Oxq3|;7#=!G)zJ0>*C|t}9!gP7ru=->ZJ-l467r>|U1pstKP7BQr-dg1ONvSn z2kc3SKUX=DqG7NvFE$ zM=6AEzQLaI^Xm{QXoMU^L%g6U0+JAzkJSUM_wVGQWZ0Lk1K4ut)9pr7BdwThD zC@tyOyho@B6=m*Z2sPH4@mIy1Pes@F1Wkpf@o=?V-W{l|f)2@;qm}`C>ke{B$jix6 zKY>1qlC%Oj>53{EIqln)d)C5^Q6k3BVp~iI+qJOhj_+OY&^3F7!!#KtTVqR@xaLD* zi#fL(_|HtP*`mgt;uw=&B?(TP8SlPRk!Q0)NJS1+vID0kH*-;HXE*m`Ag~;&A!qrO zjC~ZNfOmz$;}$e!6Gv6Kt7T<_$u(?gk2{DBo;aBhi&o@HUWbw&1$NRBq^rz$(H+Zm zo)z&%RgZ#v#pT1YZIOIjw6jVft>FgqctintQ~+huG6|{@)|Un`JKzM+4{GysN$Zlzrld3-szHl-8y<@k!B#4pJ2VER zupGGaz~+=pC~}H%;1KjPDtQx$aN^65lyOT~SMZ=V@hTSrH^JdjO_~SIfl8nxE(gAs zz{}GlFbmc$BzGnl`>uf>z@o0a`GBIy!cvBc`I6iXbTA0ImnTR6+ZIru! z=$!8YWDzVmqbjr(kW&DS1?0mu1+d||xm63uua23ktRnMSC0SKo1?YKjU1+hKwb-Ij z_X1u`V(uw;<62qT;7uqW7C4Os=M2i=au+!h4>RY++hc?tg(RQo=5SyhrAO#6t}lX% zk&1rab;P}W@}(QUedCYz?d#P3=CcbIdyd?CxgGDI9em++MayOY+q0QA(t&3?@Oq^g zsmude{4G^QQ~)!qp#(+fKd zK23Z-n8d8?pbB&{GpV;xOPiMMNww+Oo=iW!B>Li`lF!II9sqnNM_old++Qx6C zxNv@JDDr?tduAHXZ8ngbN63~YzKfFYBks%B7&jTado;eI@cv%(g9+E2u^cZx%7sY& z*7(BiCv)s> - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft36a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft36a.xsl deleted file mode 100644 index a257f37437d0a0..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft36a.xsl +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - Script Result: - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft37.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft37.txt deleted file mode 100644 index 8dbf4feb3c2e40..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft37.txt +++ /dev/null @@ -1 +0,0 @@ -John Doe \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft37.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft37.xsl deleted file mode 100644 index 50a7ff92081cfe..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft37.xsl +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft37a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft37a.xsl deleted file mode 100644 index e542ade05e632a..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft37a.xsl +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft38.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft38.txt deleted file mode 100644 index 221863e2b5c07b..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft38.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -sft38a.xsl(4,5) : warning : Execution of the document() function is prohibited and will cause a runtime error. For trusted stylesheets use /settings:document option to enable this feature. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft38.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft38.xsl deleted file mode 100644 index 726d2d9a915097..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft38.xsl +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft38a.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft38a.xsl deleted file mode 100644 index e542ade05e632a..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft38a.xsl +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft4.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft4.txt deleted file mode 100644 index a0fe2a70b2e8af..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft4.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -sft4.xsl(17,22) : warning : Execution of scripts is prohibited and will cause a runtime error. For trusted stylesheets use /settings:script option to enable this feature. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft4.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft4.xsl deleted file mode 100644 index a257f37437d0a0..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft4.xsl +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - Script Result: - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft41.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft41.txt deleted file mode 100644 index bcce07d17286e3..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft41.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -error : Invalid setting 'DTD~'; must be dtd[+|-], document[+|-] or script[+|-]. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft41.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft41.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft41.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft42.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft42.txt deleted file mode 100644 index d3ad8607def00b..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft42.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -error : Invalid setting 'script*'; must be dtd[+|-], document[+|-] or script[+|-]. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft42.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft42.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft42.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft43.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft43.txt deleted file mode 100644 index 8d5a80a2db7c19..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft43.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -error : Invalid setting 'document%'; must be dtd[+|-], document[+|-] or script[+|-]. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft43.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft43.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft43.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft44.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft44.txt deleted file mode 100644 index 938c6680f2333b..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft44.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -error : Invalid setting 'script+document-'; must be dtd[+|-], document[+|-] or script[+|-]. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft44.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft44.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft44.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft45.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft45.txt deleted file mode 100644 index 211a800acef688..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft45.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.51103 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All right reserved. - -fatal error : Unrecognized option: '/script'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft45.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft45.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft45.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft46.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft46.txt deleted file mode 100644 index 2d4308332e7ed6..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft46.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.51103 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All right reserved. - -fatal error : Unrecognized option: '/script+'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft46.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft46.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft46.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft47.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft47.txt deleted file mode 100644 index bc345aa15ee4f5..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft47.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.51103 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All right reserved. - -fatal error : Unrecognized option: '/DTD'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft47.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft47.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft47.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft48.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft48.txt deleted file mode 100644 index ccf8404bc3f406..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft48.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -fatal error : Unrecognized option: '/DTD-'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft48.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft48.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft48.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft49.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft49.txt deleted file mode 100644 index 50df2e6290f3d4..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft49.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.51103 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All right reserved. - -fatal error : Unrecognized option: '/document'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft49.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft49.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft49.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft5.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft5.txt deleted file mode 100644 index 8dbf4feb3c2e40..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft5.txt +++ /dev/null @@ -1 +0,0 @@ -John Doe \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft5.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft5.xsl deleted file mode 100644 index e542ade05e632a..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft5.xsl +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft50.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft50.txt deleted file mode 100644 index f6a6c53115c57b..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft50.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.51103 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2006. All right reserved. - -fatal error : Unrecognized option: '/document-'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft50.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft50.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft50.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft6.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft6.txt deleted file mode 100644 index ff99dfce83940e..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft6.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -sft6.xsl(4,5) : warning : Execution of the document() function is prohibited and will cause a runtime error. For trusted stylesheets use /settings:document option to enable this feature. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft6.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft6.xsl deleted file mode 100644 index e542ade05e632a..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft6.xsl +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft7.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft7.txt deleted file mode 100644 index 2506577724fef6..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft7.txt +++ /dev/null @@ -1,5 +0,0 @@ -Microsoft (R) XSLT Compiler version 2.0.61009 -for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727 -Copyright (C) Microsoft Corporation 2007. All rights reserved. - -fatal error : Unrecognized option: '/settingsDTD+'. diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft7.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft7.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft7.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft8.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft8.txt deleted file mode 100644 index aac35edb9a8cd8..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft8.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, world! \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft8.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft8.xsl deleted file mode 100644 index 9cbb8246c848f2..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft8.xsl +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft9.txt b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft9.txt deleted file mode 100644 index f4a4ae7c4eae1c..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft9.txt +++ /dev/null @@ -1,3 +0,0 @@ - - Let's see if we can resolve entities: RESOLVED_ENTITY - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft9.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft9.xsl deleted file mode 100644 index 5519836cd23f87..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/baseline/sft9.xsl +++ /dev/null @@ -1,13 +0,0 @@ - -]> - - - - - - Let's see if we can resolve entities: &myent; - - - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/precompiled/Scripting28.xsl b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/precompiled/Scripting28.xsl deleted file mode 100644 index d52e0aace6a4bb01c5908c1d8fe228de940880fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5996 zcmeHLO>fgc5S?p~_zz1iEr%pjMF>Kg3J?eo2SlsFHF1(AQf#BxEv*oL9e8ioW_MjX z-w~BsS+Skj-I?dvc{5}G`Q4FYxsp((qU2JBGLu9m5=$gUQkMg1$`f3Vr7I8Rf&O(c zKf(Mq&Z%7EZiu@v&O`j4r$y=Ywai|GRqad{ZH=)ymG6+XaQx6m6X!!ax&8WL&13lj-27UN$GeJNxC z?!tdK(^BoJ*3tm>8GJB;mMiVOGIAXsB<5=XkDXP)uOaRXM-{w#0gOtX zfzgNZ6bPI6_d(CT#Ox`w3~)6%44)Ndn1c-B7;P}`D9jGwKW3sZdqVQr-3uaRewkq| zty8l>7UA00{}P;y))=x7xy{!>jP#Aai#E3~BQk$XV3~TjW88}iT+gAKUVnqUMf5Yw zq4yUf=PL7@KAL)lqlR3^*y(Gp1<*;a69sK6c@N7|9I?F8-r)#$WM3Xu{?>>9A_1zpMpP+)8E`yy2>nkfKyCj#-IWH|E?cEor z2JaVYu&=%DRPVRQEdy97Vl$R@#r9SGTg~x%5103ft9rP)+qpX)&c98tzYoD__TZ-1 z=UaY?8azfHzK33Q&*`5#sK7Cf)RD1Hx^HG(uXk5+27Oax1HMNb;b-6H%o_|x8qhGp z7~d?I6W9URUdv}h+v&J(cIxa(_@+iS`>67KvU|L4Z+QFB`fS)fUccMfEFOxTq>I*e zb*w1s#KCrvR!8k^Ls}KDo8x3=-fYMHe#6~wzs|3_=i5M7z0Qdy!N}}dtOS%* SRTcYP!=1(NFU9ZTUHJ>3)Xazg diff --git a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/precompiled/sft1.xml b/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/precompiled/sft1.xml deleted file mode 100644 index e6294a90f80c1d..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/TestFiles/TestData/xsltc/precompiled/sft1.xml +++ /dev/null @@ -1,4 +0,0 @@ - -first blockDagon his Name, and the second!Sea Monster - - diff --git a/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/ApiTests/XsltcApiTest.cs b/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/ApiTests/XsltcApiTest.cs deleted file mode 100644 index 4c7cdc7c3a21cb..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/ApiTests/XsltcApiTest.cs +++ /dev/null @@ -1,52 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Xunit; -using Xunit.Abstractions; -using System.Xml.Xsl; -using OLEDB.Test.ModuleCore; - -namespace System.Xml.Tests -{ - //[TestCase(Name = "Load(Type) API Functional Tests", Desc = "This testcase exercises the API tests for the Load(Type) overload")] - public class XsltcAPITest : XsltcTestCaseBase - { - private ITestOutputHelper _output; - public XsltcAPITest(ITestOutputHelper output) : base(output) - { - _output = output; - } - - //[Variation("1", Desc = "Pass null, Load((Type) null)", Pri = 0)] - [Fact] - public void Var1() - { - try - { - new XslCompiledTransform().Load((Type)null); - } - catch (ArgumentNullException) - { - return; - } - - throw new CTestFailedException("Did not throw ArgumentException"); - } - - //[Variation("2", Desc = "Pass types that are not generated by xsltc.exe, Load(typeof(Object))", Pri = 1)] - [Fact] - public void Var2() - { - try - { - new XslCompiledTransform().Load(typeof(object)); - } - catch (ArgumentException) - { - return; - } - - throw new CTestFailedException("Did not throw ArgumentException"); - } - } -} diff --git a/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/CommonScenarios/XsltcTestBasicFunctionality.cs b/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/CommonScenarios/XsltcTestBasicFunctionality.cs deleted file mode 100644 index 788743298e4d15..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/CommonScenarios/XsltcTestBasicFunctionality.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Xunit; -using Xunit.Abstractions; - -namespace System.Xml.Tests -{ - //[TestCase(Name = "Basic Functionality", Desc = "This Testcase maps to test variations described in 'Basic Functional Tests'")] - public class XsltcTestBasicFunctionality : XsltcTestCaseBase - { - private ITestOutputHelper _output; - public XsltcTestBasicFunctionality(ITestOutputHelper output) : base(output) - { - _output = output; - } - - // All variations that are Invalid are run by Var2() - //[Variation("15", Desc = "Exercise what would be a circular reference, a primary stylesheet that includes another, followed by the include itself", Pri = 2, Params = new object[] { "bft15a.xsl bft15b.xsl", "bft15.txt", "EnglishOnly" })] - [InlineData("bft15a.xsl bft15b.xsl", "bft15.txt", true)] - //[Variation("27", Desc = "Exercise whitespace before flag values", Pri = 1, Params = new object[] { "/ out:bft27.dll bft27.xsl", "bft27.txt" })] - [InlineData("/ out:bft27.dll bft27.xsl", "bft27.txt", true)] - //[Variation("30", Desc = "Exercise help with option values", Pri = 1, Params = new object[] { "bft2.xsl /? bft2.xsl", "help.txt" })] - [InlineData("bft2.xsl /? bft2.xsl", "help.txt", true)] - //[Variation("35", Desc = "Device name as stylesheetname", Pri = 1, Params = new object[] { "nul.xsl", "bft35.txt" })] - [InlineData("nul.xsl", "bft35.txt", true)] - //[Variation("37", Desc = "No input source", Pri = 1, Params = new object[] { "/debug+", "bft37.txt" })] - [InlineData("/debug+", "bft37.txt", true)] - //[Variation("38", Desc = "Empty string in arguments", Pri = 1, Params = new object[] { "\"\"", "bft38.txt" })] - [InlineData("\"\"", "bft38.txt", true)] - [Trait("category", "XsltcExeRequired")] - [ConditionalTheory(nameof(xsltcExeFound))] - public void Var2(object param0, object param1, bool englishOnly = false) - { - if (ShouldSkip(englishOnly)) - { - return;// TEST_SKIPPED; - } - string cmdLine = param0.ToString(); - string baselineFile = param1.ToString(); - - VerifyTest(cmdLine, baselineFile, _createFromInputFile); - } - } -} diff --git a/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/CommonScenarios/XsltcTestCaseBase.cs b/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/CommonScenarios/XsltcTestCaseBase.cs deleted file mode 100644 index fba4559896cc56..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/CommonScenarios/XsltcTestCaseBase.cs +++ /dev/null @@ -1,347 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Xunit.Abstractions; -using System.Diagnostics; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Xml.Xsl; -using XmlCoreTest.Common; -using OLEDB.Test.ModuleCore; -using System.Runtime.Loader; - -namespace System.Xml.Tests -{ - public class XsltcTestCaseBase : CTestCase - { - // Generic data for all derived test cases - public string szDefaultNS = "urn:my-object"; - - public string szEmpty = ""; - public string szInvalid = "*?%(){}[]&!@#$"; - public string szLongNS = "http://www.microsoft.com/this/is/a/very/long/namespace/uri/to/do/the/api/testing/for/xslt/0123456789/0123456789/0123456789/0123456789/0123456789/0123456789/0123456789/0123456789/0123456789/0123456789/0123456789/0123456789/0123456789/0123456789/0123456789/0123456789/0123456789/0123456789/"; - public string szLongString = "ThisIsAVeryLongStringToBeStoredAsAVariableToDetermineHowLargeThisBufferForAVariableNameCanBeAndStillFunctionAsExpected"; - public string szSimple = "myArg"; - public string[] szWhiteSpace = { " ", "\n", "\t", "\r", "\t\n \r\t" }; - public string szXslNS = "http://www.w3.org/1999/XSL/Transform"; - - // Other global variables - protected bool _createFromInputFile = false; // This is intiialized from a parameter passed from LTM as a dimension, that dictates whether the variation is to be created using an input file. - - protected bool _isInProc; // Is the current test run in proc or /Host None? - - private static ITestOutputHelper s_output; - public XsltcTestCaseBase(ITestOutputHelper output) - { - s_output = output; - } - - public static bool xsltcExeFound() - { - try - { - // Verify xsltc.exe is available - XmlCoreTest.Common.XsltVerificationLibrary.SearchPath("xsltc.exe"); - } - catch (FileNotFoundException) - { - return false; - } - return true; - } - - public override int Init(object objParam) - { - // initialize whether this run is in proc or not - - string executionMode = "File"; - - _createFromInputFile = executionMode.Equals("File"); - - return 1; - } - - protected static void CompareOutput(string expected, Stream actualStream) - { - using (var expectedStream = new MemoryStream(Encoding.UTF8.GetBytes(expected))) - { - CompareOutput(expectedStream, actualStream); - } - } - - protected static void CompareOutput(Stream expectedStream, Stream actualStream, int count = 0) - { - actualStream.Seek(0, SeekOrigin.Begin); - - using (var expectedReader = new StreamReader(expectedStream)) - using (var actualReader = new StreamReader(actualStream)) - { - for (int i = 0; i < count; i++) - { - actualReader.ReadLine(); - expectedReader.ReadLine(); - } - - string actual = actualReader.ReadToEnd().ReplaceLineEndings(); - string expected = expectedReader.ReadToEnd().ReplaceLineEndings(); - - if (actual.Equals(expected)) - { - return; - } - - throw new CTestFailedException("Output was not as expected.", actual, expected, null); - } - } - - protected bool LoadPersistedTransformAssembly(string asmName, string typeName, string baselineFile, bool pdb) - { - var other = (AssemblyLoader)Activator.CreateInstance(typeof(AssemblyLoader), typeof(AssemblyLoader).FullName); - - bool result = other.Verify(asmName, typeName, baselineFile, pdb); - - return result; - } - - protected string ReplaceCurrentWorkingDirectory(string commandLine) - { - return commandLine.Replace(@"$(CurrentWorkingDirectory)", XsltcModule.TargetDirectory); - } - - protected bool ShouldSkip(bool englishOnly) - { - // some test only applicable in English environment, so skip them if current cultral is not english - return englishOnly && CultureInfo.CurrentCulture.TwoLetterISOLanguageName.ToLower() != "en"; - } - - protected void VerifyTest(string cmdLine, string baselineFile, bool loadFromFile) - { - VerifyTest(cmdLine, string.Empty, false, string.Empty, baselineFile, loadFromFile); - } - - protected void VerifyTest(string cmdLine, string asmName, bool asmCreated, string typeName, string baselineFile, bool loadFromFile) - { - VerifyTest(cmdLine, asmName, asmCreated, typeName, string.Empty, false, baselineFile, loadFromFile); - } - - protected void VerifyTest(string cmdLine, string asmName, bool asmCreated, string typeName, string pdbName, bool pdbCreated, string baselineFile, bool loadFromFile) - { - VerifyTest(cmdLine, asmName, asmCreated, typeName, pdbName, pdbCreated, baselineFile, true, loadFromFile); - } - - protected void VerifyTest(string cmdLine, string asmName, bool asmCreated, string typeName, string pdbName, bool pdbCreated, string baselineFile, bool runAssemblyVerification, bool loadFromFile) - { - string targetDirectory = XsltcModule.TargetDirectory; - - string output = asmCreated ? TryCreatePersistedTransformAssembly(cmdLine, _createFromInputFile, true, targetDirectory) : TryCreatePersistedTransformAssembly(cmdLine, _createFromInputFile, false, targetDirectory); - - //verify assembly file existence - if (asmName != null && string.CompareOrdinal(string.Empty, asmName) != 0) - { - if (File.Exists(GetPath(asmName)) != asmCreated) - { - throw new CTestFailedException("Assembly File Creation Check: FAILED"); - } - } - - //verify pdb existence - if (pdbName != null && string.CompareOrdinal(string.Empty, pdbName) != 0) - { - if (File.Exists(GetPath(pdbName)) != pdbCreated) - { - throw new CTestFailedException("PDB File Creation Check: FAILED"); - } - } - - if (asmCreated && !string.IsNullOrEmpty(typeName)) - { - if (!LoadPersistedTransformAssembly(GetPath(asmName), typeName, baselineFile, pdbCreated)) - { - throw new CTestFailedException("Assembly loaded failed"); - } - } - else - { - using (var ms = new MemoryStream()) - using (var sw = new StreamWriter(ms) { AutoFlush = true }) - using (var expected = new FileStream(GetPath(baselineFile), FileMode.Open, FileAccess.Read)) - { - sw.Write(output); - CompareOutput(expected, ms, 4); - } - } - - SafeDeleteFile(GetPath(pdbName)); - SafeDeleteFile(GetPath(asmName)); - - return; - } - - private static void SafeDeleteFile(string fileName) - { - try - { - var fileInfo = new FileInfo(fileName); - - if (fileInfo.Directory != null && !fileInfo.Directory.Exists) - { - fileInfo.Directory.Create(); - } - - if (fileInfo.Exists) - { - fileInfo.Delete(); - } - } - catch (ArgumentException) - { - } - catch (PathTooLongException) - { - } - catch (Exception e) - { - s_output.WriteLine(e.Message); - } - } - - // Used to generate a unique name for an input file, and write that file, based on a specified command line. - private string CreateInputFile(string commandLine) - { - string fileName = Path.Combine(XsltcModule.TargetDirectory, Guid.NewGuid() + ".ipf"); - - File.WriteAllText(fileName, commandLine); - - return fileName; - } - - private string GetPath(string fileName) - { - return XsltcModule.TargetDirectory + Path.DirectorySeparatorChar + fileName; - } - - /// - /// Currently this method supports only 1 input file. For variations that require more than one input file to test - /// @file - /// functionality, custom-craft and write those input files in the body of the variation method, then pass an - /// appropriate - /// commandline such as @file1 @file2 @file3, along with createFromInputFile = false. - /// - /// - /// - /// - /// - /// - private string TryCreatePersistedTransformAssembly(string commandLine, bool createFromInputFile, bool expectedToSucceed, string targetDirectory) - { - // If createFromInputFile is specified, create an input file now that the compiler can consume. - string processArguments = createFromInputFile ? "@" + CreateInputFile(commandLine) : commandLine; - - var processStartInfo = new ProcessStartInfo - { - FileName = XsltVerificationLibrary.SearchPath("xsltc.exe"), - Arguments = processArguments, - //WindowStyle = ProcessWindowStyle.Hidden, - CreateNoWindow = true, - UseShellExecute = false, - RedirectStandardOutput = true, - WorkingDirectory = targetDirectory - }; - - // Call xsltc to create persistant assembly. - var compilerProcess = new Process - { - StartInfo = processStartInfo - }; - - compilerProcess.Start(); - string output = compilerProcess.StandardOutput.ReadToEnd(); - compilerProcess.WaitForExit(); - - if (createFromInputFile) - { - SafeDeleteFile(processArguments.Substring(1)); - } - - if (expectedToSucceed) - { - // The Assembly was created successfully - if (compilerProcess.ExitCode == 0) - { - return output; - } - - throw new CTestFailedException("Failed to create assembly: " + output); - } - - return output; - } - - public class AssemblyLoader //: MarshalByRefObject - { - public AssemblyLoader(string asmName) - { - } - - public bool Verify(string asmName, string typeName, string baselineFile, bool pdb) - { - try - { - var xslt = new XslCompiledTransform(); - Assembly xsltasm = AssemblyLoadContext.Default.LoadFromAssemblyPath(Path.GetFullPath(asmName)); - - if (xsltasm == null) - { - //_output.WriteLine("Could not load file"); - return false; - } - - Type t = xsltasm.GetType(typeName); - - if (t == null) - { - //_output.WriteLine("No type loaded"); - return false; - } - - xslt.Load(t); - - var inputXml = new XmlDocument(); - - using (var stream = new MemoryStream()) - using (var sw = new StreamWriter(stream) { AutoFlush = true }) - { - inputXml.LoadXml("Hello, world!"); - xslt.Transform(inputXml, null, sw); - - if (!XsltVerificationLibrary.CompareXml(Path.Combine(XsltcModule.TargetDirectory, baselineFile), stream)) - { - //_output.WriteLine("Baseline file comparison failed"); - return false; - } - } - - return true; - } - catch (Exception e) - { - s_output.WriteLine(e.Message); - return false; - } - } - - private static byte[] loadFile(string filename) - { - using (var fs = new FileStream(filename, FileMode.Open)) - { - var buffer = new byte[(int)fs.Length]; - fs.Read(buffer, 0, buffer.Length); - return buffer; - } - } - } - } -} diff --git a/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/CommonScenarios/XsltcTestFile.cs b/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/CommonScenarios/XsltcTestFile.cs deleted file mode 100644 index 7d46bf2fccbb1f..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/CommonScenarios/XsltcTestFile.cs +++ /dev/null @@ -1,76 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Xunit; -using Xunit.Abstractions; -using System; - -namespace System.Xml.Tests -{ - //[TestCase(Name = "File Option Tests", Desc = "This Testcase maps to test variations described in '@file Functional Tests'")] - public class XsltcTestFile : XsltcTestCaseBase - { - private ITestOutputHelper _output; - public XsltcTestFile(ITestOutputHelper output) : base(output) - { - _output = output; - } - - //[Variation("2", Desc = "Create a file that is Unicode encoded and send to xsltc.exe", Pri = 1, Params = new object[] { "@infft2.txt", "fft2.dll", "yes", "fft2", "fft2.pdb", "no", "fft2.txt" })] - //[InlineData("@infft2.txt", "fft2.dll", "yes", "fft2", "fft2.pdb", "no", "fft2.txt")] //Skipping this, it tries to load System.dll - //[Variation("3", Desc = "Create a file that is UTF-8 encoded and send to xsltc.exe", Pri = 1, Params = new object[] { "@infft3.txt", "fft3.dll", "yes", "fft3", "fft3.pdb", "no", "fft3.txt" })] - //[InlineData("@infft3.txt", "fft3.dll", "yes", "fft3", "fft3.pdb", "no", "fft3.txt")] //Skipping this, it tries to load System.dll - //[Variation("4", Desc = "Write specific @files with different quote sets to test quote processing", Pri = 1, Params = new object[] { "@infft4.txt", "fft4.dll", "yes", "fft4", "fft4.pdb", "yes", "fft4.txt" })] - //[InlineData("@infft4.txt", "fft4.dll", "yes", "fft4", "fft4.pdb", "yes", "fft4.txt")] //Skipping this, it tries to load System.dll - //[Variation("5", Desc = "Write specific @file with unsupported format, to see how Xsltc handles invalid format input files.", Pri = 1, Params = new object[] { "@infft5.txt", "fft5.dll", "no", "fft5", "fft5.pdb", "no", "fft5.txt" })] - //[InlineData("@infft5.txt", "fft5.dll", "no", "fft5", "fft5.pdb", "no", "fft5.txt")] //Skipping this, it tries to load System.dll - //[Variation("6", Desc = "Write specific @file with line thats almost the same as a specified command line, see which takes precedence", Pri = 1, Params = new object[] { "/out:fft.dll @infft6.txt", "fft6.dll", "yes", "fft6", "fft6.pdb", "no", "fft6.txt" })] - //[InlineData("/out:fft.dll @infft6.txt", "fft6.dll", "yes", "fft6", "fft6.pdb", "no", "fft6.txt")] //Skipping this, it tries to load System.dll - //[Variation("7", Desc = "Test multiple config files, command line, 2 config files", Pri = 1, Params = new object[] { "@infft7a.txt /out:fft7.dll @infft7b.txt", "fft7.dll", "yes", "fft7a", "fft7a.pdb", "no", "fft7.txt" })] - //[InlineData("@infft7a.txt /out:fft7.dll @infft7b.txt", "fft7.dll", "yes", "fft7a", "fft7a.pdb", "no", "fft7.txt")] //Skipping this, it tries to load System.dll - //[Variation("8", Desc = "Test multiple config files, command line, config, command line, config", Pri = 1, Params = new object[] { "@infft8a.txt /out:fft8.dll @infft8b.txt /class:fft8d fft8d.xsl /debug+ @infft8c.txt", "fft8.dll", "yes", "fft8888b", "fft8.pdb", "yes", "fft8.txt" })] - //[InlineData("@infft8a.txt /out:fft8.dll @infft8b.txt /class:fft8d fft8d.xsl /debug+ @infft8c.txt", "fft8.dll", "yes", "fft8888b", "fft8.pdb", "yes", "fft8.txt")] //Skipping this, it tries to load System.dll - //[Variation("9", Desc = "Test a config file that includes itself", Pri = 1, Params = new object[] { "@infft9.txt", "fft9.dll", "no", "fft9", "fft9.pdb", "no", "fft9.txt" })] - //[InlineData("@infft9.txt", "fft9.dll", "no", "fft9", "fft9.pdb", "no", "fft9.txt")] //Skipping this, it tries to load System.dll - //[Variation("10", Desc = "Test multiple config files with circular reference", Pri = 1, Params = new object[] { "@infft10.txt", "fft10.dll", "no", "fft10", "fft10.pdb", "no", "fft10.txt" })] - //[InlineData("@infft10.txt", "fft10.dll", "no", "fft10", "fft10.pdb", "no", "fft10.txt")] //Skipping this, it tries to load System.dll - //[Variation("11", Desc = "Test multiple config files with relative paths inside the files and command line", Pri = 1, Params = new object[] { @"@.\infft11.txt", "fft11.dll", "yes", "fft11", "fft11.pdb", "no", "fft11.txt" })] - //[InlineData(@"@.\infft11.txt", "fft11.dll", "yes", "fft11", "fft11.pdb", "no", "fft11.txt")] //Skipping this, it tries to load System.dll - //[Variation("12", Desc = "Test multiple config files with circular reference and relative paths", Pri = 1, Params = new object[] { "@infft12.txt", "fft12.dll", "no", "fft12", "fft12.pdb", "no", "fft12.txt" })] - //[InlineData("@infft12.txt", "fft12.dll", "no", "fft12", "fft12.pdb", "no", "fft12.txt")] //Skipping this, it tries to load System.dll - //[Variation("13", Desc = "Test multiple config files with fully qualified path inside the files and command line", Pri = 1, Params = new object[] { @"@$(CurrentWorkingDirectory)\infft13.txt", "fft13.dll", "yes", "fft13", "fft13.pdb", "no", "fft13.txt" })] - //[InlineData(@"@$(CurrentWorkingDirectory)\infft13.txt", "fft13.dll", "yes", "fft13", "fft13.pdb", "no", "fft13.txt")] //Skipping this, it tries to load System.dll - //[Variation("14", Desc = "Test multiple config files with circular reference and fully qualified path inside the files", Pri = 1, Params = new object[] { "@infft14.txt", "fft14.dll", "no", "fft14", "fft14.pdb", "no", "fft14.txt" })] - [InlineData("@infft14.txt", "fft14.dll", "no", "fft14", "fft14.pdb", "no", "fft14.txt", true)] - //[Variation("15", Desc = "Test multiple config files with circular reference and case sensitive file names specified", Pri = 1, Params = new object[] { "@infft15.txt", "fft15.dll", "no", "fft15", "fft15.pdb", "no", "fft15.txt" })] - //[InlineData("@infft15.txt", "fft15.dll", "no", "fft15", "fft15.pdb", "no", "fft15.txt")] //Skipping this, it tries to load System.dll - //[Variation("17", Desc = "Exercise comments(\u0091#\u0092) within file", Pri = 1, Params = new object[] { "@infft17.txt", "fft17.dll", "yes", "fft17", "fft17.pdb", "no", "fft17.txt" })] - //[InlineData("@infft17.txt", "fft17.dll", "yes", "fft17", "fft17.pdb", "no", "fft17.txt")] //Skipping this, it tries to load System.dll - //[Variation("18", Desc = "When loading from a file exercise commands and filenames with \u0091#\u0094 in them", Pri = 1, Params = new object[] { "@infft18.txt", "fft18.dll", "yes", "AB#CD", "fft18.pdb", "no", "fft18.txt" })] - //[InlineData("@infft18.txt", "fft18.dll", "yes", "AB#CD", "fft18.pdb", "no", "fft18.txt")] //Skipping this, it tries to load System.dll - //[Variation("19", Desc = "Exercise wildcards with @", Pri = 1, Params = new object[] { "@*.txt", "fft19.dll", "no", "fft19", "fft19.pdb", "no", "fft19.txt", "EnglishOnly" })] - [InlineData("@*.txt", "fft19.dll", "no", "fft19", "fft19.pdb", "no", "fft19.txt", true)] - //[Variation("20", Desc = "Exercise @ without filename", Pri = 1, Params = new object[] { "@", "fft20.dll", "no", "fft20", "fft20.pdb", "no", "fft20.txt" })] - [InlineData("@", "fft20.dll", "no", "fft20", "fft20.pdb", "no", "fft20.txt", true)] - //[Variation("21", Desc = "Exercise @ with not existing filename", Pri = 1, Params = new object[] { "@IDontExist", "fft21.dll", "no", "fft21", "fft21.pdb", "no", "fft21.txt" })] - [InlineData("@IDontExist", "fft21.dll", "no", "fft21", "fft21.pdb", "no", "fft21.txt", true)] - [Trait("category", "XsltcExeRequired")] - [ConditionalTheory(nameof(xsltcExeFound))] - public void Var1(object param0, object param1, object param2, object param3, object param4, object param5, object param6, bool englishOnly = false) - { - if (ShouldSkip(englishOnly)) - { - return; //TEST_SKIPPED; - } - string cmdLine = ReplaceCurrentWorkingDirectory(param0.ToString()); - string asmName = param1.ToString(); - bool asmCreated = string.Compare(param2.ToString(), "yes", true) == 0; - string typeName = param3.ToString(); - string pdbName = param4.ToString(); - bool pdbCreated = string.Compare(param5.ToString(), "yes", true) == 0; - string baselineFile = param6.ToString(); - - VerifyTest(cmdLine, asmName, asmCreated, typeName, pdbName, pdbCreated, baselineFile, _createFromInputFile); - } - } -} diff --git a/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/CommonScenarios/XsltcTestPlatform.cs b/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/CommonScenarios/XsltcTestPlatform.cs deleted file mode 100644 index cb8a0f1d72d4f5..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/CommonScenarios/XsltcTestPlatform.cs +++ /dev/null @@ -1,103 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Xunit; -using Xunit.Abstractions; -using System.IO; - -namespace System.Xml.Tests -{ - //[TestCase(Name = "Platform Option Tests", Desc = "This Testcase maps to test variations described in 'Platform Functional Tests'")] - public class XsltcTestPlatform : XsltcTestCaseBase - { - private ITestOutputHelper _output; - public XsltcTestPlatform(ITestOutputHelper output) : base(output) - { - _output = output; - } - - //[Variation("3", Desc = "Exercise basic use case, a supported option val", Pri = 1, Params = new object[] { "/platform:x64 pft3.xsl", "", "pft3.dll", "pft3.txt" })] - [InlineData("/platform:x64 pft3.xsl", "", "pft3.dll", "pft3.txt")] - //[Variation("8", Desc = "Exercise keyword case sensitivity -2", Pri = 1, Params = new object[] { "/PLAtforM:ItaNiuM pft8.xsl", "", "pft8.dll", "pft8.txt" })] - [InlineData("/PLAtforM:ItaNiuM pft8.xsl", "", "pft8.dll", "pft8.txt")] - //[Variation("10", Desc = "Exercise keyword case sensitivity -4", Pri = 1, Params = new object[] { "/PLAtforM:AnyCpU pft10.xsl", "", "pft10.dll", "pft10.txt" })] - [InlineData("/PLAtforM:AnyCpU pft10.xsl", "", "pft10.dll", "pft10.txt")] - [Trait("category", "XsltcExeRequired")] - [ConditionalTheory(nameof(xsltcExeFound))] - public void Var1(object param0, object param1, object param2, object param3) - { - string cmdLine = param0.ToString(); - string asmName = param2.ToString(); - bool asmCreated = true; - string typeName = param1.ToString(); - string pdbName = Path.ChangeExtension(param2.ToString(), ".pdb"); - bool pdbCreated = false; - string baselineFile = param3.ToString(); - - VerifyTest(cmdLine, asmName, asmCreated, typeName, pdbName, pdbCreated, baselineFile, _createFromInputFile); - } - - //[Variation("2", Desc = "Exercise basic use case, no option value", Pri = 1, Params = new object[] { "/platform: pft2.xsl", "pft2.txt" })] - [InlineData("/platform: pft2.xsl", "pft2.txt", true)] - //[Variation("4", Desc = "Exercise basic use case, an unsupported option value", Pri = 1, Params = new object[] { "/platform:foo pft4.xsl", "pft4.txt" })] - [InlineData("/platform:foo pft4.xsl", "pft4.txt", true)] - //[Variation("12", Desc = "Exercise basic use case, an unsupported option value -2", Pri = 1, Params = new object[] { "/platform: pft12.xsl", "pft12.txt" })] - [InlineData("/platform: pft12.xsl", "pft12.txt", true)] - //[Variation("16", Desc = "Exercise basic use case, an unsupported option value -6", Pri = 1, Params = new object[] { "/platform:x86;x64 pft16.xsl", "pft16.txt" })] - [InlineData("/platform:x86;x64 pft16.xsl", "pft16.txt", true)] - [Trait("category", "XsltcExeRequired")] - [ConditionalTheory(nameof(xsltcExeFound))] - public void Var2(object param0, object param1, bool englishOnly = false) - { - if (ShouldSkip(englishOnly)) - { - return; //TEST_SKIPPED; - } - - string cmdLine = param0.ToString(); - string baselineFile = param1.ToString(); - - VerifyTest(cmdLine, baselineFile, _createFromInputFile); - } - - //[Variation("19", Desc = "Compile an assembly for different platform and load", Pri = 1, Params = new object[] { "pft19.xsl", "pft19.dll", "yes", "", "pft19.pdb", "no", "pft19.txt", "no" })] - [InlineData("pft19.xsl", "pft19.dll", "yes", "", "pft19.pdb", "no", "pft19.txt", "no")] - [Trait("category", "XsltcExeRequired")] - [ConditionalTheory(nameof(xsltcExeFound))] - public void Var3(object param0, object param1, object param2, object param3, object param4, object param5, object param6, object param7) - { - string platform = "X86"; //CModInfo.Options["Arc"] as String; - bool isSameMachine = string.Compare(param7.ToString(), "yes", true) == 0; - - string[] platforms = { "x86", "x64", "Itanium" }; - int index; - - if (platform == null) - { - Assert.True(false); - } - if (string.Compare("AMD64", platform, true) == 0) - { - index = 1; - } - else - { - index = 0; - } - - platform = platforms[(index + (isSameMachine - ? 0 - : 1)) % platforms.Length]; - - string cmdLine = param0 + " " + "/platform:" + platform; - string asmName = param1.ToString(); - bool asmCreated = string.Compare(param2.ToString(), "yes", true) == 0; - string typeName = param3.ToString(); - string pdbName = param4.ToString(); - bool pdbCreated = string.Compare(param5.ToString(), "yes", true) == 0; - string baselineFile = param6.ToString(); - - VerifyTest(cmdLine, asmName, asmCreated, typeName, pdbName, pdbCreated, baselineFile, _createFromInputFile); - } - } -} diff --git a/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/CommonScenarios/XsltcTestSettings.cs b/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/CommonScenarios/XsltcTestSettings.cs deleted file mode 100644 index c14ad335b4299e..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/CommonScenarios/XsltcTestSettings.cs +++ /dev/null @@ -1,70 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Xunit; -using Xunit.Abstractions; - -namespace System.Xml.Tests -{ - //[TestCase(Name = "Settings Tests", Desc = "This Testcase maps to test variations described in 'Settings Functional Tests'")] - public class XsltcTestSettings : XsltcTestCaseBase - { - private ITestOutputHelper _output; - public XsltcTestSettings(ITestOutputHelper output) : base(output) - { - _output = output; - } - - //[Variation("4", Desc = "Basic /settings test cases, stylesheet has script, where script-", Pri = 0, Params = new object[] { "/settings:script- sft4.xsl", "sft4hack.dll", "no", "sft4", "sft4.pdb", "no", "sft4.txt" })] - [InlineData("/settings:script- sft4.xsl", "sft4hack.dll", "no", "sft4", "sft4.pdb", "no", "sft4.txt", true)] - //[Variation("6", Desc = "Basic /settings test cases, stylesheet has document(), where document-", Pri = 0, Params = new object[] { "/settings:document- sft6.xsl", "sft6hack.dll", "no", "sft6", "sft6.pdb", "no", "sft6.txt" })] - [InlineData("/settings:document- sft6.xsl", "sft6hack.dll", "no", "sft6", "sft6.pdb", "no", "sft6.txt", true)] - //[Variation("7", Desc = "Exercise settings with no colon", Pri = 0, Params = new object[] { "/settingsDTD+ sft7.xsl", "sft7.dll", "no", "sft7", "sft7.pdb", "no", "sft7.txt" })] - [InlineData("/settingsDTD+ sft7.xsl", "sft7.dll", "no", "sft7", "sft7.pdb", "no", "sft7.txt", true)] - //[Variation("14", Desc = "Exercise Turkish I problem", Pri = 0, Params = new object[] { "/SETT\u0130NGS:SCR\u0130PT+ sft14.xsl", "sft14.dll", "no", "sft14", "sft14.pdb", "no", "sft14.txt", "EnglishOnly" })] - [InlineData("/SETT\u0130NGS:SCR\u0130PT+ sft14.xsl", "sft14.dll", "no", "sft14", "sft14.pdb", "no", "sft14.txt", true)] - //[Variation("15", Desc = "Exercise conflicting +, - symbols", Pri = 0, Params = new object[] { "/settings:script+- sft15.xsl", "sft15.dll", "no", "sft15", "sft15.pdb", "no", "sft15.txt" })] - [InlineData("/settings:script+- sft15.xsl", "sft15.dll", "no", "sft15", "sft15.pdb", "no", "sft15.txt", true)] - //[Variation("28", Desc = "Basic /settings test cases, imported stylesheet has DTD, where DTD-", Pri = 0, Params = new object[] { "/settings:DTD- sft28.xsl", "sft28.dll", "no", "sft28", "sft28.pdb", "no", "sft28.txt" })] - [InlineData("/settings:DTD- sft28.xsl", "sft28.dll", "no", "sft28", "sft28.pdb", "no", "sft28.txt", true)] - //[Variation("30", Desc = "Basic /settings test cases, imported stylesheet has script, where script-", Pri = 0, Params = new object[] { "/settings:script- sft30.xsl", "sft30hack.dll", "no", "sft30", "sft30.pdb", "no", "sft30.txt" })] - [InlineData("/settings:script- sft30.xsl", "sft30hack.dll", "no", "sft30", "sft30.pdb", "no", "sft30.txt", true)] - //[Variation("36", Desc = "Basic /settings test cases, included stylesheet has script, where script-", Pri = 0, Params = new object[] { "/settings:script- sft36.xsl", "sft36hack.dll", "no", "sft36", "sft36.pdb", "no", "sft36.txt" })] - [InlineData("/settings:script- sft36.xsl", "sft36hack.dll", "no", "sft36", "sft36.pdb", "no", "sft36.txt", true)] - //[Variation("38", Desc = "Basic /settings test cases, included stylesheet has document(), where document-", Pri = 0, Params = new object[] { "/settings:document- sft38.xsl", "sft38hack.dll", "no", "sft38", "sft38.pdb", "no", "sft38.txt" })] - [InlineData("/settings:document- sft38.xsl", "sft38hack.dll", "no", "sft38", "sft38.pdb", "no", "sft38.txt", true)] - //[Variation("41", Desc = "Exercise basic use case invalid option specified", Pri = 0, Params = new object[] { "/settings:DTD~ sft41.xsl", "sft41.dll", "no", "sft41", "sft41.pdb", "no", "sft41.txt" })] - [InlineData("/settings:DTD~ sft41.xsl", "sft41.dll", "no", "sft41", "sft41.pdb", "no", "sft41.txt", true)] - //[Variation("42", Desc = "Exercise basic use case invalid option specified", Pri = 0, Params = new object[] { "/settings:script* sft42.xsl", "sft42.dll", "no", "sft42", "sft42.pdb", "no", "sft42.txt" })] - [InlineData("/settings:script* sft42.xsl", "sft42.dll", "no", "sft42", "sft42.pdb", "no", "sft42.txt", true)] - //[Variation("44", Desc = "Exercise basic use case multiple options specified", Pri = 0, Params = new object[] { "/settings:script+document- sft44.xsl", "sft44.dll", "no", "sft44", "sft44.pdb", "no", "sft44.txt" })] - [InlineData("/settings:script+document- sft44.xsl", "sft44.dll", "no", "sft44", "sft44.pdb", "no", "sft44.txt", true)] - //[Variation("46", Desc = "Exercise basic use case invalid option specified", Pri = 0, Params = new object[] { "/script+ sft46.xsl", "sft46.dll", "no", "sft46", "sft46.pdb", "no", "sft46.txt" })] - [InlineData("/script+ sft46.xsl", "sft46.dll", "no", "sft46", "sft46.pdb", "no", "sft46.txt", true)] - //[Variation("48", Desc = "Exercise basic use case invalid option specified", Pri = 0, Params = new object[] { "/DTD- sft48.xsl", "sft48.dll", "no", "sft48", "sft48.pdb", "no", "sft48.txt" })] - [InlineData("/DTD- sft48.xsl", "sft48.dll", "no", "sft48", "sft48.pdb", "no", "sft48.txt", true)] - //[Variation("49", Desc = "Exercise basic use case invalid option specified", Pri = 0, Params = new object[] { "/document sft49.xsl", "sft49.dll", "no", "sft49", "sft49.pdb", "no", "sft49.txt" })] - [InlineData("/document sft49.xsl", "sft49.dll", "no", "sft49", "sft49.pdb", "no", "sft49.txt", true)] - //[Variation("51", Desc = "Regression: Basic /settings test cases, two stylesheet with the same script block", Pri = 0, Params = new object[] { "/settings:script+ sft3.xsl sft4.xsl", "sft3.dll", "yes", "", "sft3.pdb", "no", "sft3.txt" })] - [InlineData("/settings:script+ sft3.xsl sft4.xsl", "sft3.dll", "yes", "", "sft3.pdb", "no", "sft3.txt", true)] - [Trait("category", "XsltcExeRequired")] - [ConditionalTheory(nameof(xsltcExeFound))] - public void Var1(object param0, object param1, object param2, object param3, object param4, object param5, object param6, bool englishOnly = false) - { - if (ShouldSkip(englishOnly)) - { - return; //TEST_SKIPPED; - } - - string cmdLine = param0.ToString(); - string asmName = param1.ToString(); - bool asmCreated = string.Compare(param2.ToString(), "yes", true) == 0; - string typeName = param3.ToString(); - string pdbName = param4.ToString(); - bool pdbCreated = string.Compare(param5.ToString(), "yes", true) == 0; - string baselineFile = param6.ToString(); - - VerifyTest(cmdLine, asmName, asmCreated, typeName, pdbName, pdbCreated, baselineFile, _createFromInputFile); - } - } -} diff --git a/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/Identity.xslt b/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/Identity.xslt deleted file mode 100644 index afec73bebf0e9a..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/Identity.xslt +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/IdentityTransform.xslt b/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/IdentityTransform.xslt deleted file mode 100644 index afec73bebf0e9a..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/IdentityTransform.xslt +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/TestStylesheet.xslt b/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/TestStylesheet.xslt deleted file mode 100644 index 4f2ead16153b00..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/TestStylesheet.xslt +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - Hello - - ! - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/XsltCommon.cs b/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/XsltCommon.cs deleted file mode 100644 index a95ab52277b098..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/XsltCommon.cs +++ /dev/null @@ -1,674 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using OLEDB.Test.ModuleCore; -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Text.RegularExpressions; -using System.Xml; -using System.Xml.XmlDiff; - -namespace XmlCoreTest.Common -{ - /************************************************* - author alexkr - date 12/14/2005 - - This class contains common static methods used to verify the results of an XSLT data-driven test. - It contains the following methods: - CompareXml - used to compare two XML outputs, captured as files, using XmlDiff. - CompareChecksum - used to compare two non-XML outputs, captured as files, using a Checksum calculation. - CompareException - used to compare two Exceptions, or the meta-data of two Exceptions, using an Exception wrapper class. - - ************************************************/ - - public class XsltVerificationLibrary - { - public static string winSDKPath = string.Empty; - - /************************************************* - XMLDiff compare for XSLTV2 data driven tests. - It supports custom data-driven xmldiff options passed from the command line, - It might support an optional helperObject that can perform delayed logging, but does not yet. - ************************************************/ - - public static bool CompareXml(string baselineFile, string actualFile, string xmldiffoptionvalue) - { - return CompareXml(baselineFile, actualFile, xmldiffoptionvalue, null); - } - - public static bool CompareXml(string baselineFile, string actualFile, string xmldiffoptionvalue, DelayedWriteLogger logger) - { - using (var fsActual = new FileStream(actualFile, FileMode.Open, FileAccess.Read)) - using (var fsExpected = new FileStream(baselineFile, FileMode.Open, FileAccess.Read)) - { - return CompareXml(fsActual, fsExpected, xmldiffoptionvalue, logger); - } - } - - public static bool CompareXml(string baselineFile, Stream actualStream) - { - actualStream.Seek(0, SeekOrigin.Begin); - - using (var expectedStream = new FileStream(baselineFile, FileMode.Open, FileAccess.Read)) - return CompareXml(expectedStream, actualStream, string.Empty, null); - } - - public static bool CompareXml(Stream expectedStream, Stream actualStream, string xmldiffoptionvalue, DelayedWriteLogger logger) - { - bool bResult = false; - - // Default Diff options used by XSLT V2 driver. - int defaultXmlDiffOptions = (int)(XmlDiffOption.InfosetComparison | XmlDiffOption.IgnoreEmptyElement | XmlDiffOption.IgnoreAttributeOrder); - XmlDiff diff = new XmlDiff(); - - if (xmldiffoptionvalue == null || xmldiffoptionvalue.Equals(string.Empty)) - diff.Option = (XmlDiffOption)defaultXmlDiffOptions; - else - { - if (logger != null) logger.LogMessage("Custom XmlDiffOptions used. Value passed is " + xmldiffoptionvalue); - diff.Option = (XmlDiffOption)int.Parse(xmldiffoptionvalue); - } - - XmlParserContext context = new XmlParserContext(new NameTable(), null, "", XmlSpace.None); - - try - { - bResult = - diff.Compare(new XmlTextReader(actualStream, XmlNodeType.Element, context), - new XmlTextReader(expectedStream, XmlNodeType.Element, context)); - } - catch (Exception e) - { - bResult = false; - if (logger != null) - { - logger.LogMessage("Exception thrown in XmlDiff compare!"); - logger.LogXml(e.ToString()); - throw; - } - } - - if (bResult) - return true; - - if (logger != null) - { - logger.LogMessage("Mismatch in XmlDiff"); - logger.LogMessage("Actual result: "); - } - - return false; - } - - /************************************************* - Checksum calculation. Legacy. - ************************************************/ - - public static bool CompareChecksum(string Baseline, string OutFile, int driverVersion) - { - return CompareChecksum(Baseline, OutFile, driverVersion, null); - } - - public static bool CompareChecksum(string Baseline, string OutFile, int driverVersion, DelayedWriteLogger logger) - { - return CompareChecksum( - Baseline, - 1, //start from the first line in the baseline file - OutFile, - 1, //start from the first line in the output file - driverVersion, - logger); - } - - /// - /// - /// - /// - /// The line to start comparison in the baseline file - /// - /// The line to start comparison in the output file - /// - /// - /// - public static bool CompareChecksum(string Baseline, int baselineStartLine, string OutFile, int outFileStartLine, int driverVersion, DelayedWriteLogger logger) - { - // Keep people honest. - if (driverVersion == 2) - { - if (logger != null) logger.LogMessage("Calculating checksum for baseline output {0}...", Baseline); - - string expectedCheckSum = CalcChecksum(Baseline, baselineStartLine, logger); - string actualChecksum = CalcChecksum(OutFile, outFileStartLine, logger); - - if (expectedCheckSum.Equals(actualChecksum)) - return true; - else - { - if (logger != null) - { - logger.LogMessage("Actual checksum: {0}, Expected checksum: {1}", actualChecksum, expectedCheckSum); - logger.LogMessage("Actual result: "); - logger.WriteOutputFileToLog(OutFile); - } - return false; - } - } - else throw new NotSupportedException("Not a supported driver version"); - } - - private static string CalcChecksum(string fileName, DelayedWriteLogger logger) - { - return CalcChecksum(fileName, 1, logger); - } - - /// - /// - /// - /// - /// The line to start calculating the checksum. Any text before this line is ignored. First line is 1. - /// - /// - private static string CalcChecksum(string fileName, int startFromLine, DelayedWriteLogger logger) - { - const int BUFFERSIZE = 4096; - decimal dResult = 0; // Numerical value of the checksum - int i = 0; // Generic counter - int cBytesRead = 1; // # of bytes read at one time - int cTotalRead = 0; // Total # of bytes read so far - decimal dEndBuffer = 0; // Buffer to remove from the end (This is necessary because - // notepad adds CR/LF onto the end of every file) - char[] rgBuffer = new char[BUFFERSIZE]; - - string xml = ""; - - StreamReader fs = null; - - try - { - fs = new StreamReader(new FileStream(fileName, FileMode.Open, FileAccess.Read)); - - //switch to the line to start from, lines start from 1 - for (int j = 1; j < startFromLine; j++) - { - fs.ReadLine(); - } - - cBytesRead = fs.Read(rgBuffer, 0, BUFFERSIZE); - - while (cBytesRead > 0) - { - // Keep XML property up to date - xml = string.Concat(xml, new string(rgBuffer, 0, cBytesRead)); - - // Calculate the checksum - for (i = 0; i < cBytesRead; i++) - { - dResult += Math.Round((decimal)(rgBuffer[i] / (cTotalRead + i + 1.0)), 10); - } - - cTotalRead += cBytesRead; - dEndBuffer = 0; - - // Keep reading (in case file is bigger than 4K) - cBytesRead = fs.Read(rgBuffer, 0, BUFFERSIZE); - } - } - catch (Exception ex) - { - if (logger != null) logger.LogXml(ex.ToString()); - return ""; - } - finally - { - if (fs != null) fs.Dispose(); - } - return Convert.ToString(dResult - dEndBuffer, NumberFormatInfo.InvariantInfo); - } - - // Is this really all there is to it? - public static bool DetectEmittedPDB(string fileName) - { - if (File.Exists(fileName)) return true; - else return File.Exists(fileName + ".pdb"); - } - - // Call PEVerify on the Assembly name, parse the output, - // and return true if the output is PASS and false if the output is FAIL. - public static bool VerifyAssemblyUsingPEVerify(string asmName, bool isValidCase, DelayedWriteLogger logger, ref string output) - { - Debug.Assert(asmName != null); - Debug.Assert(asmName != string.Empty); - - if (!asmName.Contains(".dll") || !asmName.Contains(".DLL")) - asmName = asmName + ".dll"; - - if (File.Exists(asmName)) - { - return VerifyAssemblyUsingPEVerify(asmName, logger, ref output); - } - else - { - if (isValidCase) - { - string message = "PEVerify could not be run, no assembly present: " + asmName; - if (logger != null) - logger.LogMessage(message); - output = message; - return false; - } - else return true; - } - } - - public static bool VerifySingleAssemblyUsingPEVerify(string asmName, DelayedWriteLogger logger, ref string output) - { - Debug.Assert(asmName != null); - Debug.Assert(asmName != string.Empty); - - bool result = false; - - if (File.Exists(asmName)) - { - //add double quotes for names with whitespace in them - string processArguments = " /quiet " + "\"" + asmName + "\""; - - // Call PEVerify to verify persistant assembly. - Process peVerifyProcess = new Process(); - peVerifyProcess.StartInfo.FileName = SearchPath("peverify.exe"); - peVerifyProcess.StartInfo.Arguments = " " + processArguments; - //peVerifyProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; - peVerifyProcess.StartInfo.CreateNoWindow = true; - peVerifyProcess.StartInfo.UseShellExecute = false; - peVerifyProcess.StartInfo.RedirectStandardOutput = true; - - peVerifyProcess.Start(); - output = peVerifyProcess.StandardOutput.ReadToEnd(); - peVerifyProcess.WaitForExit(); - - // Check the output for the Assembly name, and the word "PASS" - // For example: - // C:>peverify /quiet 4AC8BD29F3CB888FAD76F7C08FD57AD3.dll - // 4AC8BD29F3CB888FAD76F7C08FD57AD3.dll PASS - if (peVerifyProcess.ExitCode == 0 && output.Contains(asmName) && output.Contains("PASS")) - result = true; - else - { - if (logger != null) - logger.LogMessage("PEVerify could not be run or FAILED : {0}", asmName + " " + output); - result = false; - } - } - else - { - if (logger != null) - logger.LogMessage("Assembly file could not be found : {0}", asmName); - result = false; - } - - return result; - } - - public static bool VerifyAssemblyUsingPEVerify(string asmName, DelayedWriteLogger logger, ref string output) - { - string scriptAsmNameFormat = Path.ChangeExtension(asmName, null) + "_Script{0}.dll"; - int scriptCounter = 0; - string testAsm = asmName; - bool result = false; - - do - { - result = VerifySingleAssemblyUsingPEVerify(testAsm, logger, ref output); - testAsm = string.Format(scriptAsmNameFormat, ++scriptCounter); - } - while (result && File.Exists(testAsm)); - - return result; - } - - public static string SearchPath(string fileName) - { - var locations = new HashSet(StringComparer.OrdinalIgnoreCase); - - // 32 bit if on 64 bit Windows - locations.Add(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), @"Microsoft SDKs\Windows")); - // 32 bit if on 32 bit Windows, otherwise 64 bit - locations.Add(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), @"Microsoft SDKs\Windows")); - // 64 bit if in 32 bit process on 64 bit Windows - locations.Add(Path.Combine(Environment.GetEnvironmentVariable("ProgramW6432"), @"Microsoft SDKs\Windows")); - - var files = new List(); - - foreach (var location in locations) - { - if (Directory.Exists(location)) - files.AddRange(Directory.GetFiles(location, fileName, SearchOption.AllDirectories)); - } - - if (files.Count == 0) - throw new FileNotFoundException(fileName); - - // Prefer newer versions, for stability - files.Sort((left, right) => - { - int comparison = Comparer.Default.Compare(GetVersionFromSDKPath(left), GetVersionFromSDKPath(right)); - - if (comparison == 0) - comparison = string.Compare(left, right, StringComparison.OrdinalIgnoreCase); - - return comparison; - }); - - return files[files.Count - 1]; - } - - // Pull the version out of a path like "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\xsltc.exe" - private static float GetVersionFromSDKPath(string s) - { - Match match = Regex.Match(s, @"\\v(\d+\.\d+)\w?\\", RegexOptions.IgnoreCase); - - float val = 0; - if (match.Success) - float.TryParse(match.Groups[1].Value, out val); - - return val; - } - } - - /************************************************* - This class is a delayed-write message logger, similar to CError.WriteLine etc. It is - instantiated by your XsltDriver and used to record messages that you would normally write - with CError.WriteLine, CError.WriteLineIgnore, or CError.WriteXml, in a buffered manner. - The messages can be written to the final log file using WriteOutputFileToLog() by your driver code - if there is a variation failure, or just discarded when a test passes to keep results.log files - within a managable size on disk. - - As an example, using this method reduced the size of the XSLT V2 log file from 3MB per run to around 300k. - ************************************************/ - - public class DelayedWriteLogger - { - private ArrayList _messageLog; - - public DelayedWriteLogger() - { - _messageLog = new ArrayList(); - } - - // Writes the buffer of messages to the results.log file. - public void WriteOutputFileToLog(string fileName) - { - StreamReader fs = null; - try - { - char[] rgBuffer = new char[4096]; - - fs = new StreamReader(new FileStream(fileName, FileMode.Open, FileAccess.Read)); - - int cBytesRead = fs.Read(rgBuffer, 0, 4096); - while (cBytesRead > 0) - { - this.Log(new string(rgBuffer, 0, cBytesRead)); - cBytesRead = fs.Read(rgBuffer, 0, 4096); - } - } - finally - { - if (fs != null) fs.Dispose(); - this.LogMessage(string.Empty); - } - } - - public void Log(string msg) - { - LogMessage(MessageType.Write, msg, null); - } - - public void LogMessage(string msg) - { - LogMessage(MessageType.WriteLine, msg, null); - } - - public void LogMessage(string msg, params object[] args) - { - LogMessage(MessageType.WriteLineParams, msg, args); - } - - public void LogMessageIgnore(string msg) - { - LogMessage(MessageType.WriteLineIgnore, msg, null); - } - - public void LogXml(string msg) - { - LogMessage(MessageType.Xml, msg, null); - } - - private void LogMessage(MessageType msgtype, string msg, params object[] args) - { - LogMessage message = new LogMessage(msgtype, msg, args); - _messageLog.Add(message); - } - - public void WriteLoggedMessages() - { - foreach (LogMessage mg in _messageLog) - { - switch (mg.type) - { - case MessageType.Write: - CError.Write(mg.msg); - break; - - case MessageType.WriteLine: - CError.WriteLine(mg.msg); - break; - - case MessageType.WriteLineIgnore: - CError.WriteLineIgnore(mg.msg); - break; - - case MessageType.WriteLineParams: - CError.WriteLine(mg.msg, mg.args); - break; - - case MessageType.Xml: - CError.WriteXml(mg.msg); - break; - } - } - } - } - - // used by DelayedWriteLogger - internal enum MessageType - { - Write, - WriteLine, - WriteLineParams, - WriteLineIgnore, - Xml - } - - // used by DelayedWriteLogger - internal class LogMessage - { - public LogMessage(MessageType t, string m, object[] o) - { - type = t; - msg = m; - args = o; - } - - internal MessageType type; - public string msg; - public object[] args; - } - - /************************************************* - author alexkr - date 12/12/2005 - - This class is used to compare expected exceptions with actual exceptions in the CompareException - method, used by the XSLT V2 data driven driver. - - Its use is somewhat subtle, so please read all comments, understand the Equals method, and ask for - introduction before you use it in any new code, or modify existing code. Why? There are many - assumptions made when using this class. Here are some... - - Non-Xml Exceptions are always compared by type, and must never have ExceptionResourceId or ExceptionMessage attributes in a control file. - Xml Exceptions can be either ExceptionId only, ExceptionId and ExceptionMessage for all Xml_UserException exceptions, or ExceptionId and ExceptionResourceId for all non-Xml_UserExceptions - Never have both ExceptionResourceId AND ExceptionMessage attributes set for the same Exception meta-data. The behavior is undefined. - Xml Exceptions that are Xml_UserExceptions and include a MessageFragment will only be compared in ENU runs. Globalized runs resort to Type comparison (ExceptionId) only. - Xml Exceptions that are non-Xml_UserExceptions and include an ExceptionResourceId will be compared for all runs. - - **************************************************/ - - public class XsltRuntimeException - { - public static string XMLUSEREX = "Xml_UserException"; - - private XsltRuntimeException() - { - } // no op, do not call - - public XsltRuntimeException(string a, bool d) - : this(a, XMLUSEREX, string.Empty, d) - { - } - - public XsltRuntimeException(string a, string b, string c, bool d) - { - ExceptionId = a; - ResourceId = b; - MessageFragment = c; - _examineMessages = d; - } - - public string ExceptionId; - public string ResourceId; - public string MessageFragment; - private bool _examineMessages; - - public override string ToString() - { - return ExceptionId + "\n" + ResourceId + "\n" + MessageFragment; - } - - public override int GetHashCode() - { - return base.GetHashCode(); - } - - // The Equals method must always be used this way - // ExpectedException.Equals( ActualException )? - // Please note that if ExamineMessages is true, we are in a non-localized build and we can safely examine exception messages. If false, we fall back to type comparison exclusively. - public override bool Equals(object o) - { - XsltRuntimeException objectToCompareTo = o as XsltRuntimeException; - - Debug.Assert(objectToCompareTo != null); - Debug.Assert(objectToCompareTo.ExceptionId != null, "ExceptionId must be initialized to a valid fully qualified type name"); - Debug.Assert(objectToCompareTo.ResourceId != null, "ResourceId must be initialized to String.Empty, in which case MessageFragment is used, or a legal resource Id"); - Debug.Assert(objectToCompareTo.MessageFragment != null, "MessageFragment must be initialized to String.Empty, in which case ResourceId is used, or a string that represents a specific exception message."); - Debug.Assert(this.ExceptionId != null, "ExceptionId must be initialized to a valid fully qualified type name"); - Debug.Assert(this.ResourceId != null, "ResourceId must be initialized to String.Empty, in which case MessageFragment is used, or a legal resource Id"); - Debug.Assert(this.MessageFragment != null, "MessageFragment must be initialized to String.Empty, in which case ResourceId is used, or a string that represents a specific exception message."); - - // Inside this block, we have two properly initialized XsltRuntimeExceptions to compare. - - ///// - // There are several basic comparisons, each with its own degree of certainty. - // - // The first comparison is the original used by the driver, which we no longer use: if there is any - // exception at all for an expected "Invalid" case, we match. - // - // The second comparison is the initial revision to the driver: an Exception type comparison. This is the least certain. - // type matches should no longer exist once this exception work is complete. These will be flagged by failing the test. - // - // The third comparison is for Xml_UserExceptions. In this case we try to compare the Exception Type and Exception Message. - // If the Exception type does not match, but the message does, we count that as a match. Note that this match is NOT - // immue to the effects of globalized resource strings, and hence is less certain. - // - // The fourth comparison is for NON Xml_UserExceptions. In this case we try to compare the Exception Type and ResourceId. - // If the Exception type does not match, but the resource id does, we count that a match. Note that this match is - // immune to the effects of globalized resource strings. It is the most certain match we can make. - // - ///// - if (!IsXmlException(this.ExceptionId)) - { - // Aye, here's the dillema. If its not an XML exception we can't look up its resource ID. - // So in these cases (very rare anyway) we revert to the old simple days of comparing type to type. - return objectToCompareTo.ExceptionId.Equals(this.ExceptionId); - } - else - { - if (!objectToCompareTo.ResourceId.Equals(string.Empty) && !objectToCompareTo.ResourceId.Equals(XMLUSEREX) && - objectToCompareTo.ResourceId.Equals(this.ResourceId)) - { - //**** The highest degree of certainty we have. ****// - - if (objectToCompareTo.ExceptionId.Equals(this.ExceptionId)) - return true; - // ResourceIds match, but Exception types dont. - else - { - CError.WriteLine("match?\n {0} \ncompare to \n {1} \n pls investigate why this resource id is being thrown in 2 differet exceptions", objectToCompareTo.ToString(), this.ToString()); - return true; - } - } - // ResourceId is Empty or Xml_UserException, or they dont match - else if (!this.MessageFragment.Equals(string.Empty) && _examineMessages) - { - if (objectToCompareTo.ResourceId.Equals(this.ResourceId) && - objectToCompareTo.MessageFragment.Contains(this.MessageFragment)) - { - //**** Very high certainty equivalence ****// - - if (objectToCompareTo.ExceptionId.Equals(this.ExceptionId)) - return true; - - // Messages match, but Exception types dont. - else - { - CError.WriteLine("match?(message matches but exact typename doesn't)\n {0} \ncompare to \n {1} ", objectToCompareTo.ToString(), this.ToString()); - return false; // for now. - } - } - } - // ResourceId is Empty or Xml_UserException or they dont match, Message is Empty or they dont match - else - { - //**** Lower degree of certainty ****// - // This is an exception that has not yet been updated in the control file with complete information. - // Use the older, less flexible comparison logic. - CError.WriteLine("old comparison:{0} \ncompare to \n {1} ", objectToCompareTo.ToString(), this.ToString()); - return objectToCompareTo.ExceptionId.Equals(this.ExceptionId); - } - } - return false; - } - - public static ArrayList XmlExceptionList = new ArrayList(5); - - private static void setXmlExceptionList() - { - XmlExceptionList.Add("System.Xml.Xsl.XPath.XPathCompileException"); - XmlExceptionList.Add("System.Xml.Xsl.XslLoadException"); - XmlExceptionList.Add("System.Xml.Xsl.XslTransformException"); - XmlExceptionList.Add("System.Xml.Xsl.XsltException"); - XmlExceptionList.Add("System.Xml.XmlException"); - } - - public static bool IsXmlException(string typeName) - { - setXmlExceptionList(); - return XmlExceptionList.Contains(typeName); - } - } -} diff --git a/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/XsltCompiler.Tests.csproj b/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/XsltCompiler.Tests.csproj deleted file mode 100644 index 424c4d465db44d..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/XsltCompiler.Tests.csproj +++ /dev/null @@ -1,35 +0,0 @@ - - - $(NetCoreAppCurrent) - - - - - WasmTestOnBrowser - $(TestArchiveRoot)browserornodejs/ - $(TestArchiveTestsRoot)$(OSPlatformConfig)/ - $(DefineConstants);TARGET_BROWSER - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/XsltcModule.cs b/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/XsltcModule.cs deleted file mode 100644 index 51193a65c2b70c..00000000000000 --- a/src/libraries/System.Private.Xml/tests/Xslt/XsltCompiler/XsltcModule.cs +++ /dev/null @@ -1,44 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.IO; -using XmlCoreTest.Common; -using OLEDB.Test.ModuleCore; - -namespace System.Xml.Tests -{ - //[TestModule(Name = "Xsltc", Desc = "Xsltc Compiler Tests", Pri = 1)] - public class XsltcModule : CTestModule - { - public static string TargetDirectory = Path.Combine("TestFiles", FilePathUtil.GetTestDataPath(), "xsltc", "baseline"); - - public void CopyDataFiles(string sourcePath, string targetDir) - { - if (!Directory.Exists(targetDir)) - { - Directory.CreateDirectory(targetDir); - } - - foreach (string file in Directory.GetFiles(sourcePath)) - { - string fileName = Path.GetFileName(file); - if (!File.Exists(Path.Combine(targetDir, fileName))) - { - File.Copy(file, Path.Combine(targetDir, fileName), true); - } - } - } - - public override int Init(object objParam) - { - int ret = base.Init(objParam); - - // copy all the data files to working folder - CopyDataFiles(Path.Combine("TestFiles", FilePathUtil.GetTestDataPath(), "xsltc"), TargetDirectory); - CopyDataFiles(Path.Combine("TestFiles", FilePathUtil.GetTestDataPath(), "xsltc", "precompiled"), TargetDirectory); - CopyDataFiles(Path.Combine("TestFiles", FilePathUtil.GetTestDataPath(), "xsltc", "baseline"), TargetDirectory); - - return ret; - } - } -} From 89962a54d60e4d9c9837012d1729c5a72ec748cd Mon Sep 17 00:00:00 2001 From: Aaron Robinson Date: Tue, 14 Jun 2022 08:23:27 -0700 Subject: [PATCH 107/337] Reenable C4244 in repo (#70026) * Reenable 4244 warning for Mono. * Enable compiler errors for gcc/clang. * Fix issues enabling -Werror=implicit-int-conversion * Revert turning on implicit-int-conversion as error. This check was triggering failures on parts of the PAL that require additional scrutiny beyond the scope of this work. --- src/coreclr/inc/corhlprpriv.h | 4 +- src/coreclr/inc/llvm/ELF.h | 4 +- src/coreclr/pal/inc/pal_endian.h | 2 +- src/coreclr/pal/src/cruntime/file.cpp | 2 +- src/coreclr/pal/src/cruntime/printf.cpp | 22 +++---- src/coreclr/pal/src/cruntime/printfcpp.cpp | 18 +++--- .../pal/src/cruntime/silent_printf.cpp | 4 +- src/coreclr/pal/src/file/filetime.cpp | 12 ++-- src/coreclr/pal/src/locale/utf8.cpp | 2 +- src/coreclr/pal/src/misc/time.cpp | 16 ++--- src/coreclr/pal/src/safecrt/input.inl | 8 +-- src/coreclr/pal/src/safecrt/wcslwr_s.cpp | 2 +- src/coreclr/utilcode/clrconfig.cpp | 6 +- src/mono/CMakeLists.txt | 6 +- src/mono/cmake/config.h.in | 1 - src/mono/mono/component/debugger-agent.c | 6 +- src/mono/mono/component/mini-wasm-debugger.c | 2 +- src/mono/mono/eglib/gdir-unix.c | 2 +- src/mono/mono/eglib/giconv.c | 4 +- src/mono/mono/eventpipe/ep-rt-mono.c | 20 +++---- src/mono/mono/metadata/icall-eventpipe.c | 4 +- src/mono/mono/mini/aot-compiler.c | 2 +- src/mono/mono/mini/cfgdump.c | 4 +- src/mono/mono/mini/debug-mini.c | 2 +- src/mono/mono/mini/dwarfwriter.c | 2 +- src/mono/mono/mini/interp/transform.c | 4 +- src/mono/mono/mini/mini-amd64.c | 17 +++--- src/mono/mono/mini/mini-arm.c | 58 +++++++++---------- src/mono/mono/mini/mini-arm64.c | 14 ++--- src/mono/mono/mini/mini-llvm.c | 6 +- src/mono/mono/mini/mini-unwind.h | 16 ++--- src/mono/mono/mini/mini-x86.c | 4 +- src/mono/mono/profiler/aot.c | 2 +- src/mono/mono/profiler/log.c | 10 ++-- src/mono/mono/utils/mono-rand.c | 2 +- src/native/eventpipe/ds-ipc-pal-socket.c | 6 +- src/native/external/libunwind.cmake | 4 ++ src/native/external/zlib-intel.cmake | 4 +- src/native/external/zlib.cmake | 4 +- 39 files changed, 158 insertions(+), 150 deletions(-) diff --git a/src/coreclr/inc/corhlprpriv.h b/src/coreclr/inc/corhlprpriv.h index 38faa6f6ef8be7..2c8372860ba2e2 100644 --- a/src/coreclr/inc/corhlprpriv.h +++ b/src/coreclr/inc/corhlprpriv.h @@ -605,7 +605,7 @@ class RidBitmap HRESULT hr = S_OK; mdToken rid = RidFromToken(token); SIZE_T index = rid / 8; - BYTE bit = (1 << (rid % 8)); + BYTE bit = (BYTE)(1 << (rid % 8)); if (index >= buffer.Size()) { @@ -623,7 +623,7 @@ class RidBitmap { mdToken rid = RidFromToken(token); SIZE_T index = rid / 8; - BYTE bit = (1 << (rid % 8)); + BYTE bit = (BYTE)(1 << (rid % 8)); return ((index < buffer.Size()) && (buffer[index] & bit)); } diff --git a/src/coreclr/inc/llvm/ELF.h b/src/coreclr/inc/llvm/ELF.h index 9e89b48b514a3c..b38ecf9eba73a7 100644 --- a/src/coreclr/inc/llvm/ELF.h +++ b/src/coreclr/inc/llvm/ELF.h @@ -829,7 +829,7 @@ struct Elf32_Sym { void setBinding(unsigned char b) { setBindingAndType(b, getType()); } void setType(unsigned char t) { setBindingAndType(getBinding(), t); } void setBindingAndType(unsigned char b, unsigned char t) { - st_info = (b << 4) + (t & 0x0f); + st_info = (unsigned char)((b << 4) + (t & 0x0f)); } }; @@ -849,7 +849,7 @@ struct Elf64_Sym { void setBinding(unsigned char b) { setBindingAndType(b, getType()); } void setType(unsigned char t) { setBindingAndType(getBinding(), t); } void setBindingAndType(unsigned char b, unsigned char t) { - st_info = (b << 4) + (t & 0x0f); + st_info = (unsigned char)((b << 4) + (t & 0x0f)); } }; diff --git a/src/coreclr/pal/inc/pal_endian.h b/src/coreclr/pal/inc/pal_endian.h index 6822b004ddaafe..43a8167562eeee 100644 --- a/src/coreclr/pal/inc/pal_endian.h +++ b/src/coreclr/pal/inc/pal_endian.h @@ -16,7 +16,7 @@ extern "C++" { inline UINT16 SWAP16(UINT16 x) { - return (x >> 8) | (x << 8); + return (UINT16)((x >> 8) | (x << 8)); } inline UINT32 SWAP32(UINT32 x) diff --git a/src/coreclr/pal/src/cruntime/file.cpp b/src/coreclr/pal/src/cruntime/file.cpp index eb2512c68e0e39..70462122c10a2e 100644 --- a/src/coreclr/pal/src/cruntime/file.cpp +++ b/src/coreclr/pal/src/cruntime/file.cpp @@ -522,7 +522,7 @@ PAL_fread(void * buffer, size_t size, size_t count, PAL_FILE * f) } else { - temp[nCount++]=nChar; + temp[nCount++]= (char)nChar; } } } diff --git a/src/coreclr/pal/src/cruntime/printf.cpp b/src/coreclr/pal/src/cruntime/printf.cpp index 00c7d70c8af58e..c312a935656f95 100644 --- a/src/coreclr/pal/src/cruntime/printf.cpp +++ b/src/coreclr/pal/src/cruntime/printf.cpp @@ -265,7 +265,7 @@ static BOOL Internal_ScanfExtractFormatW(LPCWSTR *Fmt, LPSTR Out, int iOutSize, if (*Fmt && **Fmt == '%') { - *Out++ = *(*Fmt)++; + *Out++ = (CHAR)*(*Fmt)++; } else { @@ -285,7 +285,7 @@ static BOOL Internal_ScanfExtractFormatW(LPCWSTR *Fmt, LPSTR Out, int iOutSize, if (**Fmt == '*') { *Store = FALSE; - *Out++ = *(*Fmt)++; + *Out++ = (CHAR)*(*Fmt)++; } /* grab width specifier */ @@ -294,8 +294,8 @@ static BOOL Internal_ScanfExtractFormatW(LPCWSTR *Fmt, LPSTR Out, int iOutSize, TempStrPtr = TempStr; while (isdigit(**Fmt)) { - *TempStrPtr++ = **Fmt; - *Out++ = *(*Fmt)++; + *TempStrPtr++ = (CHAR)**Fmt; + *Out++ = (CHAR)*(*Fmt)++; } *TempStrPtr = 0; /* end string */ *Width = atoi(TempStr); @@ -406,7 +406,7 @@ static BOOL Internal_ScanfExtractFormatW(LPCWSTR *Fmt, LPSTR Out, int iOutSize, Out += strlen(scanf_longlongfmt); } - *Out++ = *(*Fmt)++; + *Out++ = (CHAR)*(*Fmt)++; Result = TRUE; } else if (**Fmt == 'e' || **Fmt == 'E' || **Fmt == 'f' || @@ -416,7 +416,7 @@ static BOOL Internal_ScanfExtractFormatW(LPCWSTR *Fmt, LPSTR Out, int iOutSize, *Type = SCANF_TYPE_FLOAT; /* this gets rid of %E/%G since they're they're the same when scanning */ - *Out++ = tolower( *(*Fmt)++ ); + *Out++ = (CHAR)tolower( *(*Fmt)++ ); Result = TRUE; } else if (**Fmt == 'n') @@ -425,7 +425,7 @@ static BOOL Internal_ScanfExtractFormatW(LPCWSTR *Fmt, LPSTR Out, int iOutSize, { *Out++ = 'h'; } - *Out++ = *(*Fmt)++; + *Out++ = (CHAR)*(*Fmt)++; *Type = SCANF_TYPE_N; Result = TRUE; } @@ -489,8 +489,8 @@ static BOOL Internal_ScanfExtractFormatW(LPCWSTR *Fmt, LPSTR Out, int iOutSize, unsigned char prev, next; /* get the interval boundaries */ - prev = (*Fmt)[-1]; - next = (*Fmt)[1]; + prev = (unsigned char)(*Fmt)[-1]; + next = (unsigned char)(*Fmt)[1]; /* if boundaries were inverted, replace the already-copied low boundary by the 'real' low boundary */ @@ -514,7 +514,7 @@ static BOOL Internal_ScanfExtractFormatW(LPCWSTR *Fmt, LPSTR Out, int iOutSize, else { /* plain character; just copy it */ - *Out++ = **Fmt; + *Out++ = (CHAR)**Fmt; (*Fmt)++; } } @@ -625,7 +625,7 @@ int PAL_wvsscanf(LPCWSTR Buffer, LPCWSTR Format, va_list ap) { if (Prefix == SCANF_PREFIX_SHORT) { - *(va_arg(ap, short *)) = Buff - Buffer; + *(va_arg(ap, short *)) = (short)(Buff - Buffer); } else { diff --git a/src/coreclr/pal/src/cruntime/printfcpp.cpp b/src/coreclr/pal/src/cruntime/printfcpp.cpp index e014fe015e21f9..ae37ffbf1a27a2 100644 --- a/src/coreclr/pal/src/cruntime/printfcpp.cpp +++ b/src/coreclr/pal/src/cruntime/printfcpp.cpp @@ -706,7 +706,7 @@ BOOL Internal_ExtractFormatW(CPalThread *pthrCurrent, LPCWSTR *Fmt, LPSTR Out, L *Out++ = 'l'; *Out++ = 'l'; } - *Out++ = *(*Fmt)++; + *Out++ = (CHAR)*(*Fmt)++; Result = TRUE; } else if (**Fmt == 'e' || **Fmt == 'E' || **Fmt == 'f' || @@ -719,7 +719,7 @@ BOOL Internal_ExtractFormatW(CPalThread *pthrCurrent, LPCWSTR *Fmt, LPSTR Out, L } *Type = PFF_TYPE_FLOAT; - *Out++ = *(*Fmt)++; + *Out++ = (CHAR)*(*Fmt)++; Result = TRUE; } else if (**Fmt == 'n') @@ -733,7 +733,7 @@ BOOL Internal_ExtractFormatW(CPalThread *pthrCurrent, LPCWSTR *Fmt, LPSTR Out, L { *Out++ = 'h'; } - *Out++ = *(*Fmt)++; + *Out++ = (CHAR)*(*Fmt)++; *Type = PFF_TYPE_N; Result = TRUE; } @@ -1220,8 +1220,8 @@ int CoreVfwprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const wchar_16 *for TempInt = va_arg(ap, INT); /* value not used */ } - TempWChar[0] = va_arg(ap, int); - TempWChar[1] = 0; + TempWChar[0] = (WCHAR)va_arg(ap, int); + TempWChar[1] = W('\0'); /* do the padding (if needed)*/ paddingReturnValue = @@ -1254,7 +1254,7 @@ int CoreVfwprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const wchar_16 *for if (Prefix == PFF_PREFIX_SHORT) { - *(va_arg(ap, short *)) = written; + *(va_arg(ap, short *)) = (short)written; } else { @@ -1605,7 +1605,7 @@ int CoreVfprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const char *format, TempInt = va_arg(ap, INT); /* value not used */ } - TempWChar = va_arg(ap, int); + TempWChar = (WCHAR)va_arg(ap, int); Length = WideCharToMultiByte(CP_ACP, 0, &TempWChar, 1, TempBuffer, sizeof(TempBuffer), 0, 0); @@ -1617,7 +1617,7 @@ int CoreVfprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const char *format, va_end(ap); return -1; } - TempBuffer[Length] = 0; + TempBuffer[Length] = W('\0'); /* do the padding (if needed)*/ paddingReturnValue = @@ -1648,7 +1648,7 @@ int CoreVfprintf(CPalThread *pthrCurrent, PAL_FILE *stream, const char *format, if (Prefix == PFF_PREFIX_SHORT) { - *(va_arg(ap, short *)) = written; + *(va_arg(ap, short *)) = (short)written; } else { diff --git a/src/coreclr/pal/src/cruntime/silent_printf.cpp b/src/coreclr/pal/src/cruntime/silent_printf.cpp index 17e3007c762fc2..05a0e85906c811 100644 --- a/src/coreclr/pal/src/cruntime/silent_printf.cpp +++ b/src/coreclr/pal/src/cruntime/silent_printf.cpp @@ -168,7 +168,7 @@ int Silent_PAL_vfprintf(PAL_FILE *stream, const char *format, va_list aparg) TempInt = va_arg(ap, INT); /* value not used */ } - TempWChar = va_arg(ap, int); + TempWChar = (WCHAR)va_arg(ap, int); Length = Silent_WideCharToMultiByte(&TempWChar, 1, TempBuffer, 4); if (!Length) { @@ -204,7 +204,7 @@ int Silent_PAL_vfprintf(PAL_FILE *stream, const char *format, va_list aparg) if (Prefix == PFF_PREFIX_SHORT) { - *(va_arg(ap, short *)) = written; + *(va_arg(ap, short *)) = (short)written; } else { diff --git a/src/coreclr/pal/src/file/filetime.cpp b/src/coreclr/pal/src/file/filetime.cpp index 768ee426c4dbfa..ea8ca6bd0535ad 100644 --- a/src/coreclr/pal/src/file/filetime.cpp +++ b/src/coreclr/pal/src/file/filetime.cpp @@ -294,16 +294,16 @@ BOOL PALAPI FileTimeToSystemTime( CONST FILETIME * lpFileTime, #endif /* HAVE_GMTIME_R */ /* Convert unix system time to Windows system time. */ - lpSystemTime->wDay = UnixSystemTime->tm_mday; + lpSystemTime->wDay = (WORD)UnixSystemTime->tm_mday; /* Unix time counts January as a 0, under Windows it is 1*/ - lpSystemTime->wMonth = UnixSystemTime->tm_mon + 1; + lpSystemTime->wMonth = (WORD)UnixSystemTime->tm_mon + 1; /* Unix time returns the year - 1900, Windows returns the current year*/ - lpSystemTime->wYear = UnixSystemTime->tm_year + 1900; + lpSystemTime->wYear = (WORD)UnixSystemTime->tm_year + 1900; - lpSystemTime->wSecond = UnixSystemTime->tm_sec; - lpSystemTime->wMinute = UnixSystemTime->tm_min; - lpSystemTime->wHour = UnixSystemTime->tm_hour; + lpSystemTime->wSecond = (WORD)UnixSystemTime->tm_sec; + lpSystemTime->wMinute = (WORD)UnixSystemTime->tm_min; + lpSystemTime->wHour = (WORD)UnixSystemTime->tm_hour; return TRUE; } else diff --git a/src/coreclr/pal/src/locale/utf8.cpp b/src/coreclr/pal/src/locale/utf8.cpp index 8ff3229fcbabad..c0cf19dba5d7f4 100644 --- a/src/coreclr/pal/src/locale/utf8.cpp +++ b/src/coreclr/pal/src/locale/utf8.cpp @@ -1075,7 +1075,7 @@ class UTF8Encoding DecoderReplacementFallback decoderReplacementFallback; DecoderExceptionFallback decoderExceptionFallback; - bool InRange(WCHAR c, WCHAR begin, WCHAR end) + bool InRange(int c, int begin, int end) { return begin <= c && c <= end; } diff --git a/src/coreclr/pal/src/misc/time.cpp b/src/coreclr/pal/src/misc/time.cpp index ec71e5c72b06cf..7d78ae930c3979 100644 --- a/src/coreclr/pal/src/misc/time.cpp +++ b/src/coreclr/pal/src/misc/time.cpp @@ -82,13 +82,13 @@ GetSystemTime( goto EXIT; } - lpSystemTime->wYear = 1900 + utPtr->tm_year; - lpSystemTime->wMonth = utPtr->tm_mon + 1; - lpSystemTime->wDayOfWeek = utPtr->tm_wday; - lpSystemTime->wDay = utPtr->tm_mday; - lpSystemTime->wHour = utPtr->tm_hour; - lpSystemTime->wMinute = utPtr->tm_min; - lpSystemTime->wSecond = utPtr->tm_sec; + lpSystemTime->wYear = (WORD)(1900 + utPtr->tm_year); + lpSystemTime->wMonth = (WORD)(utPtr->tm_mon + 1); + lpSystemTime->wDayOfWeek = (WORD)utPtr->tm_wday; + lpSystemTime->wDay = (WORD)utPtr->tm_mday; + lpSystemTime->wHour = (WORD)utPtr->tm_hour; + lpSystemTime->wMinute = (WORD)utPtr->tm_min; + lpSystemTime->wSecond = (WORD)utPtr->tm_sec; if(-1 == timeofday_retval) { @@ -101,7 +101,7 @@ GetSystemTime( int old_seconds; int new_seconds; - lpSystemTime->wMilliseconds = timeval.tv_usec/tccMillieSecondsToMicroSeconds; + lpSystemTime->wMilliseconds = (WORD)(timeval.tv_usec/tccMillieSecondsToMicroSeconds); old_seconds = utPtr->tm_sec; new_seconds = timeval.tv_sec%60; diff --git a/src/coreclr/pal/src/safecrt/input.inl b/src/coreclr/pal/src/safecrt/input.inl index 3f415d695833ae..e68dc42f01614c 100644 --- a/src/coreclr/pal/src/safecrt/input.inl +++ b/src/coreclr/pal/src/safecrt/input.inl @@ -665,7 +665,7 @@ scanit: } else #else /* _UNICODE */ if (fl_wchar_arg) { - *(char16_t UNALIGNED *)pointer = ch; + *(char16_t UNALIGNED *)pointer = (char16_t)ch; pointer = (char16_t *)pointer + 1; #ifdef _SECURE_SCANF --array_width; @@ -867,7 +867,7 @@ getnum: if (_ISXDIGIT(ch)) { num64 <<= 4; - ch = _hextodec(ch); + ch = _hextodec((_TCHAR)ch); } else ++done_flag; @@ -910,7 +910,7 @@ getnum: if (_ISXDIGIT(ch)) { number = (number << 4); - ch = _hextodec(ch); + ch = _hextodec((_TCHAR)ch); } else ++done_flag; @@ -1262,7 +1262,7 @@ static int __cdecl _inc(miniFILE* fileptr) static void __cdecl _un_inc(int chr, miniFILE* fileptr) { if (_TEOF != chr) { - _ungettc_nolock(chr,fileptr); + _ungettc_nolock((char)chr,fileptr); } } diff --git a/src/coreclr/pal/src/safecrt/wcslwr_s.cpp b/src/coreclr/pal/src/safecrt/wcslwr_s.cpp index f80ff7bcf344a3..184776f21ee95f 100644 --- a/src/coreclr/pal/src/safecrt/wcslwr_s.cpp +++ b/src/coreclr/pal/src/safecrt/wcslwr_s.cpp @@ -30,7 +30,7 @@ DLLEXPORT errno_t __cdecl _wcslwr_s(char16_t *string, size_t sz) for (int i = 0; string[i] != 0; i++) { - string[i] = towlower(string[i]); + string[i] = (char16_t)towlower(string[i]); } _FILL_STRING(string, sz, length + 1); diff --git a/src/coreclr/utilcode/clrconfig.cpp b/src/coreclr/utilcode/clrconfig.cpp index caad3b594a6eaf..aaa33a6e4b03f2 100644 --- a/src/coreclr/utilcode/clrconfig.cpp +++ b/src/coreclr/utilcode/clrconfig.cpp @@ -634,8 +634,8 @@ void CLRConfig::Initialize() if (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_DisableConfigCache) != 0) return; - const WCHAR prefixC = towlower(COMPLUS_PREFIX[0]); - const WCHAR prefixD = towlower(DOTNET_PREFIX[0]); + const WCHAR prefixC = (WCHAR)towlower(COMPLUS_PREFIX[0]); + const WCHAR prefixD = (WCHAR)towlower(DOTNET_PREFIX[0]); // Create a cache of environment variables WCHAR* wszStrings = GetEnvironmentStringsW(); @@ -645,7 +645,7 @@ void CLRConfig::Initialize() // null terminated strings for(WCHAR *wszCurr = wszStrings; *wszCurr; wszCurr++) { - WCHAR wch = towlower(*wszCurr); + WCHAR wch = (WCHAR)towlower(*wszCurr); // Lets only cache env variables with targeted prefixes bool matchC = wch == prefixC; diff --git a/src/mono/CMakeLists.txt b/src/mono/CMakeLists.txt index c0c513df0f95b9..2be6fc84683299 100644 --- a/src/mono/CMakeLists.txt +++ b/src/mono/CMakeLists.txt @@ -508,13 +508,13 @@ if(GCC) set(WARNINGS "-Wall -Wunused -Wmissing-declarations -Wpointer-arith -Wno-cast-qual -Wwrite-strings -Wno-switch -Wno-switch-enum -Wno-unused-value -Wno-attributes -Wno-format-zero-length -Wno-unused-function") set(WARNINGS_C "-Wmissing-prototypes -Wstrict-prototypes -Wnested-externs") + set(WERROR "-Werror=return-type") + set(WERROR_C "-Werror=implicit-function-declaration") + if (CMAKE_C_COMPILER_ID MATCHES "Clang") set(WARNINGS "${WARNINGS} -Qunused-arguments -Wno-tautological-compare -Wno-parentheses-equality -Wno-self-assign -Wno-return-stack-address -Wno-constant-logical-operand -Wno-zero-length-array -Wno-asm-operand-widths") endif() - set(WERROR "-Werror=return-type") - set(WERROR_C "-Werror=implicit-function-declaration") - check_c_compiler_flag("-Werror=incompatible-pointer-types" WERROR_INCOMPATIBLE_POINTER_TYPES) if(WERROR_INCOMPATIBLE_POINTER_TYPES) set(WERROR_C "${WERROR_C} -Werror=incompatible-pointer-types") diff --git a/src/mono/cmake/config.h.in b/src/mono/cmake/config.h.in index 9245408a013bda..7c093b27deea2f 100644 --- a/src/mono/cmake/config.h.in +++ b/src/mono/cmake/config.h.in @@ -10,7 +10,6 @@ #pragma warning(disable:4152) // W4: nonstandard extension, function/data pointer conversion in expression #pragma warning(disable:4201) // W4: nonstandard extension used: nameless struct/union #pragma warning(disable:4210) // W4: nonstandard extension used: function given file scope -#pragma warning(disable:4244) // W2: integer conversion, possible loss of data #pragma warning(disable:4245) // W4: signed/unsigned mismatch #pragma warning(disable:4389) // W4: signed/unsigned mismatch #pragma warning(disable:4505) // W4: unreferenced function with internal linkage has been removed diff --git a/src/mono/mono/component/debugger-agent.c b/src/mono/mono/component/debugger-agent.c index 519a57412076d9..78b83e0549cd5c 100644 --- a/src/mono/mono/component/debugger-agent.c +++ b/src/mono/mono/component/debugger-agent.c @@ -3554,7 +3554,7 @@ process_event (EventKind event, gpointer arg, gint32 il_offset, MonoContext *ctx buffer_add_int (&buf, nevents); for (l = events; l; l = l->next) { - buffer_add_byte (&buf, event); // event kind + buffer_add_byte (&buf, GINT_TO_UINT8 (event)); // event kind buffer_add_int (&buf, GPOINTER_TO_INT (l->data)); // request id ecount ++; @@ -3628,7 +3628,7 @@ process_event (EventKind event, gpointer arg, gint32 il_offset, MonoContext *ctx EventInfo *ei = (EventInfo *)arg; buffer_add_objid (&buf, ei->exc); #ifdef TARGET_WASM - buffer_add_byte (&buf, ei->caught); + buffer_add_byte (&buf, GINT_TO_UINT8 (ei->caught)); #endif /* * We are not yet suspending, so get_objref () will not keep this object alive. So we need to do it @@ -7243,7 +7243,7 @@ event_commands (int command, guint8 *p, guint8 *end, Buffer *buf) if (!isBPOnManagedCode) { mono_de_cancel_all_ss (); } - buffer_add_byte (buf, isBPOnManagedCode); + buffer_add_byte (buf, GINT_TO_UINT8 (isBPOnManagedCode)); #endif } else if (req->event_kind == EVENT_KIND_METHOD_ENTRY) { req->info = mono_de_set_breakpoint (NULL, METHOD_ENTRY_IL_OFFSET, req, NULL); diff --git a/src/mono/mono/component/mini-wasm-debugger.c b/src/mono/mono/component/mini-wasm-debugger.c index e6e76f9e774d36..f719b1806d1159 100644 --- a/src/mono/mono/component/mini-wasm-debugger.c +++ b/src/mono/mono/component/mini-wasm-debugger.c @@ -232,7 +232,7 @@ write_value_to_buffer (MdbgProtBuffer *buf, MonoTypeEnum type, const char* varia char* endptr = NULL; const char *variableValueEnd = variableValue + strlen(variableValue); errno = 0; - buffer_add_byte (buf, type); + buffer_add_byte (buf, GINT_TO_UINT8 (type)); switch (type) { case MONO_TYPE_BOOLEAN: if (!strcasecmp (variableValue, "True")) diff --git a/src/mono/mono/eglib/gdir-unix.c b/src/mono/mono/eglib/gdir-unix.c index 10b15e7bc24e42..2ce5569c4be09e 100644 --- a/src/mono/mono/eglib/gdir-unix.c +++ b/src/mono/mono/eglib/gdir-unix.c @@ -126,7 +126,7 @@ g_mkdir_with_parents (const gchar *pathname, int mode) if (*d == '/' || *d == '\0') { char orig = *d; *d = '\0'; - rv = mkdir (path, mode); + rv = mkdir (path, (mode_t)mode); if (rv == -1 && errno != EEXIST) { g_free (path); return -1; diff --git a/src/mono/mono/eglib/giconv.c b/src/mono/mono/eglib/giconv.c index c944c8ecfb3586..f7ca5c3e3b8d29 100644 --- a/src/mono/mono/eglib/giconv.c +++ b/src/mono/mono/eglib/giconv.c @@ -158,8 +158,8 @@ static FORCE_INLINE (uint16_t) read_uint16_endian (unsigned char *inptr, unsigned endian) { if (endian == G_LITTLE_ENDIAN) - return (inptr[1] << 8) | inptr[0]; - return (inptr[0] << 8) | inptr[1]; + return (uint16_t)((inptr[1] << 8) | inptr[0]); + return (uint16_t)((inptr[0] << 8) | inptr[1]); } static FORCE_INLINE (int) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index 57ae4f37e9a8c1..ff7b69ab4ea305 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -2511,7 +2511,7 @@ ep_rt_mono_system_time_get (EventPipeSystemTime *system_time) int old_seconds; int new_seconds; - milliseconds = time_val.tv_usec / MSECS_TO_MIS; + milliseconds = (uint16_t)(time_val.tv_usec / MSECS_TO_MIS); old_seconds = ut_ptr->tm_sec; new_seconds = time_val.tv_sec % 60; @@ -2523,13 +2523,13 @@ ep_rt_mono_system_time_get (EventPipeSystemTime *system_time) ep_system_time_set ( system_time, - 1900 + ut_ptr->tm_year, - ut_ptr->tm_mon + 1, - ut_ptr->tm_wday, - ut_ptr->tm_mday, - ut_ptr->tm_hour, - ut_ptr->tm_min, - ut_ptr->tm_sec, + (uint16_t)(1900 + ut_ptr->tm_year), + (uint16_t)ut_ptr->tm_mon + 1, + (uint16_t)ut_ptr->tm_wday, + (uint16_t)ut_ptr->tm_mday, + (uint16_t)ut_ptr->tm_hour, + (uint16_t)ut_ptr->tm_min, + (uint16_t)ut_ptr->tm_sec, milliseconds); } @@ -2609,7 +2609,7 @@ void ep_rt_mono_provider_config_init (EventPipeProviderConfiguration *provider_config) { if (!ep_rt_utf8_string_compare (ep_config_get_rundown_provider_name_utf8 (), ep_provider_config_get_provider_name (provider_config))) { - MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_EVENTPIPE_Context.Level = ep_provider_config_get_logging_level (provider_config); + MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_EVENTPIPE_Context.Level = (uint8_t)ep_provider_config_get_logging_level (provider_config); MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_EVENTPIPE_Context.EnabledKeywordsBitmask = ep_provider_config_get_keywords (provider_config); MICROSOFT_WINDOWS_DOTNETRUNTIME_RUNDOWN_PROVIDER_EVENTPIPE_Context.IsEnabled = true; } @@ -3274,7 +3274,7 @@ ep_rt_mono_log_single_type ( // NOTE: If name is actively used, set it to NULL and relevant memory management to reduce byte count // This type is apparently so huge, it's too big to squeeze into an event, even // if it were the only type batched in the whole event. Bail - mono_trace (G_LOG_LEVEL_ERROR, MONO_TRACE_DIAGNOSTICS, "Failed to log single mono type %p with typeID %llu. Type is too large for the BulkType Event.\n", (gpointer)mono_type, val->fixed_sized_data.type_id); + mono_trace (G_LOG_LEVEL_ERROR, MONO_TRACE_DIAGNOSTICS, "Failed to log single mono type %p with typeID %llu. Type is too large for the BulkType Event.\n", (gpointer)mono_type, (unsigned long long)val->fixed_sized_data.type_id); return -1; } diff --git a/src/mono/mono/metadata/icall-eventpipe.c b/src/mono/mono/metadata/icall-eventpipe.c index f7ee2635e2a1d0..4d1604a808a340 100644 --- a/src/mono/mono/metadata/icall-eventpipe.c +++ b/src/mono/mono/metadata/icall-eventpipe.c @@ -212,7 +212,7 @@ ves_icall_System_Diagnostics_Tracing_EventPipeInternal_GetSessionInfo ( MonoBoolean ves_icall_System_Diagnostics_Tracing_EventPipeInternal_SignalSession (uint64_t session_id) { - return (intptr_t) mono_component_event_pipe()->signal_session ((EventPipeSessionID)session_id); + return mono_component_event_pipe()->signal_session ((EventPipeSessionID)session_id) ? TRUE : FALSE; } MonoBoolean @@ -220,7 +220,7 @@ ves_icall_System_Diagnostics_Tracing_EventPipeInternal_WaitForSessionSignal ( uint64_t session_id, int32_t timeout) { - return (intptr_t) mono_component_event_pipe()->wait_for_session_signal ((EventPipeSessionID)session_id, (uint32_t)timeout); + return mono_component_event_pipe()->wait_for_session_signal ((EventPipeSessionID)session_id, (uint32_t)timeout) ? TRUE : FALSE; } void diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index bd751c1f956508..fac7efd0fa3fe4 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -3029,7 +3029,7 @@ encode_value (gint32 value, guint8 *buf, guint8 **endbuf) p [1] = value & 0xff; p += 2; } else if ((value >= 0) && (value <= 0x1fffffff)) { - p [0] = (value >> 24) | 0xc0; + p [0] = GINT32_TO_UINT8 ((value >> 24) | 0xc0); p [1] = (value >> 16) & 0xff; p [2] = (value >> 8) & 0xff; p [3] = value & 0xff; diff --git a/src/mono/mono/mini/cfgdump.c b/src/mono/mono/mini/cfgdump.c index bf97eeeac6f5ce..64e0377f45caa8 100644 --- a/src/mono/mono/mini/cfgdump.c +++ b/src/mono/mono/mini/cfgdump.c @@ -56,7 +56,7 @@ create_socket (const char *hostname, const int port) } serv_addr.sin_family = AF_INET; - serv_addr.sin_port = htons (port); + serv_addr.sin_port = htons (GINT_TO_UINT16 (port)); serv_addr.sin_addr.s_addr = inet_addr (hostname); if (connect (sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { @@ -175,7 +175,7 @@ add_pool_entry (MonoCompile *cfg, ConstantPoolEntry *entry) write_short (cfg, NUM_SUCCESSOR); for (int i = 0; i < NUM_SUCCESSOR; i++) { char *str = g_strdup ("successor1"); - str[9] = '0' + i; + str[9] = '0' + GINT_TO_CHAR (i); write_byte (cfg, 0); write_pool (cfg, create_cp_entry (cfg, (void *) str, PT_STRING)); } diff --git a/src/mono/mono/mini/debug-mini.c b/src/mono/mono/mini/debug-mini.c index bc289a0d99f046..ab20bc258ac1e5 100644 --- a/src/mono/mono/mini/debug-mini.c +++ b/src/mono/mono/mini/debug-mini.c @@ -370,7 +370,7 @@ encode_value (gint32 value, guint8 *buf, guint8 **endbuf) p [1] = value & 0xff; p += 2; } else if ((value >= 0) && (value <= 0x1fffffff)) { - p [0] = (value >> 24) | 0xc0; + p [0] = GINT32_TO_UINT8 ((value >> 24) | 0xc0); p [1] = (value >> 16) & 0xff; p [2] = (value >> 8) & 0xff; p [3] = value & 0xff; diff --git a/src/mono/mono/mini/dwarfwriter.c b/src/mono/mono/mini/dwarfwriter.c index fa7671544853c3..8ab1dfcb3eb72c 100644 --- a/src/mono/mono/mini/dwarfwriter.c +++ b/src/mono/mono/mini/dwarfwriter.c @@ -1290,7 +1290,7 @@ emit_loclist (MonoDwarfWriter *w, MonoInst *ins, emit_pointer_value (w, loclist_begin_addr); emit_pointer_value (w, loclist_end_addr); - emit_byte (w, expr_len % 256); + emit_byte (w, GUINT32_TO_UINT8 (expr_len % 256)); emit_byte (w, GUINT32_TO_UINT8 (expr_len / 256)); emit_bytes (w, expr, expr_len); diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index 148700b4d086ae..2bd7fa8f238e67 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -2814,7 +2814,7 @@ interp_inline_newobj (TransformData *td, MonoMethod *target_method, MonoMethodSi newobj_fast = interp_add_ins (td, MINT_NEWOBJ_VT_INLINED); interp_ins_set_dreg (newobj_fast, this_reg); interp_ins_set_sreg (newobj_fast, dreg); - newobj_fast->data [0] = ALIGN_TO (vtsize, MINT_STACK_SLOT_SIZE); + newobj_fast->data [0] = GUINTPTR_TO_UINT16 (ALIGN_TO (vtsize, MINT_STACK_SLOT_SIZE)); } else { MonoVTable *vtable = mono_class_vtable_checked (klass, error); goto_if_nok (error, fail); @@ -5616,7 +5616,7 @@ generate_code (TransformData *td, MonoMethod *method, MonoMethodHeader *header, if (is_vt) { newobj_fast = interp_add_ins (td, MINT_NEWOBJ_VT); interp_ins_set_dreg (newobj_fast, dreg); - newobj_fast->data [1] = ALIGN_TO (vtsize, MINT_STACK_SLOT_SIZE); + newobj_fast->data [1] = GUINTPTR_TO_UINT16 (ALIGN_TO (vtsize, MINT_STACK_SLOT_SIZE)); } else { MonoVTable *vtable = mono_class_vtable_checked (klass, error); goto_if_nok (error, exit); diff --git a/src/mono/mono/mini/mini-amd64.c b/src/mono/mono/mini/mini-amd64.c index d6d33a996676d2..4a9acc0298eeff 100644 --- a/src/mono/mono/mini/mini-amd64.c +++ b/src/mono/mono/mini/mini-amd64.c @@ -233,7 +233,7 @@ add_general (guint32 *gr, guint32 *stack_size, ArgInfo *ainfo) (*stack_size) += sizeof (target_mgreg_t); } else { ainfo->storage = ArgInIReg; - ainfo->reg = param_regs [*gr]; + ainfo->reg = GINT32_TO_UINT8 (param_regs [*gr]); (*gr) ++; } } @@ -676,7 +676,7 @@ add_valuetype (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type, if (pass_on_stack) { /* Allways pass in memory */ - ainfo->offset = *stack_size; + ainfo->offset = GINT32_TO_INT16 (*stack_size); *stack_size += ALIGN_TO (size, 8); ainfo->storage = is_return ? ArgValuetypeAddrInIReg : ArgOnStack; if (!is_return) @@ -718,7 +718,7 @@ add_valuetype (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type, } if (struct_size > 16) { - ainfo->offset = *stack_size; + ainfo->offset = GINT32_TO_INT16 (*stack_size); *stack_size += ALIGN_TO (struct_size, 8); ainfo->storage = is_return ? ArgValuetypeAddrInIReg : ArgOnStack; if (!is_return) @@ -793,9 +793,9 @@ add_valuetype (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type, else { ainfo->pair_storage [quad] = ArgInIReg; if (is_return) - ainfo->pair_regs [quad] = return_regs [*gr]; + ainfo->pair_regs [quad] = GINT32_TO_UINT8 (return_regs [*gr]); else - ainfo->pair_regs [quad] = param_regs [*gr]; + ainfo->pair_regs [quad] = GINT32_TO_UINT8 (param_regs [*gr]); (*gr) ++; } break; @@ -805,8 +805,9 @@ add_valuetype (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type, else { if (quadsize[quad] <= 4) ainfo->pair_storage [quad] = ArgInFloatSSEReg; - else ainfo->pair_storage [quad] = ArgInDoubleSSEReg; - ainfo->pair_regs [quad] = *fr; + else + ainfo->pair_storage [quad] = ArgInDoubleSSEReg; + ainfo->pair_regs [quad] = GINT32_TO_UINT8 (*fr); (*fr) ++; } break; @@ -825,7 +826,7 @@ add_valuetype (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type, *gr = orig_gr; *fr = orig_fr; - ainfo->offset = *stack_size; + ainfo->offset = GINT32_TO_UINT16 (*stack_size); if (sig->pinvoke) arg_size = ALIGN_TO (struct_size, 8); else diff --git a/src/mono/mono/mini/mini-arm.c b/src/mono/mono/mini/mini-arm.c index fa1200e51ddbb4..31f580c500d033 100644 --- a/src/mono/mono/mini/mini-arm.c +++ b/src/mono/mono/mini/mini-arm.c @@ -598,14 +598,14 @@ mono_arch_get_argument_info (MonoMethodSignature *csig, int param_count, MonoJit offset += 4; } - arg_info [0].offset = offset; + arg_info [0].offset = GINT32_TO_UINT16 (offset); if (csig->hasthis) { frame_size += sizeof (target_mgreg_t); offset += 4; } - arg_info [0].size = frame_size; + arg_info [0].size = GINT32_TO_UINT16 (frame_size); for (k = 0; k < param_count; k++) { size = mini_type_stack_size_full (csig->params [k], &align, csig->pinvoke && !csig->marshalling_disabled); @@ -614,18 +614,18 @@ mono_arch_get_argument_info (MonoMethodSignature *csig, int param_count, MonoJit align = 1; frame_size += pad = (align - (frame_size & (align - 1))) & (align - 1); - arg_info [k].pad = pad; + arg_info [k].pad = GUINT32_TO_UINT8 (pad); frame_size += size; arg_info [k + 1].pad = 0; - arg_info [k + 1].size = size; + arg_info [k + 1].size = GINT32_TO_UINT16 (size); offset += pad; - arg_info [k + 1].offset = offset; + arg_info [k + 1].offset = GINT32_TO_UINT16 (offset); offset += size; } align = MONO_ARCH_FRAME_ALIGNMENT; frame_size += pad = (align - (frame_size & (align - 1))) & (align - 1); - arg_info [k].pad = pad; + arg_info [k].pad = GUINT32_TO_UINT8 (pad); return frame_size; } @@ -1083,7 +1083,7 @@ add_general (guint *gr, guint *stack_size, ArgInfo *ainfo, gboolean simple) *stack_size += 4; } else { ainfo->storage = RegTypeGeneral; - ainfo->reg = *gr; + ainfo->reg = GUINT32_TO_UINT8 (*gr); } } else { gboolean split; @@ -1118,7 +1118,7 @@ add_general (guint *gr, guint *stack_size, ArgInfo *ainfo, gboolean simple) (*gr) ++; } ainfo->storage = RegTypeIRegPair; - ainfo->reg = *gr; + ainfo->reg = GUINT32_TO_UINT8 (*gr); } (*gr) ++; } @@ -1170,7 +1170,7 @@ add_float (guint *fpr, guint *stack_size, ArgInfo *ainfo, gboolean is_double, gi * At this point, we have an even register * so we assign that and move along. */ - ainfo->reg = *fpr; + ainfo->reg = GUINT32_TO_UINT8 (*fpr); *fpr += 2; } else if (*float_spare >= 0) { /* @@ -1180,7 +1180,7 @@ add_float (guint *fpr, guint *stack_size, ArgInfo *ainfo, gboolean is_double, gi * use it. */ - ainfo->reg = *float_spare; + ainfo->reg = GINT32_TO_UINT8 (*float_spare); *float_spare = -1; } else { /* @@ -1189,7 +1189,7 @@ add_float (guint *fpr, guint *stack_size, ArgInfo *ainfo, gboolean is_double, gi * use the next available register. */ - ainfo->reg = *fpr; + ainfo->reg = GUINT32_TO_UINT8 (*fpr); (*fpr)++; } } else { @@ -1387,7 +1387,7 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig) pstart = 1; } n ++; - cinfo->ret.reg = gr; + cinfo->ret.reg = GUINT32_TO_UINT8 (gr); gr ++; cinfo->vret_arg_index = 1; } else { @@ -1397,7 +1397,7 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig) n ++; } if (vtype_retaddr) { - cinfo->ret.reg = gr; + cinfo->ret.reg = GUINT32_TO_UINT8 (gr); gr ++; } } @@ -1480,7 +1480,7 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig) if (IS_HARD_FLOAT && sig->pinvoke && is_hfa (t, &nfields, &esize)) { if (fpr + nfields < ARM_VFP_F16) { ainfo->storage = RegTypeHFA; - ainfo->reg = fpr; + ainfo->reg = GUINT32_TO_UINT8 (fpr); ainfo->nregs = nfields; ainfo->esize = esize; if (esize == 4) @@ -1540,14 +1540,14 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig) } if (gr > ARMREG_R3) { ainfo->size = 0; - ainfo->vtsize = nwords; + ainfo->vtsize = GINT32_TO_UINT16 (nwords); } else { int rest = ARMREG_R3 - gr + 1; int n_in_regs = rest >= nwords? nwords: rest; - ainfo->size = n_in_regs; - ainfo->vtsize = nwords - n_in_regs; - ainfo->reg = gr; + ainfo->size = GINT32_TO_UINT8 (n_in_regs); + ainfo->vtsize = GINT32_TO_UINT16 (nwords - n_in_regs); + ainfo->reg = GUINT32_TO_UINT8 (gr); gr += n_in_regs; nwords -= n_in_regs; } @@ -3100,16 +3100,16 @@ mono_arch_finish_dyn_call (MonoDynCallInfo *info, guint8 *buf) *(gpointer*)ret = (gpointer)(gsize)res; break; case MONO_TYPE_I1: - *(gint8*)ret = res; + *(gint8*)ret = GINT32_TO_INT8 (res); break; case MONO_TYPE_U1: - *(guint8*)ret = res; + *(guint8*)ret = GINT32_TO_UINT8 (res); break; case MONO_TYPE_I2: - *(gint16*)ret = res; + *(gint16*)ret = GINT32_TO_INT16 (res); break; case MONO_TYPE_U2: - *(guint16*)ret = res; + *(guint16*)ret = GINT32_TO_UINT16 (res); break; case MONO_TYPE_I4: *(gint32*)ret = res; @@ -3449,7 +3449,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) ins->sreg2 = temp->dreg; if (opcode2 == -1) g_error ("mono_op_imm_to_op failed for %s\n", mono_inst_name (ins->opcode)); - ins->opcode = opcode2; + ins->opcode = GUINT32_TO_OPCODE (opcode2); } if (ins->opcode == OP_SBB || ins->opcode == OP_ISBB || ins->opcode == OP_SUBCC) goto loop_start; @@ -3507,7 +3507,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) ins->sreg2 = temp->dreg; if (opcode2 == -1) g_error ("mono_op_imm_to_op failed for %s\n", mono_inst_name (ins->opcode)); - ins->opcode = opcode2; + ins->opcode = GINT32_TO_UINT16 (opcode2); break; } case OP_LOCALLOC_IMM: @@ -3532,7 +3532,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) temp->inst_c0 = ins->inst_offset; temp->dreg = mono_alloc_ireg (cfg); ins->sreg2 = temp->dreg; - ins->opcode = map_to_reg_reg_op (ins->opcode); + ins->opcode = GINT32_TO_UINT16 (map_to_reg_reg_op (ins->opcode)); break; case OP_LOADI2_MEMBASE: case OP_LOADU2_MEMBASE: @@ -3543,7 +3543,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) temp->inst_c0 = ins->inst_offset; temp->dreg = mono_alloc_ireg (cfg); ins->sreg2 = temp->dreg; - ins->opcode = map_to_reg_reg_op (ins->opcode); + ins->opcode = GINT32_TO_UINT16 (map_to_reg_reg_op (ins->opcode)); break; case OP_LOADR4_MEMBASE: case OP_LOADR8_MEMBASE: @@ -3582,7 +3582,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) temp->inst_c0 = ins->inst_offset; temp->dreg = mono_alloc_ireg (cfg); ins->sreg2 = temp->dreg; - ins->opcode = map_to_reg_reg_op (ins->opcode); + ins->opcode = GINT32_TO_UINT16 (map_to_reg_reg_op (ins->opcode)); break; case OP_STOREI2_MEMBASE_REG: if (arm_is_imm8 (ins->inst_offset)) @@ -3591,7 +3591,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) temp->inst_c0 = ins->inst_offset; temp->dreg = mono_alloc_ireg (cfg); ins->sreg2 = temp->dreg; - ins->opcode = map_to_reg_reg_op (ins->opcode); + ins->opcode = GINT32_TO_UINT16 (map_to_reg_reg_op (ins->opcode)); break; case OP_STORER4_MEMBASE_REG: case OP_STORER8_MEMBASE_REG: @@ -3629,7 +3629,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) temp->inst_c0 = ins->inst_imm; temp->dreg = mono_alloc_ireg (cfg); ins->sreg1 = temp->dreg; - ins->opcode = map_to_reg_reg_op (ins->opcode); + ins->opcode = GINT32_TO_UINT16 (map_to_reg_reg_op (ins->opcode)); last_ins = temp; goto loop_start; /* make it handle the possibly big ins->inst_offset */ case OP_FCOMPARE: diff --git a/src/mono/mono/mini/mini-arm64.c b/src/mono/mono/mini/mini-arm64.c index 625108729015b9..22372eb056e5ab 100644 --- a/src/mono/mono/mini/mini-arm64.c +++ b/src/mono/mono/mini/mini-arm64.c @@ -1226,7 +1226,7 @@ add_valuetype (CallInfo *cinfo, ArgInfo *ainfo, MonoType *t) ainfo->size = size; ainfo->esize = esize; for (i = 0; i < nfields; ++i) - ainfo->foffsets [i] = field_offsets [i]; + ainfo->foffsets [i] = GINT_TO_UINT8 (field_offsets [i]); cinfo->fr += ainfo->nregs; } else { ainfo->nfregs_to_skip = FP_PARAM_REGS > cinfo->fr ? FP_PARAM_REGS - cinfo->fr : 0; @@ -1984,16 +1984,16 @@ mono_arch_finish_dyn_call (MonoDynCallInfo *info, guint8 *buf) *(gpointer*)ret = (gpointer)res; break; case MONO_TYPE_I1: - *(gint8*)ret = res; + *(gint8*)ret = GHMREG_TO_UINT8 (res); break; case MONO_TYPE_U1: - *(guint8*)ret = res; + *(guint8*)ret = GHMREG_TO_UINT8 (res); break; case MONO_TYPE_I2: - *(gint16*)ret = res; + *(gint16*)ret = GHMREG_TO_INT16 (res); break; case MONO_TYPE_U2: - *(guint16*)ret = res; + *(guint16*)ret = GHMREG_TO_UINT16 (res); break; case MONO_TYPE_I4: *(gint32*)ret = res; @@ -2946,7 +2946,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) temp->inst_c0 = ins->inst_imm; temp->dreg = mono_alloc_ireg (cfg); ins->sreg1 = temp->dreg; - ins->opcode = mono_op_imm_to_op (ins->opcode); + ins->opcode = GINT_TO_OPCODE (mono_op_imm_to_op (ins->opcode)); } break; case OP_ICOMPARE_IMM: @@ -5056,7 +5056,7 @@ emit_store_regset_cfa (MonoCompile *cfg, guint8 *code, guint64 regs, int basereg for (j = 0; j < nregs; ++j) { if (cfa_regset & (1 << (i + j))) - mono_emit_unwind_op_offset (cfg, code, i + j, (- cfa_offset) + offset + ((pos + j) * 8)); + mono_emit_unwind_op_offset (cfg, code, (i + j), (- cfa_offset) + offset + ((pos + j) * 8)); } i += nregs - 1; diff --git a/src/mono/mono/mini/mini-llvm.c b/src/mono/mono/mini/mini-llvm.c index d2e5b30058014d..0178d21fcb3201 100644 --- a/src/mono/mono/mini/mini-llvm.c +++ b/src/mono/mono/mini/mini-llvm.c @@ -1989,13 +1989,13 @@ get_aotconst_name (MonoJumpInfoType type, gconstpointer data, int got_offset) name = g_strdup_printf ("%s", mono_ji_type_to_string (type)); len = strlen (name); for (size_t i = 0; i < len; ++i) - name [i] = tolower (name [i]); + name [i] = GINT_TO_CHAR (tolower (name [i])); break; default: name = g_strdup_printf ("%s_%d", mono_ji_type_to_string (type), got_offset); len = strlen (name); for (size_t i = 0; i < len; ++i) - name [i] = tolower (name [i]); + name [i] = GINT_TO_CHAR (tolower (name [i])); break; } @@ -12584,7 +12584,7 @@ add_intrinsic (LLVMModuleRef module, int id) for (int vw = 0; vw < INTRIN_vectorwidths; ++vw) { for (int ew = 0; ew < INTRIN_elementwidths; ++ew) { llvm_ovr_tag_t vec_bit = INTRIN_vector128 >> ((INTRIN_vectorwidths - 1) - vw); - llvm_ovr_tag_t elem_bit = INTRIN_int8 << ew; + llvm_ovr_tag_t elem_bit = GINT_TO_UINT16 (INTRIN_int8 << ew); llvm_ovr_tag_t test = vec_bit | elem_bit; if ((spec & test) == test) { uint8_t kind = intrin_kind [id]; diff --git a/src/mono/mono/mini/mini-unwind.h b/src/mono/mono/mini/mini-unwind.h index 3db2f45e9cb2b9..98e0db4e7fc4f8 100644 --- a/src/mono/mono/mini/mini-unwind.h +++ b/src/mono/mono/mini/mini-unwind.h @@ -98,13 +98,13 @@ typedef struct { /* Set cfa to reg+offset */ #define mono_emit_unwind_op_def_cfa(cfg,ip,reg,offset) do { mono_emit_unwind_op (cfg, (ip) - (cfg)->native_code, DW_CFA_def_cfa, (reg), (offset)); (cfg)->cur_cfa_reg = (reg); (cfg)->cur_cfa_offset = (offset); } while (0) /* Set cfa to reg+existing offset */ -#define mono_emit_unwind_op_def_cfa_reg(cfg,ip,reg) do { mono_emit_unwind_op (cfg, (ip) - (cfg)->native_code, DW_CFA_def_cfa_register, (reg), (0)); (cfg)->cur_cfa_reg = (reg); } while (0) +#define mono_emit_unwind_op_def_cfa_reg(cfg,ip,reg) do { mono_emit_unwind_op (cfg, (ip) - (cfg)->native_code, DW_CFA_def_cfa_register, (uint16_t)(reg), (0)); (cfg)->cur_cfa_reg = (reg); } while (0) /* Set cfa to existing reg+offset */ #define mono_emit_unwind_op_def_cfa_offset(cfg,ip,offset) do { mono_emit_unwind_op (cfg, (ip) - (cfg)->native_code, DW_CFA_def_cfa_offset, (0), (offset)); (cfg)->cur_cfa_offset = (offset); } while (0) /* Reg is the same as it was on enter to the function */ -#define mono_emit_unwind_op_same_value(cfg,ip,reg) mono_emit_unwind_op (cfg, (ip) - (cfg)->native_code, DW_CFA_same_value, (reg), 0) +#define mono_emit_unwind_op_same_value(cfg,ip,reg) mono_emit_unwind_op (cfg, (ip) - (cfg)->native_code, DW_CFA_same_value, (uint16_t)(reg), 0) /* Reg is saved at cfa+offset */ -#define mono_emit_unwind_op_offset(cfg,ip,reg,offset) mono_emit_unwind_op (cfg, (ip) - (cfg)->native_code, DW_CFA_offset, (reg), (offset)) +#define mono_emit_unwind_op_offset(cfg,ip,reg,offset) mono_emit_unwind_op (cfg, (ip) - (cfg)->native_code, DW_CFA_offset, (uint16_t)(reg), (offset)) /* Save the unwind state into an implicit stack */ #define mono_emit_unwind_op_remember_state(cfg,ip) mono_emit_unwind_op (cfg, (ip) - (cfg)->native_code, DW_CFA_remember_state, 0, 0) /* Restore the unwind state from the state stack */ @@ -125,15 +125,15 @@ typedef struct { #endif /* Similar macros usable when a cfg is not available, like for trampolines */ -#define mono_add_unwind_op_def_cfa(op_list,code,buf,reg,offset) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_def_cfa, (reg), (offset))); } while (0) -#define mono_add_unwind_op_def_cfa_reg(op_list,code,buf,reg) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_def_cfa_register, (reg), (0))); } while (0) +#define mono_add_unwind_op_def_cfa(op_list,code,buf,reg,offset) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_def_cfa, (uint16_t)(reg), (offset))); } while (0) +#define mono_add_unwind_op_def_cfa_reg(op_list,code,buf,reg) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_def_cfa_register, (uint16_t)(reg), (0))); } while (0) #define mono_add_unwind_op_def_cfa_offset(op_list,code,buf,offset) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_def_cfa_offset, 0, (offset))); } while (0) -#define mono_add_unwind_op_same_value(op_list,code,buf,reg) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_same_value, (reg), 0)); } while (0) -#define mono_add_unwind_op_offset(op_list,code,buf,reg,offset) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_offset, (reg), (offset))); } while (0) +#define mono_add_unwind_op_same_value(op_list,code,buf,reg) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_same_value, (uint16_t)(reg), 0)); } while (0) +#define mono_add_unwind_op_offset(op_list,code,buf,reg,offset) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_offset, (uint16_t)(reg), (offset))); } while (0) #if defined(TARGET_WIN32) && defined(TARGET_AMD64) #define mono_add_unwind_op_sp_alloc(op_list,code,buf,size) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_mono_sp_alloc_info_win64, 0, (size))); } while (0) -#define mono_add_unwind_op_fp_alloc(op_list,code,buf,reg,size) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_mono_fp_alloc_info_win64, (reg), (size))); } while (0) +#define mono_add_unwind_op_fp_alloc(op_list,code,buf,reg,size) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_mono_fp_alloc_info_win64, (uint16_t)(reg), (size))); } while (0) #else #define mono_add_unwind_op_sp_alloc(op_list,code,buf,size) #define mono_add_unwind_op_fp_alloc(op_list,code,buf,reg,size) diff --git a/src/mono/mono/mini/mini-x86.c b/src/mono/mono/mini/mini-x86.c index e3a9703888540c..567c759b22279d 100644 --- a/src/mono/mono/mini/mini-x86.c +++ b/src/mono/mono/mini/mini-x86.c @@ -281,10 +281,10 @@ add_valuetype (MonoMethodSignature *sig, ArgInfo *ainfo, MonoType *type, if ((info->native_size == 1) || (info->native_size == 2) || (info->native_size == 4) || (info->native_size == 8)) { ainfo->storage = ArgValuetypeInReg; ainfo->pair_storage [0] = ArgInIReg; - ainfo->pair_regs [0] = return_regs [0]; + ainfo->pair_regs [0] = GINT32_TO_UINT8 (return_regs [0]); if (info->native_size > 4) { ainfo->pair_storage [1] = ArgInIReg; - ainfo->pair_regs [1] = return_regs [1]; + ainfo->pair_regs [1] = GINT32_TO_UINT8 (return_regs [1]); } return; } diff --git a/src/mono/mono/profiler/aot.c b/src/mono/mono/profiler/aot.c index 278c3c05354c81..45bed109354cc3 100644 --- a/src/mono/mono/profiler/aot.c +++ b/src/mono/mono/profiler/aot.c @@ -454,7 +454,7 @@ emit_string (MonoProfiler *prof, const char *str) static void emit_record (MonoProfiler *prof, AotProfRecordType type, int id) { - emit_byte (prof, type); + emit_byte (prof, (guint8)type); emit_int32 (prof, id); } diff --git a/src/mono/mono/profiler/log.c b/src/mono/mono/profiler/log.c index a3e5de6ba37958..110253833a97bb 100644 --- a/src/mono/mono/profiler/log.c +++ b/src/mono/mono/profiler/log.c @@ -793,7 +793,7 @@ encode_sleb128 (intptr_t value, uint8_t *buf, uint8_t **endbuf) static void emit_byte (LogBuffer *logbuffer, int value) { - logbuffer->cursor [0] = value; + logbuffer->cursor [0] = GINT_TO_UINT8 (value); logbuffer->cursor++; g_assert (logbuffer->cursor <= logbuffer->buf_end && "Why are we writing past the buffer end?"); @@ -956,7 +956,7 @@ write_int16 (char *buf, int32_t value) { int i; for (i = 0; i < 2; ++i) { - buf [i] = value; + buf [i] = GINT32_TO_UINT8 (value); value >>= 8; } return buf + 2; @@ -967,7 +967,7 @@ write_int32 (char *buf, int32_t value) { int i; for (i = 0; i < 4; ++i) { - buf [i] = value; + buf [i] = GINT_TO_UINT8 (value); value >>= 8; } return buf + 4; @@ -978,7 +978,7 @@ write_int64 (char *buf, int64_t value) { int i; for (i = 0; i < 8; ++i) { - buf [i] = value; + buf [i] = GINT_TO_UINT8 (value); value >>= 8; } return buf + 8; @@ -3271,7 +3271,7 @@ proflog_icall_SetSampleMode (MonoProfilerSampleMode mode, gint32 frequency) mono_coop_mutex_unlock (&log_profiler.api_mutex); - return result; + return !!result; } ICALL_EXPORT MonoBoolean diff --git a/src/mono/mono/utils/mono-rand.c b/src/mono/mono/utils/mono-rand.c index 88b3fed1b3a4ef..cb78275d75677d 100644 --- a/src/mono/mono/utils/mono-rand.c +++ b/src/mono/mono/utils/mono-rand.c @@ -157,7 +157,7 @@ get_entropy_from_egd (const char *path, guchar *buffer, gssize buffer_size, Mono /* block until daemon can return enough entropy */ request [0] = 2; - request [1] = buffer_size < 255 ? buffer_size : 255; + request [1] = buffer_size < 255 ? (guchar)buffer_size : 255; while (count < 2) { int sent = write (socket_fd, request + count, 2 - count); err = errno; diff --git a/src/native/eventpipe/ds-ipc-pal-socket.c b/src/native/eventpipe/ds-ipc-pal-socket.c index 20e3f11c52383e..df42c024e81ad9 100644 --- a/src/native/eventpipe/ds-ipc-pal-socket.c +++ b/src/native/eventpipe/ds-ipc-pal-socket.c @@ -848,7 +848,7 @@ ipc_alloc_tcp_address ( const ep_char8_t *host_address = address; const ep_char8_t *host_port = strrchr (address, ':'); - + if (host_port && host_port != host_address) { size_t host_address_len = host_port - address; address [host_address_len] = 0; @@ -884,7 +884,7 @@ ipc_alloc_tcp_address ( if (!ipc->server_address && info->ai_family == AF_INET) { server_address = ep_rt_object_alloc (struct sockaddr_in); if (server_address) { - server_address->sin_family = info->ai_family; + server_address->sin_family = (uint8_t) info->ai_family; server_address->sin_port = htons (port); server_address->sin_addr = ((struct sockaddr_in*)info->ai_addr)->sin_addr; ipc->server_address = (ds_ipc_socket_address_t *)server_address; @@ -898,7 +898,7 @@ ipc_alloc_tcp_address ( if (!ipc->server_address && info->ai_family == AF_INET6) { server_address6 = ep_rt_object_alloc (struct sockaddr_in6); if (server_address6) { - server_address6->sin6_family = info->ai_family; + server_address6->sin6_family = (uint8_t) info->ai_family; server_address6->sin6_port = htons (port); server_address6->sin6_addr = ((struct sockaddr_in6*)info->ai_addr)->sin6_addr; ipc->server_address = (ds_ipc_socket_address_t *)server_address6; diff --git a/src/native/external/libunwind.cmake b/src/native/external/libunwind.cmake index 0d767ccccdbabe..c304fd1523b721 100644 --- a/src/native/external/libunwind.cmake +++ b/src/native/external/libunwind.cmake @@ -435,4 +435,8 @@ else(CLR_CMAKE_HOST_UNIX) ) endif(CLR_CMAKE_HOST_UNIX) +if(CMAKE_C_COMPILER_ID MATCHES "Clang") + add_compile_options($<$:-Wno-implicit-int-conversion>) +endif() + addprefix(LIBUNWIND_SOURCES "${CMAKE_CURRENT_LIST_DIR}/libunwind/src" "${LIBUNWIND_SOURCES_BASE}") diff --git a/src/native/external/zlib-intel.cmake b/src/native/external/zlib-intel.cmake index c8352de35f2fc7..a9d0be1fa4b059 100644 --- a/src/native/external/zlib-intel.cmake +++ b/src/native/external/zlib-intel.cmake @@ -1,6 +1,8 @@ if(MSVC) add_compile_options($<$:/wd4244>) # conversion from 'type1' to 'type2', possible loss of data -endif(MSVC) +else(CMAKE_C_COMPILER_ID MATCHES "Clang") + add_compile_options($<$:-Wno-implicit-int-conversion>) +endif() set(ZLIB_SOURCES_BASE adler32.c diff --git a/src/native/external/zlib.cmake b/src/native/external/zlib.cmake index ef8a1e1a635b22..80b5f7b1a54387 100644 --- a/src/native/external/zlib.cmake +++ b/src/native/external/zlib.cmake @@ -1,6 +1,8 @@ if(MSVC) add_compile_options($<$:/wd4244>) # conversion from 'type1' to 'type2', possible loss of data -endif(MSVC) +else(CMAKE_C_COMPILER_ID MATCHES "Clang") + add_compile_options($<$:-Wno-implicit-int-conversion>) +endif() set(ZLIB_SOURCES_BASE adler32.c From 8bb880d97e7450c1d1fa94b83cf045b65e631918 Mon Sep 17 00:00:00 2001 From: Brennan Date: Tue, 14 Jun 2022 08:58:03 -0700 Subject: [PATCH 108/337] Add SlidingWindow and FixedWindow to RateLimitPartition (#68782) --- .../ref/System.Threading.RateLimiting.cs | 68 ++++++++++--------- .../RateLimiting/RateLimitPartition.cs | 57 ++++++++++++++++ .../tests/RateLimiterPartitionTests.cs | 34 +++++++++- 3 files changed, 124 insertions(+), 35 deletions(-) diff --git a/src/libraries/System.Threading.RateLimiting/ref/System.Threading.RateLimiting.cs b/src/libraries/System.Threading.RateLimiting/ref/System.Threading.RateLimiting.cs index 9b3419ab6a2265..7c4f99e6167b13 100644 --- a/src/libraries/System.Threading.RateLimiting/ref/System.Threading.RateLimiting.cs +++ b/src/libraries/System.Threading.RateLimiting/ref/System.Threading.RateLimiting.cs @@ -23,6 +23,28 @@ public ConcurrencyLimiterOptions(int permitLimit, System.Threading.RateLimiting. public int QueueLimit { get { throw null; } } public System.Threading.RateLimiting.QueueProcessingOrder QueueProcessingOrder { get { throw null; } } } + public sealed partial class FixedWindowRateLimiter : System.Threading.RateLimiting.ReplenishingRateLimiter + { + public FixedWindowRateLimiter(System.Threading.RateLimiting.FixedWindowRateLimiterOptions options) { } + public override System.TimeSpan? IdleDuration { get { throw null; } } + public override bool IsAutoReplenishing { get { throw null; } } + public override System.TimeSpan ReplenishmentPeriod { get { throw null; } } + protected override System.Threading.RateLimiting.RateLimitLease AcquireCore(int requestCount) { throw null; } + protected override void Dispose(bool disposing) { } + protected override System.Threading.Tasks.ValueTask DisposeAsyncCore() { throw null; } + public override int GetAvailablePermits() { throw null; } + public override bool TryReplenish() { throw null; } + protected override System.Threading.Tasks.ValueTask WaitAsyncCore(int requestCount, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + } + public sealed partial class FixedWindowRateLimiterOptions + { + public FixedWindowRateLimiterOptions(int permitLimit, System.Threading.RateLimiting.QueueProcessingOrder queueProcessingOrder, int queueLimit, System.TimeSpan window, bool autoReplenishment = true) { } + public bool AutoReplenishment { get { throw null; } } + public int PermitLimit { get { throw null; } } + public int QueueLimit { get { throw null; } } + public System.Threading.RateLimiting.QueueProcessingOrder QueueProcessingOrder { get { throw null; } } + public System.TimeSpan Window { get { throw null; } } + } public static partial class MetadataName { public static System.Threading.RateLimiting.MetadataName ReasonPhrase { get { throw null; } } @@ -90,7 +112,9 @@ protected virtual void Dispose(bool disposing) { } public static partial class RateLimitPartition { public static System.Threading.RateLimiting.RateLimitPartition CreateConcurrencyLimiter(TKey partitionKey, System.Func factory) { throw null; } + public static System.Threading.RateLimiting.RateLimitPartition CreateFixedWindowLimiter(TKey partitionKey, System.Func factory) { throw null; } public static System.Threading.RateLimiting.RateLimitPartition CreateNoLimiter(TKey partitionKey) { throw null; } + public static System.Threading.RateLimiting.RateLimitPartition CreateSlidingWindowLimiter(TKey partitionKey, System.Func factory) { throw null; } public static System.Threading.RateLimiting.RateLimitPartition CreateTokenBucketLimiter(TKey partitionKey, System.Func factory) { throw null; } public static System.Threading.RateLimiting.RateLimitPartition Create(TKey partitionKey, System.Func factory) { throw null; } } @@ -109,29 +133,6 @@ protected ReplenishingRateLimiter() { } public abstract System.TimeSpan ReplenishmentPeriod { get; } public abstract bool TryReplenish(); } - public sealed partial class TokenBucketRateLimiter : System.Threading.RateLimiting.ReplenishingRateLimiter - { - public TokenBucketRateLimiter(System.Threading.RateLimiting.TokenBucketRateLimiterOptions options) { } - public override System.TimeSpan? IdleDuration { get { throw null; } } - public override bool IsAutoReplenishing { get { throw null; } } - public override System.TimeSpan ReplenishmentPeriod { get { throw null; } } - protected override System.Threading.RateLimiting.RateLimitLease AcquireCore(int tokenCount) { throw null; } - protected override void Dispose(bool disposing) { } - protected override System.Threading.Tasks.ValueTask DisposeAsyncCore() { throw null; } - public override int GetAvailablePermits() { throw null; } - public override bool TryReplenish() { throw null; } - protected override System.Threading.Tasks.ValueTask WaitAsyncCore(int tokenCount, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } - } - public sealed partial class TokenBucketRateLimiterOptions - { - public TokenBucketRateLimiterOptions(int tokenLimit, System.Threading.RateLimiting.QueueProcessingOrder queueProcessingOrder, int queueLimit, System.TimeSpan replenishmentPeriod, int tokensPerPeriod, bool autoReplenishment = true) { } - public bool AutoReplenishment { get { throw null; } } - public int QueueLimit { get { throw null; } } - public System.Threading.RateLimiting.QueueProcessingOrder QueueProcessingOrder { get { throw null; } } - public System.TimeSpan ReplenishmentPeriod { get { throw null; } } - public int TokenLimit { get { throw null; } } - public int TokensPerPeriod { get { throw null; } } - } public sealed partial class SlidingWindowRateLimiter : System.Threading.RateLimiting.ReplenishingRateLimiter { public SlidingWindowRateLimiter(System.Threading.RateLimiting.SlidingWindowRateLimiterOptions options) { } @@ -149,32 +150,33 @@ public sealed partial class SlidingWindowRateLimiterOptions { public SlidingWindowRateLimiterOptions(int permitLimit, System.Threading.RateLimiting.QueueProcessingOrder queueProcessingOrder, int queueLimit, System.TimeSpan window, int segmentsPerWindow, bool autoReplenishment = true) { } public bool AutoReplenishment { get { throw null; } } + public int PermitLimit { get { throw null; } } public int QueueLimit { get { throw null; } } public System.Threading.RateLimiting.QueueProcessingOrder QueueProcessingOrder { get { throw null; } } - public System.TimeSpan Window { get { throw null; } } - public int PermitLimit { get { throw null; } } public int SegmentsPerWindow { get { throw null; } } + public System.TimeSpan Window { get { throw null; } } } - public sealed partial class FixedWindowRateLimiter : System.Threading.RateLimiting.ReplenishingRateLimiter + public sealed partial class TokenBucketRateLimiter : System.Threading.RateLimiting.ReplenishingRateLimiter { - public FixedWindowRateLimiter(System.Threading.RateLimiting.FixedWindowRateLimiterOptions options) { } + public TokenBucketRateLimiter(System.Threading.RateLimiting.TokenBucketRateLimiterOptions options) { } public override System.TimeSpan? IdleDuration { get { throw null; } } public override bool IsAutoReplenishing { get { throw null; } } public override System.TimeSpan ReplenishmentPeriod { get { throw null; } } - protected override System.Threading.RateLimiting.RateLimitLease AcquireCore(int requestCount) { throw null; } + protected override System.Threading.RateLimiting.RateLimitLease AcquireCore(int tokenCount) { throw null; } protected override void Dispose(bool disposing) { } protected override System.Threading.Tasks.ValueTask DisposeAsyncCore() { throw null; } public override int GetAvailablePermits() { throw null; } public override bool TryReplenish() { throw null; } - protected override System.Threading.Tasks.ValueTask WaitAsyncCore(int requestCount, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } + protected override System.Threading.Tasks.ValueTask WaitAsyncCore(int tokenCount, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } } - public sealed partial class FixedWindowRateLimiterOptions + public sealed partial class TokenBucketRateLimiterOptions { - public FixedWindowRateLimiterOptions(int permitLimit, System.Threading.RateLimiting.QueueProcessingOrder queueProcessingOrder, int queueLimit, System.TimeSpan window, bool autoReplenishment = true) { } + public TokenBucketRateLimiterOptions(int tokenLimit, System.Threading.RateLimiting.QueueProcessingOrder queueProcessingOrder, int queueLimit, System.TimeSpan replenishmentPeriod, int tokensPerPeriod, bool autoReplenishment = true) { } public bool AutoReplenishment { get { throw null; } } public int QueueLimit { get { throw null; } } public System.Threading.RateLimiting.QueueProcessingOrder QueueProcessingOrder { get { throw null; } } - public System.TimeSpan Window { get { throw null; } } - public int PermitLimit { get { throw null; } } + public System.TimeSpan ReplenishmentPeriod { get { throw null; } } + public int TokenLimit { get { throw null; } } + public int TokensPerPeriod { get { throw null; } } } } diff --git a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/RateLimitPartition.cs b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/RateLimitPartition.cs index 134794940cf585..1942262ba95706 100644 --- a/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/RateLimitPartition.cs +++ b/src/libraries/System.Threading.RateLimiting/src/System/Threading/RateLimiting/RateLimitPartition.cs @@ -12,6 +12,9 @@ public static class RateLimitPartition /// Defines a partition with the given rate limiter factory. ///
/// The type to distinguish partitions with. + /// + /// The should return a new instance of a rate limiter every time it is called. + /// /// The specific key for this partition. This will be used to check for an existing cached limiter before calling the . /// The function called when a rate limiter for the given is needed. This should be a new instance of a rate limiter every time it is called. /// @@ -74,5 +77,59 @@ public static RateLimitPartition CreateTokenBucketLimiter( return new TokenBucketRateLimiter(options); }); } + + /// + /// Defines a partition with a with the given . + /// + /// + /// Set to to save an allocation. This method will create a new options type and set to otherwise. + /// + /// The type to distinguish partitions with. + /// The specific key for this partition. + /// The function called when a rate limiter for the given is needed. This can return the same instance of across different calls. + /// + public static RateLimitPartition CreateSlidingWindowLimiter( + TKey partitionKey, + Func factory) + { + return Create(partitionKey, key => + { + SlidingWindowRateLimiterOptions options = factory(key); + // We don't want individual SlidingWindowRateLimiters to have timers. We will instead have our own internal Timer handling all of them + if (options.AutoReplenishment is true) + { + options = new SlidingWindowRateLimiterOptions(options.PermitLimit, options.QueueProcessingOrder, options.QueueLimit, + options.Window, options.SegmentsPerWindow, autoReplenishment: false); + } + return new SlidingWindowRateLimiter(options); + }); + } + + /// + /// Defines a partition with a with the given . + /// + /// + /// Set to to save an allocation. This method will create a new options type and set to otherwise. + /// + /// The type to distinguish partitions with. + /// The specific key for this partition. + /// The function called when a rate limiter for the given is needed. This can return the same instance of across different calls. + /// + public static RateLimitPartition CreateFixedWindowLimiter( + TKey partitionKey, + Func factory) + { + return Create(partitionKey, key => + { + FixedWindowRateLimiterOptions options = factory(key); + // We don't want individual FixedWindowRateLimiters to have timers. We will instead have our own internal Timer handling all of them + if (options.AutoReplenishment is true) + { + options = new FixedWindowRateLimiterOptions(options.PermitLimit, options.QueueProcessingOrder, options.QueueLimit, + options.Window, autoReplenishment: false); + } + return new FixedWindowRateLimiter(options); + }); + } } } diff --git a/src/libraries/System.Threading.RateLimiting/tests/RateLimiterPartitionTests.cs b/src/libraries/System.Threading.RateLimiting/tests/RateLimiterPartitionTests.cs index 7e2bfe17285702..175c4e96fdcda1 100644 --- a/src/libraries/System.Threading.RateLimiting/tests/RateLimiterPartitionTests.cs +++ b/src/libraries/System.Threading.RateLimiting/tests/RateLimiterPartitionTests.cs @@ -32,8 +32,8 @@ public void Create_TokenBucket() var limiter = factory(1); var tokenBucketLimiter = Assert.IsType(limiter); Assert.Equal(options.TokenLimit, tokenBucketLimiter.GetAvailablePermits()); - // TODO: Check other properties when ReplenshingRateLimiter is merged - // TODO: Check that autoReplenishment: true got changed to false + Assert.Equal(options.ReplenishmentPeriod, tokenBucketLimiter.ReplenishmentPeriod); + Assert.False(tokenBucketLimiter.IsAutoReplenishing); } [Fact] @@ -79,5 +79,35 @@ public void Create_AnyLimiter() var tokenBucketLimiter = Assert.IsType(limiter); Assert.Equal(1, tokenBucketLimiter.GetAvailablePermits()); } + + [Fact] + public void Create_FixedWindow() + { + var options = new FixedWindowRateLimiterOptions(1, QueueProcessingOrder.OldestFirst, 10, TimeSpan.FromMinutes(1), true); + var partition = RateLimitPartition.CreateFixedWindowLimiter(1, key => options); + + var factoryProperty = typeof(RateLimitPartition).GetField("Factory", Reflection.BindingFlags.NonPublic | Reflection.BindingFlags.Instance)!; + var factory = (Func)factoryProperty.GetValue(partition); + var limiter = factory(1); + var fixedWindowLimiter = Assert.IsType(limiter); + Assert.Equal(options.PermitLimit, fixedWindowLimiter.GetAvailablePermits()); + Assert.Equal(options.Window, fixedWindowLimiter.ReplenishmentPeriod); + Assert.False(fixedWindowLimiter.IsAutoReplenishing); + } + + [Fact] + public void Create_SlidingWindow() + { + var options = new SlidingWindowRateLimiterOptions(1, QueueProcessingOrder.OldestFirst, 10, TimeSpan.FromSeconds(33), 3, true); + var partition = RateLimitPartition.CreateSlidingWindowLimiter(1, key => options); + + var factoryProperty = typeof(RateLimitPartition).GetField("Factory", Reflection.BindingFlags.NonPublic | Reflection.BindingFlags.Instance)!; + var factory = (Func)factoryProperty.GetValue(partition); + var limiter = factory(1); + var slidingWindowLimiter = Assert.IsType(limiter); + Assert.Equal(options.PermitLimit, slidingWindowLimiter.GetAvailablePermits()); + Assert.Equal(TimeSpan.FromSeconds(11), slidingWindowLimiter.ReplenishmentPeriod); + Assert.False(slidingWindowLimiter.IsAutoReplenishing); + } } } From 20cb077d22658a1264fd4619ae8f96697a02453e Mon Sep 17 00:00:00 2001 From: Dennis Yemelyanov <10681271+dennis-yemelyanov@users.noreply.github.com> Date: Tue, 14 Jun 2022 09:52:37 -0700 Subject: [PATCH 109/337] align GC memory load calculation on Linux with Docker and Kubernetes (#64128) * align memory load calculation in GC with Docker and Kubernetes * pass inactive file field name as a parameter --- src/coreclr/gc/unix/cgroup.cpp | 99 +++++++++++++++-------------- src/coreclr/pal/src/misc/cgroup.cpp | 99 +++++++++++++++-------------- 2 files changed, 102 insertions(+), 96 deletions(-) diff --git a/src/coreclr/gc/unix/cgroup.cpp b/src/coreclr/gc/unix/cgroup.cpp index 34f7f4f47f62df..50069e469147e2 100644 --- a/src/coreclr/gc/unix/cgroup.cpp +++ b/src/coreclr/gc/unix/cgroup.cpp @@ -47,6 +47,10 @@ Module Name: #define CGROUP1_MEMORY_LIMIT_FILENAME "/memory.limit_in_bytes" #define CGROUP2_MEMORY_LIMIT_FILENAME "/memory.max" #define CGROUP_MEMORY_STAT_FILENAME "/memory.stat" +#define CGROUP1_MEMORY_USAGE_FILENAME "/memory.usage_in_bytes" +#define CGROUP2_MEMORY_USAGE_FILENAME "/memory.current" +#define CGROUP1_MEMORY_STAT_INACTIVE_FIELD "total_inactive_file " +#define CGROUP2_MEMORY_STAT_INACTIVE_FIELD "inactive_file " extern bool ReadMemoryValueFromFile(const char* filename, uint64_t* val); @@ -56,36 +60,11 @@ class CGroup static int s_cgroup_version; static char *s_memory_cgroup_path; - - static const char *s_mem_stat_key_names[]; - static size_t s_mem_stat_key_lengths[]; - static size_t s_mem_stat_n_keys; public: static void Initialize() { s_cgroup_version = FindCGroupVersion(); s_memory_cgroup_path = FindCGroupPath(s_cgroup_version == 1 ? &IsCGroup1MemorySubsystem : nullptr); - - if (s_cgroup_version == 1) - { - s_mem_stat_n_keys = 4; - s_mem_stat_key_names[0] = "total_inactive_anon "; - s_mem_stat_key_names[1] = "total_active_anon "; - s_mem_stat_key_names[2] = "total_dirty "; - s_mem_stat_key_names[3] = "total_unevictable "; - } - else - { - s_mem_stat_n_keys = 3; - s_mem_stat_key_names[0] = "anon "; - s_mem_stat_key_names[1] = "file_dirty "; - s_mem_stat_key_names[2] = "unevictable "; - } - - for (size_t i = 0; i < s_mem_stat_n_keys; i++) - { - s_mem_stat_key_lengths[i] = strlen(s_mem_stat_key_names[i]); - } } static void Cleanup() @@ -113,9 +92,9 @@ class CGroup if (s_cgroup_version == 0) return false; else if (s_cgroup_version == 1) - return GetCGroupMemoryUsage(val); + return GetCGroupMemoryUsage(val, CGROUP1_MEMORY_USAGE_FILENAME, CGROUP1_MEMORY_STAT_INACTIVE_FIELD); else if (s_cgroup_version == 2) - return GetCGroupMemoryUsage(val); + return GetCGroupMemoryUsage(val, CGROUP2_MEMORY_USAGE_FILENAME, CGROUP2_MEMORY_STAT_INACTIVE_FIELD); else { assert(!"Unknown cgroup version."); @@ -401,8 +380,38 @@ class CGroup return result; } - static bool GetCGroupMemoryUsage(size_t *val) + static bool GetCGroupMemoryUsage(size_t *val, const char *filename, const char *inactiveFileFieldName) { + // Use the same way to calculate memory load as popular container tools (Docker, Kubernetes, Containerd etc.) + // For cgroup v1: value of 'memory.usage_in_bytes' minus 'total_inactive_file' value of 'memory.stat' + // For cgroup v2: value of 'memory.current' minus 'inactive_file' value of 'memory.stat' + + char* mem_usage_filename = nullptr; + if (asprintf(&mem_usage_filename, "%s%s", s_memory_cgroup_path, filename) < 0) + return false; + + uint64_t temp = 0; + + size_t usage = 0; + + bool result = ReadMemoryValueFromFile(mem_usage_filename, &temp); + if (result) + { + if (temp > std::numeric_limits::max()) + { + usage = std::numeric_limits::max(); + } + else + { + usage = (size_t)temp; + } + } + + free(mem_usage_filename); + + if (!result) + return result; + if (s_memory_cgroup_path == nullptr) return false; @@ -417,44 +426,38 @@ class CGroup char *line = nullptr; size_t lineLen = 0; - size_t readValues = 0; + bool foundInactiveFileValue = false; char* endptr; - *val = 0; - while (getline(&line, &lineLen, stat_file) != -1 && readValues < s_mem_stat_n_keys) + size_t inactiveFileFieldNameLength = strlen(inactiveFileFieldName); + + while (getline(&line, &lineLen, stat_file) != -1) { - for (size_t i = 0; i < s_mem_stat_n_keys; i++) + if (strncmp(line, inactiveFileFieldName, inactiveFileFieldNameLength) == 0) { - if (strncmp(line, s_mem_stat_key_names[i], s_mem_stat_key_lengths[i]) == 0) + errno = 0; + const char* startptr = line + inactiveFileFieldNameLength; + size_t inactiveFileValue = strtoll(startptr, &endptr, 10); + if (endptr != startptr && errno == 0) { - errno = 0; - const char* startptr = line + s_mem_stat_key_lengths[i]; - *val += strtoll(startptr, &endptr, 10); - if (endptr != startptr && errno == 0) - readValues++; - - break; + foundInactiveFileValue = true; + *val = usage - inactiveFileValue; } + + break; } } fclose(stat_file); free(line); - if (readValues == s_mem_stat_n_keys) - return true; - - return false; + return foundInactiveFileValue; } }; int CGroup::s_cgroup_version = 0; char *CGroup::s_memory_cgroup_path = nullptr; -const char *CGroup::s_mem_stat_key_names[4] = {}; -size_t CGroup::s_mem_stat_key_lengths[4] = {}; -size_t CGroup::s_mem_stat_n_keys = 0; - void InitializeCGroup() { CGroup::Initialize(); diff --git a/src/coreclr/pal/src/misc/cgroup.cpp b/src/coreclr/pal/src/misc/cgroup.cpp index 955347ceda65d6..890ddf38363d61 100644 --- a/src/coreclr/pal/src/misc/cgroup.cpp +++ b/src/coreclr/pal/src/misc/cgroup.cpp @@ -38,6 +38,10 @@ SET_DEFAULT_DEBUG_CHANNEL(MISC); #define CGROUP1_MEMORY_LIMIT_FILENAME "/memory.limit_in_bytes" #define CGROUP2_MEMORY_LIMIT_FILENAME "/memory.max" #define CGROUP_MEMORY_STAT_FILENAME "/memory.stat" +#define CGROUP1_MEMORY_USAGE_FILENAME "/memory.usage_in_bytes" +#define CGROUP2_MEMORY_USAGE_FILENAME "/memory.current" +#define CGROUP1_MEMORY_STAT_INACTIVE_FIELD "total_inactive_file " +#define CGROUP2_MEMORY_STAT_INACTIVE_FIELD "inactive_file " #define CGROUP1_CFS_QUOTA_FILENAME "/cpu.cfs_quota_us" #define CGROUP1_CFS_PERIOD_FILENAME "/cpu.cfs_period_us" #define CGROUP2_CPU_MAX_FILENAME "/cpu.max" @@ -49,37 +53,12 @@ class CGroup static char *s_memory_cgroup_path; static char *s_cpu_cgroup_path; - - static const char *s_mem_stat_key_names[]; - static size_t s_mem_stat_key_lengths[]; - static size_t s_mem_stat_n_keys; public: static void Initialize() { s_cgroup_version = FindCGroupVersion(); s_memory_cgroup_path = FindCGroupPath(s_cgroup_version == 1 ? &IsCGroup1MemorySubsystem : nullptr); s_cpu_cgroup_path = FindCGroupPath(s_cgroup_version == 1 ? &IsCGroup1CpuSubsystem : nullptr); - - if (s_cgroup_version == 1) - { - s_mem_stat_n_keys = 4; - s_mem_stat_key_names[0] = "total_inactive_anon "; - s_mem_stat_key_names[1] = "total_active_anon "; - s_mem_stat_key_names[2] = "total_dirty "; - s_mem_stat_key_names[3] = "total_unevictable "; - } - else - { - s_mem_stat_n_keys = 3; - s_mem_stat_key_names[0] = "anon "; - s_mem_stat_key_names[1] = "file_dirty "; - s_mem_stat_key_names[2] = "unevictable "; - } - - for (size_t i = 0; i < s_mem_stat_n_keys; i++) - { - s_mem_stat_key_lengths[i] = strlen(s_mem_stat_key_names[i]); - } } static void Cleanup() @@ -108,9 +87,9 @@ class CGroup if (s_cgroup_version == 0) return false; else if (s_cgroup_version == 1) - return GetCGroupMemoryUsage(val); + return GetCGroupMemoryUsage(val, CGROUP1_MEMORY_USAGE_FILENAME, CGROUP1_MEMORY_STAT_INACTIVE_FIELD); else if (s_cgroup_version == 2) - return GetCGroupMemoryUsage(val); + return GetCGroupMemoryUsage(val, CGROUP2_MEMORY_USAGE_FILENAME, CGROUP2_MEMORY_STAT_INACTIVE_FIELD); else { _ASSERTE(!"Unknown cgroup version."); @@ -416,8 +395,38 @@ class CGroup return result; } - static bool GetCGroupMemoryUsage(size_t *val) + static bool GetCGroupMemoryUsage(size_t *val, const char *filename, const char *inactiveFileFieldName) { + // Use the same way to calculate memory load as popular container tools (Docker, Kubernetes, Containerd etc.) + // For cgroup v1: value of 'memory.usage_in_bytes' minus 'total_inactive_file' value of 'memory.stat' + // For cgroup v2: value of 'memory.current' minus 'inactive_file' value of 'memory.stat' + + char* mem_usage_filename = nullptr; + if (asprintf(&mem_usage_filename, "%s%s", s_memory_cgroup_path, filename) < 0) + return false; + + uint64_t temp = 0; + + size_t usage = 0; + + bool result = ReadMemoryValueFromFile(mem_usage_filename, &temp); + if (result) + { + if (temp > std::numeric_limits::max()) + { + usage = std::numeric_limits::max(); + } + else + { + usage = (size_t)temp; + } + } + + free(mem_usage_filename); + + if (!result) + return result; + if (s_memory_cgroup_path == nullptr) return false; @@ -432,34 +441,32 @@ class CGroup char *line = nullptr; size_t lineLen = 0; - size_t readValues = 0; + bool foundInactiveFileValue = false; char* endptr; - *val = 0; - while (getline(&line, &lineLen, stat_file) != -1 && readValues < s_mem_stat_n_keys) + size_t inactiveFileFieldNameLength = strlen(inactiveFileFieldName); + + while (getline(&line, &lineLen, stat_file) != -1) { - for (size_t i = 0; i < s_mem_stat_n_keys; i++) + if (strncmp(line, inactiveFileFieldName, inactiveFileFieldNameLength) == 0) { - if (strncmp(line, s_mem_stat_key_names[i], s_mem_stat_key_lengths[i]) == 0) + errno = 0; + const char* startptr = line + inactiveFileFieldNameLength; + size_t inactiveFileValue = strtoll(startptr, &endptr, 10); + if (endptr != startptr && errno == 0) { - errno = 0; - const char* startptr = line + s_mem_stat_key_lengths[i]; - *val += strtoll(startptr, &endptr, 10); - if (endptr != startptr && errno == 0) - readValues++; - - break; + foundInactiveFileValue = true; + *val = usage - inactiveFileValue; } + + break; } } fclose(stat_file); free(line); - if (readValues == s_mem_stat_n_keys) - return true; - - return false; + return foundInactiveFileValue; } static bool ReadMemoryValueFromFile(const char* filename, uint64_t* val) @@ -624,10 +631,6 @@ int CGroup::s_cgroup_version = 0; char *CGroup::s_memory_cgroup_path = nullptr; char *CGroup::s_cpu_cgroup_path = nullptr; -const char *CGroup::s_mem_stat_key_names[4] = {}; -size_t CGroup::s_mem_stat_key_lengths[4] = {}; -size_t CGroup::s_mem_stat_n_keys = 0; - void InitializeCGroup() { CGroup::Initialize(); From 3428247624deb717d79ceaf348f63dbb530acfd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksey=20Kliger=20=28=CE=BBgeek=29?= Date: Tue, 14 Jun 2022 12:54:00 -0400 Subject: [PATCH 110/337] [wasm] Fix Debug configuration builds (#70683) * Fix cmake error ``` Manually-specified variables were not used by the project: CONFIGURATION_WASM_OPT_FLAGS ``` * Build the interpreter with -O1 on Wasm in Debug configs Otherwise `interp_exec_method` and `generate_code` can easily overflow the stack in some browsers with even a few recursive calls (for example during .cctor initializaiton) --- src/mono/mono/mini/CMakeLists.txt | 6 ++++++ src/mono/wasm/runtime/CMakeLists.txt | 2 ++ 2 files changed, 8 insertions(+) diff --git a/src/mono/mono/mini/CMakeLists.txt b/src/mono/mono/mini/CMakeLists.txt index 85f5f14a210a2b..448f9ded04fd53 100644 --- a/src/mono/mono/mini/CMakeLists.txt +++ b/src/mono/mono/mini/CMakeLists.txt @@ -289,6 +289,12 @@ if(ENABLE_INTERP_LIB) add_library(mono-ee-interp STATIC "${interp_sources}") target_link_libraries(mono-ee-interp monoapi) install(TARGETS mono-ee-interp LIBRARY) +if(HOST_WASM AND CMAKE_BUILD_TYPE STREQUAL "Debug") +# Always optimize the interpreter, even in Debug builds. Unoptimized interp_exec_method and +# generate_code are so big that some browsers overflow the stack with even a few recursive +# invocations (e.g. during .cctor initialization) +target_compile_options(mono-ee-interp PRIVATE -O1) +endif() endif() if(ENABLE_LLVM) diff --git a/src/mono/wasm/runtime/CMakeLists.txt b/src/mono/wasm/runtime/CMakeLists.txt index f857028e5ad57e..f15ed2ec40297e 100644 --- a/src/mono/wasm/runtime/CMakeLists.txt +++ b/src/mono/wasm/runtime/CMakeLists.txt @@ -34,6 +34,8 @@ set_target_properties(dotnet PROPERTIES LINK_FLAGS "@${NATIVE_BIN_DIR}/src/emcc-default.rsp @${NATIVE_BIN_DIR}/src/emcc-link.rsp ${CONFIGURATION_LINK_FLAGS} --extern-pre-js ${NATIVE_BIN_DIR}/src/cjs/runtime.cjs.iffe.js --pre-js ${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.pre.js --js-library ${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.lib.js --js-library ${NATIVE_BIN_DIR}/src/pal_random.lib.js --post-js ${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.post.js --extern-post-js ${NATIVE_BIN_DIR}/src/cjs/dotnet.cjs.extpost.js " RUNTIME_OUTPUT_DIRECTORY "${NATIVE_BIN_DIR}") +set(ignoreMeWasmOptFlags "${CONFIGURATION_WASM_OPT_FLAGS}") + if(CMAKE_BUILD_TYPE STREQUAL "Release") add_custom_command(TARGET dotnet POST_BUILD COMMAND ${EMSDK_PATH}/upstream/bin/wasm-opt --enable-exception-handling ${CONFIGURATION_WASM_OPT_FLAGS} --strip-dwarf ${NATIVE_BIN_DIR}/dotnet.wasm -o ${NATIVE_BIN_DIR}/dotnet.wasm From fb9be0a9cf88f750bdf5e82ac7ef10eb8d70eaa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksey=20Kliger=20=28=CE=BBgeek=29?= Date: Tue, 14 Jun 2022 12:54:48 -0400 Subject: [PATCH 111/337] [wasm] Make runtime_is_initialized promise callbacks one-shot (#70694) * [wasm] Make runtime_is_initialized promise callbacks one-shot Throw if runtime_is_initialized_resolve or runtime_is_initialized_reject is called more than once * Add a slightly generalized GuardedPromise object Protects against multiple-resolve, multiple-reject, reject after resolve and resolve after reject. Does not protect against the executor throwing. --- src/mono/wasm/runtime/guarded-promise.ts | 34 ++++++++++++++++++++++++ src/mono/wasm/runtime/startup.ts | 7 ++--- 2 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 src/mono/wasm/runtime/guarded-promise.ts diff --git a/src/mono/wasm/runtime/guarded-promise.ts b/src/mono/wasm/runtime/guarded-promise.ts new file mode 100644 index 00000000000000..fe46ca43521ba2 --- /dev/null +++ b/src/mono/wasm/runtime/guarded-promise.ts @@ -0,0 +1,34 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +/// A Promise that guards against multiple-resolve, multiple-reject, reject-after-accept and accept-after-reject. +class GuardedPromise extends Promise { + constructor(executor: (resolve: (value: T | PromiseLike) => void, reject: (reason?: any) => void) => void) { + super((resolve, reject) => { + let resolved = false; + let rejected = false; + executor((value: T | PromiseLike) => { + if (resolved) { + throw new Error("Promise resolved more than once"); + } + if (rejected) { + throw new Error("Can not resolve a Promise after it has been rejected"); + } + resolved = true; + resolve(value); + }, (reason: any) => { + if (resolved) { + throw new Error("Can not reject a Promise after it has been resolved"); + } + if (rejected) { + throw new Error("Promise rejected more than once"); + } + rejected = true; + reject(reason); + }); + }); + } +} + +export default GuardedPromise; + diff --git a/src/mono/wasm/runtime/startup.ts b/src/mono/wasm/runtime/startup.ts index 2920dd8de7b74f..c33549c2717cec 100644 --- a/src/mono/wasm/runtime/startup.ts +++ b/src/mono/wasm/runtime/startup.ts @@ -5,6 +5,7 @@ import { AllAssetEntryTypes, mono_assert, AssetEntry, CharPtrNull, DotnetModule, import { ENVIRONMENT_IS_ESM, ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, INTERNAL, locateFile, Module, MONO, requirePromise, runtimeHelpers } from "./imports"; import cwraps from "./cwraps"; import { mono_wasm_raise_debug_event, mono_wasm_runtime_ready } from "./debug"; +import GuardedPromise from "./guarded-promise"; import { mono_wasm_globalization_init, mono_wasm_load_icu_data } from "./icu"; import { toBase64StringImpl } from "./base64"; import { mono_wasm_init_aot_profiler, mono_wasm_init_coverage_profiler } from "./profiler"; @@ -17,9 +18,9 @@ import { mono_on_abort } from "./run"; import { mono_wasm_new_root } from "./roots"; import { init_crypto } from "./crypto-worker"; -export let runtime_is_initialized_resolve: Function; -export let runtime_is_initialized_reject: Function; -export const mono_wasm_runtime_is_initialized = new Promise((resolve, reject) => { +export let runtime_is_initialized_resolve: () => void; +export let runtime_is_initialized_reject: (reason?: any) => void; +export const mono_wasm_runtime_is_initialized = new GuardedPromise((resolve, reject) => { runtime_is_initialized_resolve = resolve; runtime_is_initialized_reject = reject; }); From 261574bf4121b40c7023c73571fb7a690397bd0f Mon Sep 17 00:00:00 2001 From: Gleb Balykov Date: Tue, 14 Jun 2022 20:34:25 +0300 Subject: [PATCH 112/337] Do not use ExecutableMemoryAllocator on 64 bit platforms if default base address usage is requested (#70563) --- src/coreclr/pal/src/map/map.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/coreclr/pal/src/map/map.cpp b/src/coreclr/pal/src/map/map.cpp index 55b6aa3fecf0ef..ad3a453aa539f0 100644 --- a/src/coreclr/pal/src/map/map.cpp +++ b/src/coreclr/pal/src/map/map.cpp @@ -2284,7 +2284,13 @@ void * MAPMapPEFile(HANDLE hFile, off_t offset) // more efficient code (by avoiding usage of jump stubs). Alignment to a 64 KB granularity should // not be necessary (alignment to page size should be sufficient), but see // ExecutableMemoryAllocator::AllocateMemory() for the reason why it is done. - loadedBase = ReserveMemoryFromExecutableAllocator(pThread, ALIGN_UP(reserveSize, VIRTUAL_64KB)); + +#ifdef FEATURE_ENABLE_NO_ADDRESS_SPACE_RANDOMIZATION + if (!g_useDefaultBaseAddr) +#endif // FEATURE_ENABLE_NO_ADDRESS_SPACE_RANDOMIZATION + { + loadedBase = ReserveMemoryFromExecutableAllocator(pThread, ALIGN_UP(reserveSize, VIRTUAL_64KB)); + } #endif // HOST_64BIT if (loadedBase == NULL) From 56e58d304a8e8e770e4abda13d3031c9feae5709 Mon Sep 17 00:00:00 2001 From: Thays Grazia Date: Tue, 14 Jun 2022 15:55:13 -0300 Subject: [PATCH 113/337] [wasm][debugger] Implement get bytes from loaded_files using debugger protocol. (#69072) * Implement get bytes from loaded_files using debugger protocol. * fix pdb size == nul * Adressing @radical comments. * Fix build. * fix compilation * Addressing @radical comments. Co-authored-by: Ankit Jain --- src/mono/mono/component/debugger-protocol.h | 5 +- src/mono/mono/component/mini-wasm-debugger.c | 18 +++++ src/mono/mono/metadata/mono-debug.c | 13 ++++ src/mono/mono/mini/mini-wasm.h | 2 + .../debugger/BrowserDebugProxy/DebugStore.cs | 74 +++++++++++++------ .../debugger/BrowserDebugProxy/MonoProxy.cs | 7 +- .../BrowserDebugProxy/MonoSDBHelper.cs | 38 +++++++++- src/mono/wasm/runtime/driver.c | 18 +++++ .../metadata/details/assembly-functions.h | 1 + 9 files changed, 150 insertions(+), 26 deletions(-) diff --git a/src/mono/mono/component/debugger-protocol.h b/src/mono/mono/component/debugger-protocol.h index af28674c42d52f..70753b7ec70111 100644 --- a/src/mono/mono/component/debugger-protocol.h +++ b/src/mono/mono/component/debugger-protocol.h @@ -11,7 +11,7 @@ */ #define MAJOR_VERSION 2 -#define MINOR_VERSION 60 +#define MINOR_VERSION 61 typedef enum { MDBGPROT_CMD_COMPOSITE = 100 @@ -36,7 +36,8 @@ typedef enum { MDBGPROT_CMD_VM_READ_MEMORY = 16, MDBGPROT_CMD_VM_WRITE_MEMORY = 17, MDBGPROT_CMD_GET_ASSEMBLY_BY_NAME = 18, - MDBGPROT_CMD_GET_MODULE_BY_GUID = 19 + MDBGPROT_CMD_GET_MODULE_BY_GUID = 19, + MDBGPROT_CMD_GET_ASSEMBLY_BYTES = 20, //wasm specific } MdbgProtCmdVM; typedef enum { diff --git a/src/mono/mono/component/mini-wasm-debugger.c b/src/mono/mono/component/mini-wasm-debugger.c index f719b1806d1159..a13e273ebb9eba 100644 --- a/src/mono/mono/component/mini-wasm-debugger.c +++ b/src/mono/mono/component/mini-wasm-debugger.c @@ -418,6 +418,24 @@ mono_wasm_send_dbg_command (int id, MdbgProtCommandSet command_set, int command, invoke_data.endp = data + size; error = mono_do_invoke_method (tls, &buf, &invoke_data, data, &data); } + else if (command_set == MDBGPROT_CMD_SET_VM && (command == MDBGPROT_CMD_GET_ASSEMBLY_BYTES)) + { + char* assembly_name = m_dbgprot_decode_string (data, &data, data + size); + if (assembly_name == NULL) + { + m_dbgprot_buffer_add_int (&buf, 0); + m_dbgprot_buffer_add_int (&buf, 0); + } + else + { + unsigned int assembly_size = 0; + int symfile_size = 0; + const unsigned char* assembly_bytes = mono_wasm_get_assembly_bytes (assembly_name, &assembly_size); + const unsigned char* pdb_bytes = mono_get_symfile_bytes_from_bundle (assembly_name, &symfile_size); + m_dbgprot_buffer_add_byte_array (&buf, (uint8_t *) assembly_bytes, assembly_size); + m_dbgprot_buffer_add_byte_array (&buf, (uint8_t *) pdb_bytes, symfile_size); + } + } else error = mono_process_dbg_packet (id, command_set, command, &no_reply, data, data + size, &buf); diff --git a/src/mono/mono/metadata/mono-debug.c b/src/mono/mono/metadata/mono-debug.c index 5fbe40b0f55b72..37a98e7e43df38 100644 --- a/src/mono/mono/metadata/mono-debug.c +++ b/src/mono/mono/metadata/mono-debug.c @@ -1112,6 +1112,19 @@ open_symfile_from_bundle (MonoImage *image) return NULL; } +const mono_byte * +mono_get_symfile_bytes_from_bundle (const char *assembly_name, int *size) +{ + BundledSymfile *bsymfile; + for (bsymfile = bundled_symfiles; bsymfile; bsymfile = bsymfile->next) { + if (strcmp (bsymfile->aname, assembly_name)) + continue; + *size = bsymfile->size; + return bsymfile->raw_contents; + } + return NULL; +} + void mono_debugger_lock (void) { diff --git a/src/mono/mono/mini/mini-wasm.h b/src/mono/mono/mini/mini-wasm.h index d307077de1c337..e83a1baefb1933 100644 --- a/src/mono/mono/mini/mini-wasm.h +++ b/src/mono/mono/mini/mini-wasm.h @@ -103,6 +103,8 @@ G_EXTERN_C void mono_wasm_enable_debugging (int log_level); void mono_wasm_set_timeout (int timeout); int mono_wasm_assembly_already_added (const char *assembly_name); +const unsigned char *mono_wasm_get_assembly_bytes (const char *name, unsigned int *size); + void mono_wasm_print_stack_trace (void); gboolean diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs b/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs index 9fb4b8f04fe9e8..2baa2f2e02873f 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/DebugStore.cs @@ -1366,36 +1366,61 @@ public IEnumerable Add(SessionId id, string name, byte[] assembly_da } } - public async IAsyncEnumerable Load(SessionId id, string[] loaded_files, [EnumeratorCancellation] CancellationToken token) + public async IAsyncEnumerable Load(SessionId id, string[] loaded_files, ExecutionContext context, bool useDebuggerProtocol, [EnumeratorCancellation] CancellationToken token) { var asm_files = new List(); - var pdb_files = new List(); - foreach (string file_name in loaded_files) - { - if (file_name.EndsWith(".pdb", StringComparison.OrdinalIgnoreCase)) - pdb_files.Add(file_name); - else - asm_files.Add(file_name); - } - List steps = new List(); - foreach (string url in asm_files) + + if (!useDebuggerProtocol) { - try + var pdb_files = new List(); + foreach (string file_name in loaded_files) { - string candidate_pdb = Path.ChangeExtension(url, "pdb"); - string pdb = pdb_files.FirstOrDefault(n => n == candidate_pdb); + if (file_name.EndsWith(".pdb", StringComparison.OrdinalIgnoreCase)) + pdb_files.Add(file_name); + else + asm_files.Add(file_name); + } - steps.Add( - new DebugItem - { - Url = url, - Data = Task.WhenAll(MonoProxy.HttpClient.GetByteArrayAsync(url, token), pdb != null ? MonoProxy.HttpClient.GetByteArrayAsync(pdb, token) : Task.FromResult(null)) - }); + foreach (string url in asm_files) + { + try + { + string candidate_pdb = Path.ChangeExtension(url, "pdb"); + string pdb = pdb_files.FirstOrDefault(n => n == candidate_pdb); + + steps.Add( + new DebugItem + { + Url = url, + Data = Task.WhenAll(MonoProxy.HttpClient.GetByteArrayAsync(url, token), pdb != null ? MonoProxy.HttpClient.GetByteArrayAsync(pdb, token) : Task.FromResult(null)) + }); + } + catch (Exception e) + { + logger.LogDebug($"Failed to read {url} ({e.Message})"); + } } - catch (Exception e) + } + else + { + foreach (string file_name in loaded_files) { - logger.LogDebug($"Failed to read {url} ({e.Message})"); + if (file_name.EndsWith(".pdb", StringComparison.OrdinalIgnoreCase)) + continue; + try + { + steps.Add( + new DebugItem + { + Url = file_name, + Data = context.SdbAgent.GetBytesFromAssemblyAndPdb(Path.GetFileName(file_name), token) + }); + } + catch (Exception e) + { + logger.LogDebug($"Failed to read {file_name} ({e.Message})"); + } } } @@ -1405,6 +1430,11 @@ public async IAsyncEnumerable Load(SessionId id, string[] loaded_fil try { byte[][] bytes = await step.Data.ConfigureAwait(false); + if (bytes[0] == null) + { + logger.LogDebug($"Bytes from assembly {step.Url} is NULL"); + continue; + } assembly = new AssemblyInfo(monoProxy, id, step.Url, bytes[0], bytes[1], logger, token); } catch (Exception e) diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs index d81bb825b467b5..4ddddec96cb8db 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs @@ -1509,7 +1509,12 @@ internal async Task LoadStore(SessionId sessionId, CancellationToken } else { - await foreach (SourceFile source in context.store.Load(sessionId, loaded_files, token).WithCancellation(token)) + var useDebuggerProtocol = false; + (int MajorVersion, int MinorVersion) = await context.SdbAgent.GetVMVersion(token); + if (MajorVersion == 2 && MinorVersion >= 61) + useDebuggerProtocol = true; + + await foreach (SourceFile source in context.store.Load(sessionId, loaded_files, context, useDebuggerProtocol, token)) { await OnSourceFileAdded(sessionId, source, context, token); } diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs index a95715a4ef19a0..1ee180fadb73e1 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs @@ -140,7 +140,8 @@ internal enum CmdVM { VmReadMemory = 16, VmWriteMemory = 17, GetAssemblyByName = 18, - GetModuleByGUID = 19 + GetModuleByGUID = 19, + GetAssemblyAndPdbBytes = 20 } internal enum CmdFrame { @@ -750,6 +751,9 @@ internal sealed class MonoSDBHelper private static int MINOR_VERSION = 61; private static int MAJOR_VERSION = 2; + private int VmMinorVersion { get; set; } + private int VmMajorVersion { get; set; } + private Dictionary methods; private Dictionary assemblies; private Dictionary types; @@ -770,6 +774,8 @@ public MonoSDBHelper(MonoProxy proxy, ILogger logger, SessionId sessionId) this.proxy = proxy; this.logger = logger; this.sessionId = sessionId; + this.VmMajorVersion = -1; + this.VmMinorVersion = -1; ValueCreator = new(this, logger); ResetStore(null); } @@ -883,6 +889,18 @@ public async Task GetTypeInfo(int typeId, Cancella public void ClearCache() => ValueCreator.ClearCache(); + public async Task<(int, int)> GetVMVersion(CancellationToken token) + { + if (VmMajorVersion != -1) + return (VmMajorVersion, VmMinorVersion); + using var commandParamsWriter = new MonoBinaryWriter(); + using var retDebuggerCmdReader = await SendDebuggerAgentCommand(CmdVM.Version, commandParamsWriter, token); + retDebuggerCmdReader.ReadString(); //vm version + VmMajorVersion = retDebuggerCmdReader.ReadInt32(); + VmMinorVersion = retDebuggerCmdReader.ReadInt32(); + return (VmMajorVersion, VmMinorVersion); + } + public async Task SetProtocolVersion(CancellationToken token) { using var commandParamsWriter = new MonoBinaryWriter(); @@ -2128,6 +2146,24 @@ public async Task ApplyUpdates(int moduleId, string dmeta, string dil, str return true; } + public async Task GetBytesFromAssemblyAndPdb(string assemblyName, CancellationToken token) + { + using var commandParamsWriter = new MonoBinaryWriter(); + byte[] assembly_buf = null; + byte[] pdb_buf = null; + commandParamsWriter.Write(assemblyName); + var retDebuggerCmdReader = await SendDebuggerAgentCommand(CmdVM.GetAssemblyAndPdbBytes, commandParamsWriter, token); + int assembly_size = retDebuggerCmdReader.ReadInt32(); + if (assembly_size > 0) + assembly_buf = retDebuggerCmdReader.ReadBytes(assembly_size); + int pdb_size = retDebuggerCmdReader.ReadInt32(); + if (pdb_size > 0) + pdb_buf = retDebuggerCmdReader.ReadBytes(pdb_size); + byte[][] ret = new byte[2][]; + ret[0] = assembly_buf; + ret[1] = pdb_buf; + return ret; + } private static readonly string[] s_primitiveTypeNames = new[] { "bool", diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index 2a30682885e7cd..fb0b15101fdd33 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -238,6 +238,24 @@ mono_wasm_assembly_already_added (const char *assembly_name) return 0; } +const unsigned char * +mono_wasm_get_assembly_bytes (const char *assembly_name, unsigned int *size) +{ + if (assembly_count == 0) + return 0; + + WasmAssembly *entry = assemblies; + while (entry != NULL) { + if (strcmp (entry->assembly.name, assembly_name) == 0) + { + *size = entry->assembly.size; + return entry->assembly.data; + } + entry = entry->next; + } + return NULL; +} + typedef struct WasmSatelliteAssembly_ WasmSatelliteAssembly; struct WasmSatelliteAssembly_ { diff --git a/src/native/public/mono/metadata/details/assembly-functions.h b/src/native/public/mono/metadata/details/assembly-functions.h index 4634ba4046a0f5..df752b66956193 100644 --- a/src/native/public/mono/metadata/details/assembly-functions.h +++ b/src/native/public/mono/metadata/details/assembly-functions.h @@ -64,6 +64,7 @@ MONO_API_FUNCTION(MONO_RT_EXTERNAL_ONLY void, mono_assembly_name_free, (MonoAsse MONO_API_FUNCTION(void, mono_register_bundled_assemblies, (const MonoBundledAssembly **assemblies)) MONO_API_FUNCTION(void, mono_register_symfile_for_assembly, (const char* assembly_name, const mono_byte *raw_contents, int size)) +MONO_API_FUNCTION(const mono_byte *, mono_get_symfile_bytes_from_bundle, (const char* assembly_name, int *size)) MONO_API_FUNCTION(void, mono_set_assemblies_path, (const char* path)) From 978df67ced885aeca5f7e75379451bc1a57cc219 Mon Sep 17 00:00:00 2001 From: Andy Gocke Date: Tue, 14 Jun 2022 12:13:53 -0700 Subject: [PATCH 114/337] Add doc on Unix temporary file security practice (#70585) * Add doc on Unix temporary file security practice * Update unix-tmp.md * Update unix-tmp.md * Add example permissions encoding * Update docs/design/security/unix-tmp.md Co-authored-by: Dan Moseley * Update unix-tmp.md Co-authored-by: Dan Moseley --- docs/design/security/unix-tmp.md | 45 ++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 docs/design/security/unix-tmp.md diff --git a/docs/design/security/unix-tmp.md b/docs/design/security/unix-tmp.md new file mode 100644 index 00000000000000..bea8cb8f11ae6a --- /dev/null +++ b/docs/design/security/unix-tmp.md @@ -0,0 +1,45 @@ + +# Unix temporary files + +The Unix support for temporary files is different from the Windows model and developers who +are used to Windows may inadvertently create security risk if they use the same practices on Unix. + +Most notably, the Windows model for temporary files is that the operating system provides each user with a *unique*, *user-owned* temporary directory. +Moreover, all Windows users, including the service and system users, have designated user folders, including temporary folders. + +The Unix model is very different. The temp directory, assuming there is one, is often a global folder (except on MacOS). +If possible, prefer a library function like `GetTempPath()` to find the folder. Otherwise, +the `TMPDIR` environment variable is used to store the location of this folder. This variable is +widely used and supported, but it is not mandatory for all Unix implementations. It should be the preferred +mechanism for finding the Unix temporary folder if a library method is not available. It will commonly +point to either the `/tmp` or `/var/tmp` folder. These folders are not used for MacOS, so it is not recommended +to use them directly. + +Because the temporary directory is often global, any use of the temp directory should be carefully +considered. In general, the best use of the temp directory is for programs which, + +1. Will create the temporary file during their process execution +1. Do not depend on predictable temporary file/folder names +1. Will not access the file after the process exits + +In these cases, the process can create a file or files with + 1. A pseudorandom name, unlikely to cause collisions + 1. Permissions which restrict all access to owner-only, i.e. 700 for directories, 600 for files + +Any other use needs to be carefully audited, particularly if the temporary file is intended for use across +multiple processes. Some considerations: + +- **Never** write files with global access permissions +- **Always** verify that the owner of the file is the current user and that the permissions + only allow write access by the owner when reading existing files +- **Never** rely on having ownership of a particular file name. Any process can write a file with that name, + creating a denial of service. + - When creating files, consider likelihood of file name collision and performance impact of attempting + to create new names, if supported. + + If any of the above conflict with the feature requirements, consider instead writing temporary files to a + location in the user home folder. Some considerations for this model: + + - There is no automatic cleanup in user folders. Files will remain permanently or require cleanup by the app + - Some environments do not have user home folders (e.g., systemd). Consider providing an environment variable + to override the location of the temporary folder, and provide user documentation for this variable. From 0ca092e806d407d91b0e20f1552d6505cd872d3e Mon Sep 17 00:00:00 2001 From: Badre BSAILA <54767641+pedrobsaila@users.noreply.github.com> Date: Tue, 14 Jun 2022 23:52:30 +0200 Subject: [PATCH 115/337] ConfigurationBinder.Bind on virtual properties duplicates elements (#70592) * ConfigurationBinder.Bind on virtual properties duplicates elements * simplify GetAllProperties * return array instead of list --- .../src/ConfigurationBinder.cs | 24 ++++-------------- .../tests/ConfigurationBinderTests.cs | 25 +++++++++++++++++++ 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs index 2d2f5658188a44..bc7b74e24db8be 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/src/ConfigurationBinder.cs @@ -204,7 +204,7 @@ public static void Bind(this IConfiguration configuration, object? instance, Act [RequiresUnreferencedCode(PropertyTrimmingWarningMessage)] private static void BindNonScalar(this IConfiguration configuration, object instance, BinderOptions options) { - List modelProperties = GetAllProperties(instance.GetType()); + PropertyInfo[] modelProperties = GetAllProperties(instance.GetType()); if (options.ErrorOnUnknownConfiguration) { @@ -451,7 +451,7 @@ private static object CreateInstance( } - List properties = GetAllProperties(type); + PropertyInfo[] properties = GetAllProperties(type); if (!DoAllParametersHaveEquivalentProperties(parameters, properties, out string nameOfInvalidParameters)) { @@ -482,7 +482,7 @@ private static object CreateInstance( } private static bool DoAllParametersHaveEquivalentProperties(ParameterInfo[] parameters, - List properties, out string missing) + PropertyInfo[] properties, out string missing) { HashSet propertyNames = new(StringComparer.OrdinalIgnoreCase); foreach (PropertyInfo prop in properties) @@ -752,22 +752,8 @@ private static bool IsArrayCompatibleReadOnlyInterface(Type type) return null; } - private static List GetAllProperties( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] - Type type) - { - var allProperties = new List(); - - Type? baseType = type; - do - { - allProperties.AddRange(baseType!.GetProperties(DeclaredOnlyLookup)); - baseType = baseType.BaseType; - } - while (baseType != typeof(object)); - - return allProperties; - } + private static PropertyInfo[] GetAllProperties([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type) + => type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); [RequiresUnreferencedCode(PropertyTrimmingWarningMessage)] private static object? BindParameter(ParameterInfo parameter, Type type, IConfiguration config, diff --git a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/ConfigurationBinderTests.cs b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/ConfigurationBinderTests.cs index 932b6111fb25a3..16d58c6166cec8 100644 --- a/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/ConfigurationBinderTests.cs +++ b/src/libraries/Microsoft.Extensions.Configuration.Binder/tests/ConfigurationBinderTests.cs @@ -1750,6 +1750,21 @@ public void CanBindNullableNestedStructProperties() Assert.True(bound.NullableNestedStruct.Value.DeeplyNested.Boolean); } + [Fact] + public void CanBindVirtualPropertiesWithoutDuplicates() + { + ConfigurationBuilder configurationBuilder = new(); + configurationBuilder.AddInMemoryCollection(new Dictionary + { + { "Test:0", "1" } + }); + IConfiguration config = configurationBuilder.Build(); + + var test = new ClassOverridingVirtualProperty(); + config.Bind(test); + Assert.Equal("1", Assert.Single(test.Test)); + } + private interface ISomeInterface { @@ -1827,5 +1842,15 @@ public struct DeeplyNested public bool Boolean { get; set; } } } + + public class BaseClassWithVirtualProperty + { + public virtual string[] Test { get; set; } = System.Array.Empty(); + } + + public class ClassOverridingVirtualProperty : BaseClassWithVirtualProperty + { + public override string[] Test { get => base.Test; set => base.Test = value; } + } } } From 042fdf43dedd58dc3e6cdc118df5a7198792a9e7 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Tue, 14 Jun 2022 15:15:36 -0700 Subject: [PATCH 116/337] Obsolete AssemblyName.CodeBase, AssemblyName.EscapedCodeBase (#70534) --- .../src/System/Reflection/RuntimeAssembly.cs | 5 +++-- src/libraries/Common/src/System/Obsoletions.cs | 3 +++ .../ComponentModel/Composition/Hosting/AssemblyCatalog.cs | 2 ++ .../src/System/Reflection/AssemblyName.cs | 2 ++ .../src/System/Xml/Serialization/Compilation.cs | 1 - src/libraries/System.Reflection/tests/AssemblyNameTests.cs | 3 ++- .../System.Runtime.Extensions/tests/System/AppDomainTests.cs | 2 -- .../System.Runtime.Loader/tests/AssemblyLoadContextTest.cs | 2 -- src/libraries/System.Runtime/ref/System.Runtime.cs | 2 ++ 9 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs index c6c20002f2cdcb..fa602e0c1dc390 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs @@ -134,9 +134,10 @@ public override AssemblyName GetName(bool copiedName) an.RawFlags = GetFlags() | AssemblyNameFlags.PublicKey; -#pragma warning disable IL3000 // System.Reflection.AssemblyName.CodeBase' always returns an empty string for assemblies embedded in a single-file app. +#pragma warning disable IL3000, SYSLIB0044 // System.Reflection.AssemblyName.CodeBase' always returns an empty string for assemblies embedded in a single-file app. + // AssemblyName.CodeBase and AssemblyName.EscapedCodeBase are obsolete. Using them for loading an assembly is not supported. an.CodeBase = GetCodeBase(); -#pragma warning restore IL3000 +#pragma warning restore IL3000, SYSLIB0044 #pragma warning disable SYSLIB0037 // AssemblyName.HashAlgorithm is obsolete an.HashAlgorithm = GetHashAlgorithm(); diff --git a/src/libraries/Common/src/System/Obsoletions.cs b/src/libraries/Common/src/System/Obsoletions.cs index 0e96926467077c..bf9e6a0b990b90 100644 --- a/src/libraries/Common/src/System/Obsoletions.cs +++ b/src/libraries/Common/src/System/Obsoletions.cs @@ -141,5 +141,8 @@ internal static class Obsoletions internal const string EcDhPublicKeyBlobMessage = "ECDiffieHellmanPublicKey.ToByteArray() and the associated constructor do not have a consistent and interoperable implementation on all platforms. Use ECDiffieHellmanPublicKey.ExportSubjectPublicKeyInfo() instead."; internal const string EcDhPublicKeyBlobDiagId = "SYSLIB0043"; + + internal const string AssemblyNameCodeBaseMessage = "AssemblyName.CodeBase and AssemblyName.EscapedCodeBase are obsolete. Using them for loading an assembly is not supported."; + internal const string AssemblyNameCodeBaseDiagId = "SYSLIB0044"; } } diff --git a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/AssemblyCatalog.cs b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/AssemblyCatalog.cs index d35b5df575d1f5..3eeb586b5f910b 100644 --- a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/AssemblyCatalog.cs +++ b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/AssemblyCatalog.cs @@ -558,7 +558,9 @@ private static Assembly LoadAssembly(string codeBase) catch (ArgumentException) { assemblyName = new AssemblyName(); +#pragma warning disable SYSLIB0044 // AssemblyName.CodeBase and AssemblyName.EscapedCodeBase are obsolete. Using them for loading an assembly is not supported. assemblyName.CodeBase = codeBase; +#pragma warning restore SYSLIB0044 } try diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyName.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyName.cs index b5034994b45134..479c6199feceb2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyName.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/AssemblyName.cs @@ -82,6 +82,7 @@ public string? CultureName set => _cultureInfo = (value == null) ? null : new CultureInfo(value); } + [Obsolete(Obsoletions.AssemblyNameCodeBaseMessage, DiagnosticId = Obsoletions.AssemblyNameCodeBaseDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] public string? CodeBase { [RequiresAssemblyFiles("The code will return an empty string for assemblies embedded in a single-file app")] @@ -89,6 +90,7 @@ public string? CodeBase set => _codeBase = value; } + [Obsolete(Obsoletions.AssemblyNameCodeBaseMessage, DiagnosticId = Obsoletions.AssemblyNameCodeBaseDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [RequiresAssemblyFiles("The code will return an empty string for assemblies embedded in a single-file app")] public string? EscapedCodeBase { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compilation.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compilation.cs index eb198919446b98..bb49980d6b115c 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compilation.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compilation.cs @@ -162,7 +162,6 @@ internal void InitAssemblyMethods(XmlMapping[] xmlMappings) serializerName = Compiler.GetTempAssemblyName(name, defaultNamespace); // use strong name name.Name = serializerName; - name.CodeBase = null; name.CultureInfo = CultureInfo.InvariantCulture; try diff --git a/src/libraries/System.Reflection/tests/AssemblyNameTests.cs b/src/libraries/System.Reflection/tests/AssemblyNameTests.cs index 612ca620ee7a01..ce1f29b4789549 100644 --- a/src/libraries/System.Reflection/tests/AssemblyNameTests.cs +++ b/src/libraries/System.Reflection/tests/AssemblyNameTests.cs @@ -235,7 +235,7 @@ public void Verify_CultureName() AssemblyName an = new AssemblyName("MyAssemblyName"); Assert.Null(an.CultureName); } - +#pragma warning disable SYSLIB0044 // AssemblyName.CodeBase .AssemblyName.EscapedCodeBase are obsolete [Fact] public void Verify_CodeBase() { @@ -259,6 +259,7 @@ public static void Verify_EscapedCodeBase() n.CodeBase = @"file:///c:/program files/MyAssemblyName.dll"; Assert.Equal(n.EscapedCodeBase, Uri.EscapeUriString(n.CodeBase)); } +#pragma warning restore SYSLIB0044 [Fact] public static void Verify_HashAlgorithm() diff --git a/src/libraries/System.Runtime.Extensions/tests/System/AppDomainTests.cs b/src/libraries/System.Runtime.Extensions/tests/System/AppDomainTests.cs index 9aa3789453b6a4..24f763de070595 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/AppDomainTests.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/AppDomainTests.cs @@ -254,7 +254,6 @@ public void ExecuteAssemblyByName() Assert.Equal(10, AppDomain.CurrentDomain.ExecuteAssemblyByName(assembly.FullName, new string[2] { "2", "3" })); Assert.Throws(() => AppDomain.CurrentDomain.ExecuteAssemblyByName(assembly.FullName, new string[1] { "a" })); AssemblyName assemblyName = assembly.GetName(); - assemblyName.CodeBase = null; Assert.Equal(105, AppDomain.CurrentDomain.ExecuteAssemblyByName(assemblyName, new string[3] { "50", "25", "25" })); }).Dispose(); } @@ -358,7 +357,6 @@ public void Unload() public void Load() { AssemblyName assemblyName = typeof(AppDomainTests).Assembly.GetName(); - assemblyName.CodeBase = null; Assert.NotNull(AppDomain.CurrentDomain.Load(assemblyName)); Assert.NotNull(AppDomain.CurrentDomain.Load(typeof(AppDomainTests).Assembly.FullName)); } diff --git a/src/libraries/System.Runtime.Loader/tests/AssemblyLoadContextTest.cs b/src/libraries/System.Runtime.Loader/tests/AssemblyLoadContextTest.cs index 82097bf4a6f21d..43f3a0726de3be 100644 --- a/src/libraries/System.Runtime.Loader/tests/AssemblyLoadContextTest.cs +++ b/src/libraries/System.Runtime.Loader/tests/AssemblyLoadContextTest.cs @@ -115,7 +115,6 @@ public static void LoadFromAssemblyName_AssemblyNotFound() public static void LoadFromAssemblyName_ValidTrustedPlatformAssembly() { var asmName = typeof(System.Linq.Enumerable).Assembly.GetName(); - asmName.CodeBase = null; var loadContext = new CustomTPALoadContext(); // We should be able to override (and thus, load) assemblies that were @@ -131,7 +130,6 @@ public static void LoadFromAssemblyName_ValidTrustedPlatformAssembly() public static void LoadFromAssemblyName_FallbackToDefaultContext() { var asmName = typeof(System.Linq.Enumerable).Assembly.GetName(); - asmName.CodeBase = null; var loadContext = new AssemblyLoadContext("FallbackToDefaultContextTest"); // This should not have any special handlers, so it should just find the version in the default context diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 680a79f0102a2d..6128d31e83f8a7 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -10781,11 +10781,13 @@ public sealed partial class AssemblyName : System.ICloneable, System.Runtime.Ser { public AssemblyName() { } public AssemblyName(string assemblyName) { } + [System.ObsoleteAttribute("AssemblyName.CodeBase and AssemblyName.EscapedCodeBase are obsolete. Using them for loading an assembly is not supported.", DiagnosticId = "SYSLIB0044", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public string? CodeBase { [System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute("The code will return an empty string for assemblies embedded in a single-file app")] get { throw null; } set { } } public System.Reflection.AssemblyContentType ContentType { get { throw null; } set { } } public System.Globalization.CultureInfo? CultureInfo { get { throw null; } set { } } public string? CultureName { get { throw null; } set { } } [System.Diagnostics.CodeAnalysis.RequiresAssemblyFilesAttribute("The code will return an empty string for assemblies embedded in a single-file app")] + [System.ObsoleteAttribute("AssemblyName.CodeBase and AssemblyName.EscapedCodeBase are obsolete. Using them for loading an assembly is not supported.", DiagnosticId = "SYSLIB0044", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] public string? EscapedCodeBase { get { throw null; } } public System.Reflection.AssemblyNameFlags Flags { get { throw null; } set { } } public string FullName { get { throw null; } } From c8654e7378a085c8221028cf0ebd759d800ceba7 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Wed, 15 Jun 2022 01:09:55 +0200 Subject: [PATCH 117/337] JIT: Enable JitConsumeProfileForCasts by default (#69869) --- .../src/System/Runtime/CompilerServices/CastHelpers.cs | 7 ++++++- src/coreclr/jit/jitconfigvalues.h | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs index a921099356ec3d..486aeb72faddbc 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/CastHelpers.cs @@ -477,7 +477,12 @@ private static CastResult TryGet(nuint source, nuint target) private static object? ChkCastClassSpecial(void* toTypeHnd, object obj) { MethodTable* mt = RuntimeHelpers.GetMethodTable(obj); - Debug.Assert(mt != toTypeHnd, "The check for the trivial cases should be inlined by the JIT"); + + // Normally, this case is expected to be handled by JIT inline. + // However, with PGO data JIT might decide to check a different type instead + // so this one has to be always checked here + if (toTypeHnd == mt) + goto done; for (; ; ) { diff --git a/src/coreclr/jit/jitconfigvalues.h b/src/coreclr/jit/jitconfigvalues.h index 33cf1d74f206eb..569b030b95a84f 100644 --- a/src/coreclr/jit/jitconfigvalues.h +++ b/src/coreclr/jit/jitconfigvalues.h @@ -548,7 +548,7 @@ CONFIG_INTEGER(JitMinimalJitProfiling, W("JitMinimalJitProfiling"), 1) CONFIG_INTEGER(JitMinimalPrejitProfiling, W("JitMinimalPrejitProfiling"), 0) CONFIG_INTEGER(JitProfileCasts, W("JitProfileCasts"), 0) // Profile castclass/isinst -CONFIG_INTEGER(JitConsumeProfileForCasts, W("JitConsumeProfileForCasts"), 0) // Consume profile data (if any) for +CONFIG_INTEGER(JitConsumeProfileForCasts, W("JitConsumeProfileForCasts"), 1) // Consume profile data (if any) for // castclass/isinst CONFIG_INTEGER(JitClassProfiling, W("JitClassProfiling"), 1) // Profile virtual and interface calls From 41ce20a1c294b87cfe2b081f696b9b96238785ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Rylek?= Date: Wed, 15 Jun 2022 02:07:05 +0200 Subject: [PATCH 118/337] Fix AttributePresence in composite mode (#70737) According to my comparative perf measurements composite framework spends about 5M more instructions in the method coreclr.dll!CMiniMdTemplate::SearchTableForMultipleRows(CMiniColDef sColumn) I tracked this down to the R2R table AttributePresence which is used to speed up attribute queries against the ECMA metadata model. In composite mode we were putting the table in the image header, not component header, and so the runtime was unable to locate it. This change fixes generation of the table in Crossgen2; I have verified that with this change I no longer see the 5M outlier. Thanks Tomas --- .../Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs index 550b4e451adc0d..44925d84cfe21c 100644 --- a/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs +++ b/src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs @@ -663,7 +663,7 @@ public void AttachToDependencyGraph(DependencyAnalyzerBase graph) if (inputModule == TypeSystemContext.SystemModule) { AttributePresenceFilterNode attributePresenceTable = new AttributePresenceFilterNode(inputModule); - Header.Add(Internal.Runtime.ReadyToRunSectionType.AttributePresence, attributePresenceTable, attributePresenceTable); + tableHeader.Add(Internal.Runtime.ReadyToRunSectionType.AttributePresence, attributePresenceTable, attributePresenceTable); } } From 6896e1bb4aae0877a6cb154710b6936e4d69716e Mon Sep 17 00:00:00 2001 From: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> Date: Wed, 15 Jun 2022 03:09:49 +0300 Subject: [PATCH 119/337] Handle mis-sized structs in ARM/64 `PUTARG_SPLIT` codegen (#70249) * Add a test * Fix out-of-bounds loads in ARM/64's "genPutArgSplit" * Split the test out --- src/coreclr/jit/codegenarmarch.cpp | 61 +++++---- .../StructABI/MisSizedStructs_ArmSplit.cs | 124 ++++++++++++++++++ .../StructABI/MisSizedStructs_ArmSplit.csproj | 13 ++ 3 files changed, 174 insertions(+), 24 deletions(-) create mode 100644 src/tests/JIT/Directed/StructABI/MisSizedStructs_ArmSplit.cs create mode 100644 src/tests/JIT/Directed/StructABI/MisSizedStructs_ArmSplit.csproj diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index f5de40823259e4..bbaba6051a0f33 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -1306,14 +1306,8 @@ void CodeGen::genPutArgSplit(GenTreePutArgSplit* treeNode) } else // addrNode is used { - assert(addrNode != nullptr); - // TODO-Cleanup: `Lowering::NewPutArg` marks only `LCL_VAR_ADDR` as contained nowadays, - // but we use `genConsumeAddress` as a precaution, use `genConsumeReg()` instead. - assert(!addrNode->isContained()); - // Generate code to load the address that we need into a register - genConsumeAddress(addrNode); - addrReg = addrNode->GetRegNum(); + addrReg = genConsumeReg(addrNode); // If addrReg equal to baseReg, we use the last target register as alternative baseReg. // Because the candidate mask for the internal baseReg does not include any of the target register, @@ -1327,21 +1321,40 @@ void CodeGen::genPutArgSplit(GenTreePutArgSplit* treeNode) ClassLayout* layout = source->AsObj()->GetLayout(); // Put on stack first - unsigned nextIndex = treeNode->gtNumRegs; - unsigned structOffset = nextIndex * TARGET_POINTER_SIZE; - int remainingSize = treeNode->GetStackByteSize(); + unsigned structOffset = treeNode->gtNumRegs * TARGET_POINTER_SIZE; + unsigned remainingSize = layout->GetSize() - structOffset; unsigned argOffsetOut = treeNode->getArgOffset(); - // remainingSize is always multiple of TARGET_POINTER_SIZE - assert(remainingSize % TARGET_POINTER_SIZE == 0); + assert((remainingSize > 0) && (roundUp(remainingSize, TARGET_POINTER_SIZE) == treeNode->GetStackByteSize())); while (remainingSize > 0) { - var_types type = layout->GetGCPtrType(nextIndex); + var_types type; + if (remainingSize >= TARGET_POINTER_SIZE) + { + type = layout->GetGCPtrType(structOffset / TARGET_POINTER_SIZE); + } + else if (remainingSize >= 4) + { + type = TYP_INT; + } + else if (remainingSize >= 2) + { + type = TYP_USHORT; + } + else + { + assert(remainingSize == 1); + type = TYP_UBYTE; + } + + emitAttr attr = emitActualTypeSize(type); + unsigned moveSize = genTypeSize(type); + instruction loadIns = ins_Load(type); if (varNode != nullptr) { - // Load from our varNumImp source - emit->emitIns_R_S(INS_ldr, emitTypeSize(type), baseReg, srcVarNum, structOffset); + // Load from our local source + emit->emitIns_R_S(loadIns, attr, baseReg, srcVarNum, structOffset); } else { @@ -1349,16 +1362,16 @@ void CodeGen::genPutArgSplit(GenTreePutArgSplit* treeNode) assert(baseReg != addrReg); // Load from our address expression source - emit->emitIns_R_R_I(INS_ldr, emitTypeSize(type), baseReg, addrReg, structOffset); + emit->emitIns_R_R_I(loadIns, attr, baseReg, addrReg, structOffset); } - // Emit str instruction to store the register into the outgoing argument area - emit->emitIns_S_R(INS_str, emitTypeSize(type), baseReg, varNumOut, argOffsetOut); - argOffsetOut += TARGET_POINTER_SIZE; // We stored 4-bytes of the struct - assert(argOffsetOut <= argOffsetMax); // We can't write beyond the outgoing arg area - remainingSize -= TARGET_POINTER_SIZE; // We loaded 4-bytes of the struct - structOffset += TARGET_POINTER_SIZE; - nextIndex += 1; + // Emit the instruction to store the register into the outgoing argument area + emit->emitIns_S_R(ins_Store(type), attr, baseReg, varNumOut, argOffsetOut); + argOffsetOut += moveSize; + assert(argOffsetOut <= argOffsetMax); + + remainingSize -= moveSize; + structOffset += moveSize; } // We set up the registers in order, so that we assign the last target register `baseReg` is no longer in use, @@ -1371,7 +1384,7 @@ void CodeGen::genPutArgSplit(GenTreePutArgSplit* treeNode) if (varNode != nullptr) { - // Load from our varNumImp source + // Load from our local source emit->emitIns_R_S(INS_ldr, emitTypeSize(type), targetReg, srcVarNum, structOffset); } else diff --git a/src/tests/JIT/Directed/StructABI/MisSizedStructs_ArmSplit.cs b/src/tests/JIT/Directed/StructABI/MisSizedStructs_ArmSplit.cs new file mode 100644 index 00000000000000..2f83aa0685b7da --- /dev/null +++ b/src/tests/JIT/Directed/StructABI/MisSizedStructs_ArmSplit.cs @@ -0,0 +1,124 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; + +public unsafe class MisSizedStructs_ArmSplit +{ + public const byte ByteValue = 0xC1; + + public static int Main() + { + if (ProblemWithOutOfBoundsLoads(out int result)) + { + return result; + } + + return 100; + } + + // Test that we do not load of bounds for split arguments on ARM. + // + static bool ProblemWithOutOfBoundsLoads(out int result) + { + result = 100; + + // TODO: enable for x64 once https://github.com/dotnet/runtime/issues/65937 has been fixed. + if (!OperatingSystem.IsLinux() || (RuntimeInformation.ProcessArchitecture == Architecture.X64)) + { + return false; + } + + const int PROT_NONE = 0x0; + const int PROT_READ = 0x1; + const int PROT_WRITE = 0x2; + const int MAP_PRIVATE = 0x02; + const int MAP_ANONYMOUS = 0x20; + const int PAGE_SIZE = 0x1000; + + byte* pages = (byte*)mmap(null, 2 * PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + if (pages == (byte*)-1) + { + Console.WriteLine("Failed to allocate two pages, errno is {0}, giving up on the test", Marshal.GetLastSystemError()); + return false; + } + + if (mprotect(pages + PAGE_SIZE, PAGE_SIZE, PROT_NONE) != 0) + { + Console.WriteLine("Failed to protect the second page, errno is {0}, giving up on the test", Marshal.GetLastSystemError()); + munmap(pages, 2 * PAGE_SIZE); + return false; + } + + pages[PAGE_SIZE - 1] = ByteValue; + + if (CallForSplitStructWithSixteenBytes(0, *(StructWithSixteenBytes*)(pages + PAGE_SIZE - sizeof(StructWithSixteenBytes))) != ByteValue) + { + result = 200; + return true; + } + if (CallForSplitStructWithSeventeenBytes(0, *(StructWithSeventeenBytes*)(pages + PAGE_SIZE - sizeof(StructWithSeventeenBytes))) != ByteValue) + { + result = 201; + return true; + } + if (CallForSplitStructWithEighteenBytes(0, *(StructWithEighteenBytes*)(pages + PAGE_SIZE - sizeof(StructWithEighteenBytes))) != ByteValue) + { + result = 202; + return true; + } + if (CallForSplitStructWithNineteenBytes(0, *(StructWithNineteenBytes*)(pages + PAGE_SIZE - sizeof(StructWithNineteenBytes))) != ByteValue) + { + result = 203; + return true; + } + + munmap(pages, 2 * PAGE_SIZE); + + return false; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static byte CallForSplitStructWithSixteenBytes(long arg0, StructWithSixteenBytes splitArg) => splitArg.Bytes[15]; + + [MethodImpl(MethodImplOptions.NoInlining)] + private static byte CallForSplitStructWithSeventeenBytes(long arg0, StructWithSeventeenBytes splitArg) => splitArg.Bytes[16]; + + [MethodImpl(MethodImplOptions.NoInlining)] + private static byte CallForSplitStructWithEighteenBytes(long arg0, StructWithEighteenBytes splitArg) => splitArg.Bytes[17]; + + [MethodImpl(MethodImplOptions.NoInlining)] + private static byte CallForSplitStructWithNineteenBytes(long arg0, StructWithNineteenBytes splitArg) => splitArg.Bytes[18]; + + [DllImport("libc")] + private static extern void* mmap(void* addr, nuint length, int prot, int flags, int fd, nuint offset); + + [DllImport("libc")] + private static extern int mprotect(void* addr, nuint len, int prot); + + [DllImport("libc")] + private static extern int munmap(void* addr, nuint length); + + struct StructWithSixteenBytes + { + public fixed byte Bytes[16]; + } + + struct StructWithSeventeenBytes + { + public fixed byte Bytes[17]; + } + + struct StructWithEighteenBytes + { + public fixed byte Bytes[18]; + } + + struct StructWithNineteenBytes + { + public fixed byte Bytes[19]; + } +} diff --git a/src/tests/JIT/Directed/StructABI/MisSizedStructs_ArmSplit.csproj b/src/tests/JIT/Directed/StructABI/MisSizedStructs_ArmSplit.csproj new file mode 100644 index 00000000000000..de62e29fa3e187 --- /dev/null +++ b/src/tests/JIT/Directed/StructABI/MisSizedStructs_ArmSplit.csproj @@ -0,0 +1,13 @@ + + + Exe + true + + + PdbOnly + True + + + + + From 42d76d33307ee15acfcfa17813fbcd0d10db624d Mon Sep 17 00:00:00 2001 From: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> Date: Wed, 15 Jun 2022 03:31:54 +0300 Subject: [PATCH 120/337] Refactor how implicit byrefs are morphed (#70243) * Refactor implicit by-refs morphing Move it to "fgMorphLocal". Enabled folding in "LocalAddressVisitor". * Add FEATURE_IMPLICIT_BYREFS And use it in all the necessary places. Resolves the TP regression on Unix x64, turning it into a TP improvement. * Add a zero-diff quirk --- src/coreclr/jit/compiler.h | 46 +-- src/coreclr/jit/compiler.hpp | 13 +- src/coreclr/jit/gentree.cpp | 4 +- src/coreclr/jit/lclmorph.cpp | 13 +- src/coreclr/jit/lclvars.cpp | 81 ++++- src/coreclr/jit/morph.cpp | 452 ++++++++++------------------ src/coreclr/jit/scopeinfo.cpp | 4 +- src/coreclr/jit/targetamd64.h | 2 + src/coreclr/jit/targetarm.h | 1 + src/coreclr/jit/targetarm64.h | 1 + src/coreclr/jit/targetloongarch64.h | 1 + src/coreclr/jit/targetx86.h | 1 + src/coreclr/jit/valuenum.cpp | 3 - 13 files changed, 266 insertions(+), 356 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index e8b10c5c55c1b2..a7ece7e80e9cd3 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -477,9 +477,9 @@ class LclVarDsc unsigned char lvIsTemp : 1; // Short-lifetime compiler temp -#if defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#if FEATURE_IMPLICIT_BYREFS unsigned char lvIsImplicitByRef : 1; // Set if the argument is an implicit byref. -#endif // defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#endif // FEATURE_IMPLICIT_BYREFS #if defined(TARGET_LOONGARCH64) unsigned char lvIs4Field1 : 1; // Set if the 1st field is int or float within struct for LA-ABI64. @@ -1015,13 +1015,8 @@ class LclVarDsc return NO_CLASS_HANDLE; } #endif - assert(m_layout != nullptr); -#if defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) - assert(varTypeIsStruct(TypeGet()) || (lvIsImplicitByRef && (TypeGet() == TYP_BYREF))); -#else - assert(varTypeIsStruct(TypeGet())); -#endif - CORINFO_CLASS_HANDLE structHnd = m_layout->GetClassHandle(); + + CORINFO_CLASS_HANDLE structHnd = GetLayout()->GetClassHandle(); assert(structHnd != NO_CLASS_HANDLE); return structHnd; } @@ -1091,10 +1086,14 @@ class LclVarDsc return varTypeIsGC(lvType) || ((lvType == TYP_STRUCT) && m_layout->HasGCPtr()); } - // Returns the layout of a struct variable. + // Returns the layout of a struct variable or implicit byref. ClassLayout* GetLayout() const { - assert(varTypeIsStruct(lvType)); +#if FEATURE_IMPLICIT_BYREFS + assert(varTypeIsStruct(TypeGet()) || (lvIsImplicitByRef && (TypeGet() == TYP_BYREF))); +#else + assert(varTypeIsStruct(TypeGet())); +#endif return m_layout; } @@ -3281,22 +3280,8 @@ class Compiler } #endif // TARGET_X86 - // For x64 this is 3, 5, 6, 7, >8 byte structs that are passed by reference. - // For ARM64, this is structs larger than 16 bytes that are passed by reference. - bool lvaIsImplicitByRefLocal(unsigned varNum) - { -#if defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) - LclVarDsc* varDsc = lvaGetDesc(varNum); - if (varDsc->lvIsImplicitByRef) - { - assert(varDsc->lvIsParam); - - assert(varTypeIsStruct(varDsc) || (varDsc->lvType == TYP_BYREF)); - return true; - } -#endif // defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) - return false; - } + bool lvaIsImplicitByRefLocal(unsigned lclNum) const; + bool lvaIsLocalImplicitlyAccessedByRef(unsigned lclNum) const; // Returns true if this local var is a multireg struct bool lvaIsMultiregStruct(LclVarDsc* varDsc, bool isVararg); @@ -5644,7 +5629,10 @@ class Compiler void fgMakeOutgoingStructArgCopy(GenTreeCall* call, CallArg* arg); GenTree* fgMorphLocal(GenTreeLclVarCommon* lclNode); +#ifdef TARGET_X86 GenTree* fgMorphExpandStackArgForVarArgs(GenTreeLclVarCommon* lclNode); +#endif // TARGET_X86 + GenTree* fgMorphExpandImplicitByRefArg(GenTreeLclVarCommon* lclNode); GenTree* fgMorphLocalVar(GenTree* tree, bool forceRemorph); public: @@ -5858,10 +5846,6 @@ class Compiler // promoted, create new promoted struct temps. void fgRetypeImplicitByRefArgs(); - // Rewrite appearances of implicit byrefs (manifest the implied additional level of indirection). - bool fgMorphImplicitByRefArgs(GenTree* tree); - GenTree* fgMorphImplicitByRefArgs(GenTree* tree, bool isAddr); - // Clear up annotations for any struct promotion temps created for implicit byrefs. void fgMarkDemotedImplicitByRefArgs(); diff --git a/src/coreclr/jit/compiler.hpp b/src/coreclr/jit/compiler.hpp index 5499893630cbc6..294151904e0a0c 100644 --- a/src/coreclr/jit/compiler.hpp +++ b/src/coreclr/jit/compiler.hpp @@ -1123,7 +1123,12 @@ inline GenTreeField* Compiler::gtNewFieldRef(var_types type, CORINFO_FIELD_HANDL LclVarDsc* varDsc = lvaGetDesc(obj->AsUnOp()->gtOp1->AsLclVarCommon()); varDsc->lvFieldAccessed = 1; -#if defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) + + // TODO-Cleanup: the UNIX_AMD64_ABI condition below is a zero-diff quirk. + // Remove it and use "lvaIsImplicitByRefLocal" instead of the "#if". + CLANG_FORMAT_COMMENT_ANCHOR; + +#if FEATURE_IMPLICIT_BYREFS || defined(UNIX_AMD64_ABI) // These structs are passed by reference and can easily become global // references if those references are exposed. We clear out // address-exposure information for these parameters when they are @@ -1135,7 +1140,7 @@ inline GenTreeField* Compiler::gtNewFieldRef(var_types type, CORINFO_FIELD_HANDL { fieldNode->gtFlags |= GTF_GLOB_REF; } -#endif // defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#endif // FEATURE_IMPLICIT_BYREFS || defined(UNIX_AMD64_ABI) } else { @@ -1880,10 +1885,10 @@ inline void LclVarDsc::incRefCnts(weight_t weight, Compiler* comp, RefCountState bool doubleWeight = lvIsTemp; -#if defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#if FEATURE_IMPLICIT_BYREFS // and, for the time being, implicit byref params doubleWeight |= lvIsImplicitByRef; -#endif // defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#endif // FEATURE_IMPLICIT_BYREFS if (doubleWeight && (weight * 2 > weight)) { diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 559a86c26a11b5..2e79010de076e3 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -16415,7 +16415,7 @@ const GenTreeLclVarCommon* GenTree::IsLocalAddrExpr() const // GenTreeLclVar* GenTree::IsImplicitByrefParameterValue(Compiler* compiler) { -#if defined(TARGET_AMD64) || defined(TARGET_ARM64) +#if FEATURE_IMPLICIT_BYREFS && !defined(TARGET_LOONGARCH64) // TODO-LOONGARCH64-CQ: enable this. GenTreeLclVar* lcl = nullptr; @@ -16447,7 +16447,7 @@ GenTreeLclVar* GenTree::IsImplicitByrefParameterValue(Compiler* compiler) return lcl; } -#endif // defined(TARGET_AMD64) || defined(TARGET_ARM64) +#endif // FEATURE_IMPLICIT_BYREFS && !defined(TARGET_LOONGARCH64) return nullptr; } diff --git a/src/coreclr/jit/lclmorph.cpp b/src/coreclr/jit/lclmorph.cpp index 25074f8827472e..358383b6afece7 100644 --- a/src/coreclr/jit/lclmorph.cpp +++ b/src/coreclr/jit/lclmorph.cpp @@ -836,10 +836,10 @@ class LocalAddressVisitor final : public GenTreeVisitor LclVarDsc* varDsc = m_compiler->lvaGetDesc(val.LclNum()); - if (varDsc->lvPromoted || varDsc->lvIsStructField || m_compiler->lvaIsImplicitByRefLocal(val.LclNum())) + if (varDsc->lvPromoted || varDsc->lvIsStructField) { - // TODO-ADDR: For now we ignore promoted and "implicit by ref" variables, - // they require additional changes in subsequent phases. + // TODO-ADDR: For now we ignore promoted variables, they require + // additional changes in subsequent phases. return; } @@ -1017,11 +1017,10 @@ class LocalAddressVisitor final : public GenTreeVisitor return IndirTransform::None; } - if (varDsc->lvPromoted || varDsc->lvIsStructField || m_compiler->lvaIsImplicitByRefLocal(val.LclNum())) + if (varDsc->lvPromoted || varDsc->lvIsStructField) { - // TODO-ADDR: For now we ignore promoted and "implicit by ref" variables, - // they require additional changes in subsequent phases - // (e.g. fgMorphImplicitByRefArgs does not handle LCL_FLD nodes). + // TODO-ADDR: For now we ignore promoted variables, they require additional + // changes in subsequent phases. return IndirTransform::None; } diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index cc12c8a3837dad..53a601b068a284 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -1494,14 +1494,14 @@ void Compiler::lvaInitVarDsc(LclVarDsc* varDsc, varDsc->lvOverlappingFields = StructHasOverlappingFields(cFlags); } -#if defined(TARGET_AMD64) || defined(TARGET_ARM64) - varDsc->lvIsImplicitByRef = 0; -#elif defined(TARGET_LOONGARCH64) +#if FEATURE_IMPLICIT_BYREFS varDsc->lvIsImplicitByRef = 0; - varDsc->lvIs4Field1 = 0; - varDsc->lvIs4Field2 = 0; - varDsc->lvIsSplit = 0; -#endif // defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#endif // FEATURE_IMPLICIT_BYREFS +#ifdef TARGET_LOONGARCH64 + varDsc->lvIs4Field1 = 0; + varDsc->lvIs4Field2 = 0; + varDsc->lvIsSplit = 0; +#endif // TARGET_LOONGARCH64 // Set the lvType (before this point it is TYP_UNDEF). @@ -1832,7 +1832,7 @@ bool Compiler::StructPromotionHelper::CanPromoteStructType(CORINFO_CLASS_HANDLE const int MaxOffset = MAX_NumOfFieldsInPromotableStruct * FP_REGSIZE_BYTES; #endif // defined(TARGET_XARCH) || defined(TARGET_ARM64) #else // !FEATURE_SIMD - const int MaxOffset = MAX_NumOfFieldsInPromotableStruct * sizeof(double); + const int MaxOffset = MAX_NumOfFieldsInPromotableStruct * sizeof(double); #endif // !FEATURE_SIMD assert((BYTE)MaxOffset == MaxOffset); // because lvaStructFieldInfo.fldOffset is byte-sized @@ -2535,12 +2535,10 @@ void Compiler::StructPromotionHelper::PromoteStructVar(unsigned lclNum) compiler->compLongUsed = true; } -#if defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) - +#if FEATURE_IMPLICIT_BYREFS // Reset the implicitByRef flag. fieldVarDsc->lvIsImplicitByRef = 0; - -#endif +#endif // FEATURE_IMPLICIT_BYREFS // Do we have a parameter that can be enregistered? // @@ -2890,6 +2888,61 @@ void Compiler::lvaSetVarDoNotEnregister(unsigned varNum DEBUGARG(DoNotEnregister #endif } +//------------------------------------------------------------------------ +// lvaIsImplicitByRefLocal: Is the local an "implicit byref" parameter? +// +// We term structs passed via pointers to shadow copies "implicit byrefs". +// They are used on Windows x64 for structs 3, 5, 6, 7, > 8 bytes in size, +// and on ARM64/LoongArch64 for structs larger than 16 bytes. +// +// They are "byrefs" because the VM sometimes uses memory allocated on the +// GC heap for the shadow copies. +// +// Arguments: +// lclNum - The local in question +// +// Return Value: +// Whether "lclNum" refers to an implicit byref. +// +bool Compiler::lvaIsImplicitByRefLocal(unsigned lclNum) const +{ +#if FEATURE_IMPLICIT_BYREFS + LclVarDsc* varDsc = lvaGetDesc(lclNum); + if (varDsc->lvIsImplicitByRef) + { + assert(varDsc->lvIsParam); + + assert(varTypeIsStruct(varDsc) || (varDsc->TypeGet() == TYP_BYREF)); + return true; + } +#endif // FEATURE_IMPLICIT_BYREFS + return false; +} + +//------------------------------------------------------------------------ +// lvaIsLocalImplicitlyAccessedByRef: Will this local be accessed indirectly? +// +// Arguments: +// lclNum - The number of local in question +// +// Return Value: +// If "lclNum" is an implicit byref parameter, or its dependently promoted +// field, "true", otherwise, "false". +// +// Notes: +// This method is only meaningful before the locals have been morphed into +// explicit indirections. +// +bool Compiler::lvaIsLocalImplicitlyAccessedByRef(unsigned lclNum) const +{ + if (lvaGetDesc(lclNum)->lvIsStructField) + { + return lvaIsImplicitByRefLocal(lvaGetDesc(lclNum)->lvParentLcl); + } + + return lvaIsImplicitByRefLocal(lclNum); +} + // Returns true if this local var is a multireg struct. // TODO-Throughput: This does a lookup on the class handle, and in the outgoing arg context // this information is already available on the CallArgABIInformation, and shouldn't need to be @@ -2951,7 +3004,7 @@ void Compiler::lvaSetStruct(unsigned varNum, CORINFO_CLASS_HANDLE typeHnd, bool CorInfoType simdBaseJitType = CORINFO_TYPE_UNDEF; varDsc->lvType = impNormStructType(typeHnd, &simdBaseJitType); -#if defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#if FEATURE_IMPLICIT_BYREFS // Mark implicit byref struct parameters if (varDsc->lvIsParam && !varDsc->lvIsStructField) { @@ -2964,7 +3017,7 @@ void Compiler::lvaSetStruct(unsigned varNum, CORINFO_CLASS_HANDLE typeHnd, bool varDsc->lvIsImplicitByRef = 1; } } -#endif // defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#endif // FEATURE_IMPLICIT_BYREFS #if FEATURE_SIMD if (simdBaseJitType != CORINFO_TYPE_UNDEF) diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 1ecb8dab146b0e..d8a0fed4d1d029 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -179,16 +179,7 @@ GenTree* Compiler::fgMorphIntoHelperCall(GenTree* tree, int helper, bool morphAr // GenTree* Compiler::fgMorphExpandCast(GenTreeCast* tree) { - GenTree* oper = tree->CastOp(); - - if (fgGlobalMorph && (oper->gtOper == GT_ADDR)) - { - // Make sure we've checked if 'oper' is an address of an implicit-byref parameter. - // If it is, fgMorphImplicitByRefArgs will change its type, and we want the cast - // morphing code to see that type. - fgMorphImplicitByRefArgs(oper); - } - + GenTree* oper = tree->CastOp(); var_types srcType = genActualType(oper); var_types dstType = tree->CastToType(); unsigned dstSize = genTypeSize(dstType); @@ -4612,10 +4603,11 @@ GenTree* Compiler::fgMorphIndexAddr(GenTreeIndexAddr* indexAddr) // Likewise, allocate a temporary if the expression is a GT_LCL_FLD node. These used to be created // after fgMorphIndexAddr from GT_FIELD trees so this preserves the existing behavior. This is // perhaps a decision that should be left to CSE but FX diffs show that it is slightly better to - // do this here. + // do this here. Likewise for implicit byrefs. - if ((arrRef->gtFlags & (GTF_ASG | GTF_CALL | GTF_GLOB_REF)) || - gtComplexityExceeds(&arrRef, MAX_ARR_COMPLEXITY) || arrRef->OperIs(GT_FIELD, GT_LCL_FLD)) + if (((arrRef->gtFlags & (GTF_ASG | GTF_CALL | GTF_GLOB_REF)) != 0) || + gtComplexityExceeds(&arrRef, MAX_ARR_COMPLEXITY) || arrRef->OperIs(GT_FIELD, GT_LCL_FLD) || + (arrRef->OperIs(GT_LCL_VAR) && lvaIsLocalImplicitlyAccessedByRef(arrRef->AsLclVar()->GetLclNum()))) { unsigned arrRefTmpNum = lvaGrabTemp(true DEBUGARG("arr expr")); arrRefDefn = gtNewTempAssign(arrRefTmpNum, arrRef); @@ -4628,8 +4620,9 @@ GenTree* Compiler::fgMorphIndexAddr(GenTreeIndexAddr* indexAddr) noway_assert(arrRef2 != nullptr); } - if ((index->gtFlags & (GTF_ASG | GTF_CALL | GTF_GLOB_REF)) || gtComplexityExceeds(&index, MAX_ARR_COMPLEXITY) || - index->OperIs(GT_FIELD, GT_LCL_FLD)) + if (((index->gtFlags & (GTF_ASG | GTF_CALL | GTF_GLOB_REF)) != 0) || + gtComplexityExceeds(&index, MAX_ARR_COMPLEXITY) || index->OperIs(GT_FIELD, GT_LCL_FLD) || + (index->OperIs(GT_LCL_VAR) && lvaIsLocalImplicitlyAccessedByRef(index->AsLclVar()->GetLclNum()))) { unsigned indexTmpNum = lvaGrabTemp(true DEBUGARG("index expr")); indexDefn = gtNewTempAssign(indexTmpNum, index); @@ -4817,11 +4810,15 @@ GenTree* Compiler::fgMorphLocal(GenTreeLclVarCommon* lclNode) GenTree* expandedTree = nullptr; #ifdef TARGET_X86 expandedTree = fgMorphExpandStackArgForVarArgs(lclNode); -#endif // TARGET_X86 +#else + expandedTree = fgMorphExpandImplicitByRefArg(lclNode); +#endif if (expandedTree != nullptr) { - return fgMorphTree(expandedTree); + expandedTree = fgMorphTree(expandedTree); + DBEXEC(expandedTree == lclNode, expandedTree->gtDebugFlags &= ~GTF_DEBUG_NODE_MORPHED); + return expandedTree; } if (lclNode->OperIsLocalAddr()) @@ -4898,6 +4895,116 @@ GenTree* Compiler::fgMorphExpandStackArgForVarArgs(GenTreeLclVarCommon* lclNode) } #endif +//------------------------------------------------------------------------ +// fgMorphExpandImplicitByRefArg: Morph an implicit by-ref parameter. +// +// Arguments: +// lclNode - The local node to morph +// +// Return Value: +// The expanded tree for "lclNode", which the caller is expected to +// morph further. +// +GenTree* Compiler::fgMorphExpandImplicitByRefArg(GenTreeLclVarCommon* lclNode) +{ + if (!fgGlobalMorph) + { + return nullptr; + } + + unsigned lclNum = lclNode->GetLclNum(); + LclVarDsc* varDsc = lvaGetDesc(lclNum); + unsigned fieldOffset = 0; + unsigned newLclNum = BAD_VAR_NUM; + + if (lvaIsImplicitByRefLocal(lclNum)) + { + // The SIMD transformation to coalesce contiguous references to SIMD vector fields will re-invoke + // the traversal to mark address-taken locals. So, we may encounter a tree that has already been + // transformed to TYP_BYREF. If we do, leave it as-is. + if (lclNode->OperIs(GT_LCL_VAR) && lclNode->TypeIs(TYP_BYREF)) + { + return nullptr; + } + + if (varDsc->lvPromoted) + { + // fgRetypeImplicitByRefArgs created a new promoted struct local to represent this arg. + // Rewrite the node to refer to it. + assert(varDsc->lvFieldLclStart != 0); + + lclNode->SetLclNum(varDsc->lvFieldLclStart); + return lclNode; + } + + newLclNum = lclNum; + } + else if (varDsc->lvIsStructField && lvaIsImplicitByRefLocal(varDsc->lvParentLcl)) + { + // This was a field reference to an implicit-by-reference struct parameter that was + // dependently promoted. + newLclNum = varDsc->lvParentLcl; + fieldOffset = varDsc->lvFldOffset; + } + else + { + return nullptr; + } + + // Add a level of indirection to this node. The "base" will be a local node referring to "newLclNum". + // We will also add an offset, and, if the original "lclNode" represents a location, a dereference. + bool isAddress = lclNode->OperIsLocalAddr(); + unsigned offset = lclNode->GetLclOffs() + fieldOffset; + var_types argNodeType = lclNode->TypeGet(); + ClassLayout* argNodeLayout = nullptr; + if (varTypeIsStruct(argNodeType)) + { + argNodeLayout = lclNode->GetLayout(this); + } + + JITDUMP("\nRewriting an implicit by-ref parameter %s:\n", isAddress ? "address" : "reference"); + DISPTREE(lclNode); + + lclNode->ChangeType(TYP_BYREF); + lclNode->ChangeOper(GT_LCL_VAR); + lclNode->SetLclNum(newLclNum); + lclNode->SetAllEffectsFlags(GTF_EMPTY); // Implicit by-ref parameters cannot be address-exposed. + + GenTree* addrNode = lclNode; + if (offset != 0) + { + addrNode = gtNewOperNode(GT_ADD, TYP_BYREF, addrNode, gtNewIconNode(offset, TYP_I_IMPL)); + } + + GenTree* newArgNode; + if (!isAddress) + { + if (varTypeIsStruct(argNodeType)) + { + newArgNode = gtNewObjNode(argNodeLayout, addrNode); + } + else + { + newArgNode = gtNewIndir(argNodeType, addrNode); + } + + // Currently, we have to conservatively treat all indirections off of implicit byrefs as + // global. This is because we lose the information on whether the original local's address + // was exposed when we retype it in "fgRetypeImplicitByRefArgs". + newArgNode->gtFlags |= GTF_GLOB_REF; + } + else + { + newArgNode = addrNode; + } + + JITDUMP("Transformed into:\n"); + DISPTREE(newArgNode); + JITDUMP("\n"); + + return newArgNode; +} + /***************************************************************************** * * Transform the given GT_LCL_VAR tree for code generation. @@ -5006,21 +5113,12 @@ GenTree* Compiler::fgMorphField(GenTree* tree, MorphAddrContext* mac) CORINFO_FIELD_HANDLE symHnd = tree->AsField()->gtFldHnd; unsigned fldOffset = tree->AsField()->gtFldOffset; GenTree* objRef = tree->AsField()->GetFldObj(); - bool objIsLocal = false; bool fldMayOverlap = tree->AsField()->gtFldMayOverlap; FieldSeqNode* fieldSeq = FieldSeqStore::NotAField(); // Reset the flag because we may reuse the node. tree->AsField()->gtFldMayOverlap = false; - if (fgGlobalMorph && (objRef != nullptr) && (objRef->gtOper == GT_ADDR)) - { - // Make sure we've checked if 'objRef' is an address of an implicit-byref parameter. - // If it is, fgMorphImplicitByRefArgs may change it do a different opcode, which the - // simd field rewrites are sensitive to. - fgMorphImplicitByRefArgs(objRef); - } - noway_assert(((objRef != nullptr) && (objRef->IsLocalAddrExpr() != nullptr)) || ((tree->gtFlags & GTF_GLOB_REF) != 0)); @@ -5052,13 +5150,9 @@ GenTree* Compiler::fgMorphField(GenTree* tree, MorphAddrContext* mac) // before it is used. MorphAddrContext defMAC(MACK_Ind); - /* Is this an instance data member? */ - - if (objRef) + // Is this an instance data member? + if (objRef != nullptr) { - GenTree* addr; - objIsLocal = objRef->IsLocal(); - if (tree->gtFlags & GTF_IND_TLS_REF) { NO_WAY("instance field can not be a TLS ref."); @@ -5137,8 +5231,8 @@ GenTree* Compiler::fgMorphField(GenTree* tree, MorphAddrContext* mac) */ var_types objRefType = objRef->TypeGet(); - - GenTree* comma = nullptr; + GenTree* addr = nullptr; + GenTree* comma = nullptr; // NULL mac means we encounter the GT_FIELD first. This denotes a dereference of the field, // and thus is equivalent to a MACK_Ind with zero offset. @@ -5213,11 +5307,10 @@ GenTree* Compiler::fgMorphField(GenTree* tree, MorphAddrContext* mac) // Create the "comma" subtree // GenTree* asg = nullptr; - GenTree* nullchk; unsigned lclNum; - if (objRef->gtOper != GT_LCL_VAR) + if (!objRef->OperIs(GT_LCL_VAR) || lvaIsLocalImplicitlyAccessedByRef(objRef->AsLclVar()->GetLclNum())) { lclNum = fgGetBigOffsetMorphingTemp(genActualType(objRef->TypeGet())); @@ -5229,17 +5322,13 @@ GenTree* Compiler::fgMorphField(GenTree* tree, MorphAddrContext* mac) lclNum = objRef->AsLclVarCommon()->GetLclNum(); } - GenTree* lclVar = gtNewLclvNode(lclNum, objRefType); - nullchk = gtNewNullCheck(lclVar, compCurBB); + GenTree* lclVar = gtNewLclvNode(lclNum, objRefType); + GenTree* nullchk = gtNewNullCheck(lclVar, compCurBB); - if (asg) + if (asg != nullptr) { // Create the "comma" node. - comma = gtNewOperNode(GT_COMMA, - TYP_VOID, // We don't want to return anything from this "comma" node. - // Set the type to TYP_VOID, so we can select "cmp" instruction - // instead of "mov" instruction later on. - asg, nullchk); + comma = gtNewOperNode(GT_COMMA, TYP_VOID, asg, nullchk); } else { @@ -9931,18 +10020,6 @@ GenTree* Compiler::fgMorphFieldAssignToSimdSetElement(GenTree* tree) tree->AsOp()->gtOp1 = target; tree->AsOp()->gtOp2 = simdTree; - // fgMorphTree has already called fgMorphImplicitByRefArgs() on this assignment, but the source - // and target have not yet been morphed. - // Therefore, in case the source and/or target are now implicit byrefs, we need to call it again. - if (fgMorphImplicitByRefArgs(tree)) - { - if (tree->gtGetOp1()->OperIsBlk()) - { - assert(tree->gtGetOp1()->TypeGet() == simdType); - tree->gtGetOp1()->SetOper(GT_IND); - tree->gtGetOp1()->gtType = simdType; - } - } #ifdef DEBUG tree->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED; #endif @@ -13211,41 +13288,19 @@ GenTree* Compiler::fgMorphRetInd(GenTreeUnOp* ret) if (addr->OperIs(GT_ADDR) && addr->gtGetOp1()->OperIs(GT_LCL_VAR)) { - // If struct promotion was undone, adjust the annotations - if (fgGlobalMorph && fgMorphImplicitByRefArgs(addr)) - { - return ind; - } - // If `return` retypes LCL_VAR as a smaller struct it should not set `doNotEnregister` on that // LclVar. // Example: in `Vector128:AsVector2` we have RETURN SIMD8(OBJ SIMD8(ADDR byref(LCL_VAR SIMD16))). GenTreeLclVar* lclVar = addr->gtGetOp1()->AsLclVar(); + if (!lvaIsImplicitByRefLocal(lclVar->GetLclNum())) { assert(!gtIsActiveCSE_Candidate(addr) && !gtIsActiveCSE_Candidate(ind)); - unsigned indSize; - if (ind->OperIs(GT_IND)) - { - indSize = genTypeSize(ind); - } - else - { - indSize = ind->AsBlk()->GetLayout()->GetSize(); - } - - LclVarDsc* varDsc = lvaGetDesc(lclVar); - unsigned lclVarSize; - if (!lclVar->TypeIs(TYP_STRUCT)) + LclVarDsc* varDsc = lvaGetDesc(lclVar); + unsigned indSize = ind->Size(); + unsigned lclVarSize = lvaLclExactSize(lclVar->GetLclNum()); - { - lclVarSize = genTypeSize(varDsc->TypeGet()); - } - else - { - lclVarSize = varDsc->lvExactSize; - } // TODO: change conditions in `canFold` to `indSize <= lclVarSize`, but currently do not support `BITCAST // int<-SIMD16` etc. assert((indSize <= lclVarSize) || varDsc->lvDoNotEnregister); @@ -13280,6 +13335,7 @@ GenTree* Compiler::fgMorphRetInd(GenTreeUnOp* ret) } } } + return ind; } @@ -14183,23 +14239,6 @@ GenTree* Compiler::fgMorphTree(GenTree* tree, MorphAddrContext* mac) } #endif - if (fgGlobalMorph) - { - // Apply any rewrites for implicit byref arguments before morphing the - // tree. - - if (fgMorphImplicitByRefArgs(tree)) - { -#ifdef DEBUG - if (verbose && treesBeforeAfterMorph) - { - printf("\nfgMorphTree (%d), after implicit-byref rewrite:\n", thisMorphNum); - gtDispTree(tree); - } -#endif - } - } - /*------------------------------------------------------------------------- * fgMorphTree() can potentially replace a tree with another, and the * caller has to store the return value correctly. @@ -16621,7 +16660,7 @@ void Compiler::fgMorphLocalField(GenTree* tree, GenTree* parent) void Compiler::fgResetImplicitByRefRefCount() { -#if (defined(TARGET_AMD64) && !defined(UNIX_AMD64_ABI)) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#if FEATURE_IMPLICIT_BYREFS #ifdef DEBUG if (verbose) { @@ -16644,7 +16683,7 @@ void Compiler::fgResetImplicitByRefRefCount() } } -#endif // (TARGET_AMD64 && !UNIX_AMD64_ABI) || TARGET_ARM64 || TARGET_LOONGARCH64 +#endif // FEATURE_IMPLICIT_BYREFS } //------------------------------------------------------------------------ @@ -16653,12 +16692,12 @@ void Compiler::fgResetImplicitByRefRefCount() // which struct promotions of implicit byrefs to keep or discard. // For those which are kept, insert the appropriate initialization code. // For those which are to be discarded, annotate the promoted field locals -// so that fgMorphImplicitByRefArgs will know to rewrite their appearances -// using indirections off the pointer parameters. - +// so that fgMorphExpandImplicitByRefArg will know to rewrite their +// appearances using indirections off the pointer parameters. +// void Compiler::fgRetypeImplicitByRefArgs() { -#if (defined(TARGET_AMD64) && !defined(UNIX_AMD64_ABI)) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#if FEATURE_IMPLICIT_BYREFS #ifdef DEBUG if (verbose) { @@ -16779,7 +16818,7 @@ void Compiler::fgRetypeImplicitByRefArgs() if (undoPromotion) { - // Leave lvParentLcl pointing to the parameter so that fgMorphImplicitByRefArgs + // Leave lvParentLcl pointing to the parameter so that fgMorphExpandImplicitByRefArg // will know to rewrite appearances of this local. assert(fieldVarDsc->lvParentLcl == lclNum); } @@ -16816,7 +16855,7 @@ void Compiler::fgRetypeImplicitByRefArgs() // have these fields. varDsc->lvFieldCnt = 0; - // Hijack lvPromoted to communicate to fgMorphImplicitByRefArgs + // Hijack lvPromoted to communicate to fgMorphExpandImplicitByRefArg // whether references to the struct should be rewritten as // indirections off the pointer (not promoted) or references // to the new struct local (promoted). @@ -16828,10 +16867,10 @@ void Compiler::fgRetypeImplicitByRefArgs() // promotion wanted to promote but that aren't considered profitable to // rewrite. It hijacks lvFieldLclStart to communicate to // fgMarkDemotedImplicitByRefArgs that it needs to clean up annotations left - // on such args for fgMorphImplicitByRefArgs to consult in the interim. + // on such args for fgMorphExpandImplicitByRefArg to consult in the interim. // Here we have an arg that was simply never promoted, so make sure it doesn't - // have nonzero lvFieldLclStart, since that would confuse fgMorphImplicitByRefArgs - // and fgMarkDemotedImplicitByRefArgs. + // have nonzero lvFieldLclStart, since that would confuse the aforementioned + // functions. assert(varDsc->lvFieldLclStart == 0); } @@ -16864,20 +16903,21 @@ void Compiler::fgRetypeImplicitByRefArgs() } } -#endif // (TARGET_AMD64 && !UNIX_AMD64_ABI) || TARGET_ARM64 || TARGET_LOONGARCH64 +#endif // FEATURE_IMPLICIT_BYREFS } //------------------------------------------------------------------------ // fgMarkDemotedImplicitByRefArgs: Clear annotations for any implicit byrefs that struct promotion // asked to promote. Appearances of these have now been rewritten -// (by fgMorphImplicitByRefArgs) using indirections from the pointer -// parameter or references to the promotion temp, as appropriate. - +// (by fgMorphExpandImplicitByRefArg) using indirections from +// the pointer parameter or references to the promotion temp, as +// appropriate. +// void Compiler::fgMarkDemotedImplicitByRefArgs() { JITDUMP("\n*************** In fgMarkDemotedImplicitByRefArgs()\n"); -#if (defined(TARGET_AMD64) && !defined(UNIX_AMD64_ABI)) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#if FEATURE_IMPLICIT_BYREFS for (unsigned lclNum = 0; lclNum < info.compArgsCount; lclNum++) { @@ -16889,13 +16929,13 @@ void Compiler::fgMarkDemotedImplicitByRefArgs() if (varDsc->lvPromoted) { - // The parameter is simply a pointer now, so clear lvPromoted. It was left set - // by fgRetypeImplicitByRefArgs to communicate to fgMorphImplicitByRefArgs that + // The parameter is simply a pointer now, so clear lvPromoted. It was left set by + // fgRetypeImplicitByRefArgs to communicate to fgMorphExpandImplicitByRefArg that // appearances of this arg needed to be rewritten to a new promoted struct local. varDsc->lvPromoted = false; // Clear the lvFieldLclStart value that was set by fgRetypeImplicitByRefArgs - // to tell fgMorphImplicitByRefArgs which local is the new promoted struct one. + // to tell fgMorphExpandImplicitByRefArg which local is the new promoted struct one. varDsc->lvFieldLclStart = 0; } else if (varDsc->lvFieldLclStart != 0) @@ -16938,181 +16978,7 @@ void Compiler::fgMarkDemotedImplicitByRefArgs() } } -#endif // (TARGET_AMD64 && !UNIX_AMD64_ABI) || TARGET_ARM64 || TARGET_LOONGARCH64 -} - -/***************************************************************************** - * - * Morph irregular parameters - * for x64 and ARM64 this means turning them into byrefs, adding extra indirs. - */ -bool Compiler::fgMorphImplicitByRefArgs(GenTree* tree) -{ -#if (!defined(TARGET_AMD64) || defined(UNIX_AMD64_ABI)) && !defined(TARGET_ARM64) && !defined(TARGET_LOONGARCH64) - - return false; - -#else // (TARGET_AMD64 && !UNIX_AMD64_ABI) || TARGET_ARM64 || TARGET_LOONGARCH64 - - bool changed = false; - - // Implicit byref morphing needs to know if the reference to the parameter is a - // child of GT_ADDR or not, so this method looks one level down and does the - // rewrite whenever a child is a reference to an implicit byref parameter. - if (tree->gtOper == GT_ADDR) - { - if (tree->AsOp()->gtOp1->gtOper == GT_LCL_VAR) - { - GenTree* morphedTree = fgMorphImplicitByRefArgs(tree, true); - changed = (morphedTree != nullptr); - assert(!changed || (morphedTree == tree)); - } - } - else - { - for (GenTree** pTree : tree->UseEdges()) - { - GenTree** pTreeCopy = pTree; - GenTree* childTree = *pTree; - if (childTree->gtOper == GT_LCL_VAR) - { - GenTree* newChildTree = fgMorphImplicitByRefArgs(childTree, false); - if (newChildTree != nullptr) - { - changed = true; - *pTreeCopy = newChildTree; - } - } - } - } - - return changed; -#endif // (TARGET_AMD64 && !UNIX_AMD64_ABI) || TARGET_ARM64 || TARGET_LOONGARCH64 -} - -GenTree* Compiler::fgMorphImplicitByRefArgs(GenTree* tree, bool isAddr) -{ - assert((tree->gtOper == GT_LCL_VAR) || ((tree->gtOper == GT_ADDR) && (tree->AsOp()->gtOp1->gtOper == GT_LCL_VAR))); - assert(isAddr == (tree->gtOper == GT_ADDR)); - - GenTree* lclVarTree = isAddr ? tree->AsOp()->gtOp1 : tree; - unsigned lclNum = lclVarTree->AsLclVarCommon()->GetLclNum(); - LclVarDsc* lclVarDsc = lvaGetDesc(lclNum); - - CORINFO_FIELD_HANDLE fieldHnd; - unsigned fieldOffset = 0; - var_types fieldRefType = TYP_UNKNOWN; - - if (lvaIsImplicitByRefLocal(lclNum)) - { - // The SIMD transformation to coalesce contiguous references to SIMD vector fields will - // re-invoke the traversal to mark address-taken locals. - // So, we may encounter a tree that has already been transformed to TYP_BYREF. - // If we do, leave it as-is. - if (!varTypeIsStruct(lclVarTree)) - { - assert(lclVarTree->TypeGet() == TYP_BYREF); - - return nullptr; - } - else if (lclVarDsc->lvPromoted) - { - // fgRetypeImplicitByRefArgs created a new promoted struct local to represent this - // arg. Rewrite this to refer to the new local. - assert(lclVarDsc->lvFieldLclStart != 0); - lclVarTree->AsLclVarCommon()->SetLclNum(lclVarDsc->lvFieldLclStart); - return tree; - } - - fieldHnd = nullptr; - } - else if (lclVarDsc->lvIsStructField && lvaIsImplicitByRefLocal(lclVarDsc->lvParentLcl)) - { - // This was a field reference to an implicit-by-reference struct parameter that was - // dependently promoted; update it to a field reference off the pointer. - // Grab the field handle from the struct field lclVar. - fieldHnd = lclVarDsc->lvFieldHnd; - fieldOffset = lclVarDsc->lvFldOffset; - assert(fieldHnd != nullptr); - // Update lclNum/lclVarDsc to refer to the parameter - lclNum = lclVarDsc->lvParentLcl; - lclVarDsc = lvaGetDesc(lclNum); - fieldRefType = lclVarTree->TypeGet(); - } - else - { - // We only need to tranform the 'marked' implicit by ref parameters - return nullptr; - } - - // This is no longer a def of the lclVar, even if it WAS a def of the struct. - lclVarTree->gtFlags &= ~(GTF_LIVENESS_MASK); - - if (isAddr) - { - if (fieldHnd == nullptr) - { - // change &X into just plain X - tree->ReplaceWith(lclVarTree, this); - tree->gtType = TYP_BYREF; - } - else - { - // change &(X.f) [i.e. GT_ADDR of local for promoted arg field] - // into &(X, f) [i.e. GT_ADDR of GT_FIELD off ptr param] - lclVarTree->AsLclVarCommon()->SetLclNum(lclNum); - lclVarTree->gtType = TYP_BYREF; - tree->AsOp()->gtOp1 = gtNewFieldRef(fieldRefType, fieldHnd, lclVarTree, fieldOffset); - } - -#ifdef DEBUG - if (verbose) - { - printf("Replacing address of implicit by ref struct parameter with byref:\n"); - } -#endif // DEBUG - } - else - { - // Change X into OBJ(X) or FIELD(X, f) - var_types structType = tree->gtType; - tree->gtType = TYP_BYREF; - - if (fieldHnd) - { - tree->AsLclVarCommon()->SetLclNum(lclNum); - tree = gtNewFieldRef(fieldRefType, fieldHnd, tree, fieldOffset); - } - else - { - tree = gtNewObjNode(lclVarDsc->GetStructHnd(), tree); - - if (structType == TYP_STRUCT) - { - gtSetObjGcInfo(tree->AsObj()); - } - } - - // TODO-CQ: If the VM ever stops violating the ABI and passing heap references - // we could apply TGT_NOT_HEAP here. - tree->gtFlags = (tree->gtFlags & GTF_COMMON_MASK); - -#ifdef DEBUG - if (verbose) - { - printf("Replacing value of implicit by ref struct parameter with indir of parameter:\n"); - } -#endif // DEBUG - } - -#ifdef DEBUG - if (verbose) - { - gtDispTree(tree); - } -#endif // DEBUG - - return tree; +#endif // FEATURE_IMPLICIT_BYREFS } //------------------------------------------------------------------------ diff --git a/src/coreclr/jit/scopeinfo.cpp b/src/coreclr/jit/scopeinfo.cpp index 6b2fcd5690eb6e..b349d5e7aae64e 100644 --- a/src/coreclr/jit/scopeinfo.cpp +++ b/src/coreclr/jit/scopeinfo.cpp @@ -295,7 +295,7 @@ void CodeGenInterface::siVarLoc::siFillStackVarLoc( case TYP_LONG: case TYP_DOUBLE: #endif // TARGET_64BIT -#if defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#if FEATURE_IMPLICIT_BYREFS // In the AMD64 ABI we are supposed to pass a struct by reference when its // size is not 1, 2, 4 or 8 bytes in size. During fgMorph, the compiler modifies // the IR to comply with the ABI and therefore changes the type of the lclVar @@ -314,7 +314,7 @@ void CodeGenInterface::siVarLoc::siFillStackVarLoc( this->vlType = VLT_STK_BYREF; } else -#endif // defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#endif // FEATURE_IMPLICIT_BYREFS { this->vlType = VLT_STK; } diff --git a/src/coreclr/jit/targetamd64.h b/src/coreclr/jit/targetamd64.h index ee2868fef42388..645d1933e3c5a4 100644 --- a/src/coreclr/jit/targetamd64.h +++ b/src/coreclr/jit/targetamd64.h @@ -34,6 +34,7 @@ #define FEATURE_SET_FLAGS 0 // Set to true to force the JIT to mark the trees with GTF_SET_FLAGS when the flags need to be set #define MAX_PASS_SINGLEREG_BYTES 8 // Maximum size of a struct passed in a single register (double). #ifdef UNIX_AMD64_ABI + #define FEATURE_IMPLICIT_BYREFS 0 // Support for struct parameters passed via pointers to shadow copies #define FEATURE_MULTIREG_ARGS_OR_RET 1 // Support for passing and/or returning single values in more than one register #define FEATURE_MULTIREG_ARGS 1 // Support for passing a single argument in more than one register #define FEATURE_MULTIREG_RET 1 // Support for returning a single value in more than one register @@ -48,6 +49,7 @@ // This is also the maximum number of registers for a MultiReg node. #else // !UNIX_AMD64_ABI #define WINDOWS_AMD64_ABI // Uses the Windows ABI for AMD64 + #define FEATURE_IMPLICIT_BYREFS 1 // Support for struct parameters passed via pointers to shadow copies #define FEATURE_MULTIREG_ARGS_OR_RET 0 // Support for passing and/or returning single values in more than one register #define FEATURE_MULTIREG_ARGS 0 // Support for passing a single argument in more than one register #define FEATURE_MULTIREG_RET 0 // Support for returning a single value in more than one register diff --git a/src/coreclr/jit/targetarm.h b/src/coreclr/jit/targetarm.h index 8e93c1be084409..3e43eaa587141c 100644 --- a/src/coreclr/jit/targetarm.h +++ b/src/coreclr/jit/targetarm.h @@ -23,6 +23,7 @@ #define FEATURE_FASTTAILCALL 1 // Tail calls made as epilog+jmp #define FEATURE_TAILCALL_OPT 1 // opportunistic Tail calls (i.e. without ".tail" prefix) made as fast tail calls. #define FEATURE_SET_FLAGS 1 // Set to true to force the JIT to mark the trees with GTF_SET_FLAGS when the flags need to be set + #define FEATURE_IMPLICIT_BYREFS 0 // Support for struct parameters passed via pointers to shadow copies #define FEATURE_MULTIREG_ARGS_OR_RET 1 // Support for passing and/or returning single values in more than one register (including HFA support) #define FEATURE_MULTIREG_ARGS 1 // Support for passing a single argument in more than one register (including passing HFAs) #define FEATURE_MULTIREG_RET 1 // Support for returning a single value in more than one register (including HFA returns) diff --git a/src/coreclr/jit/targetarm64.h b/src/coreclr/jit/targetarm64.h index dbfd813ac090c6..c9a1610aab2c5c 100644 --- a/src/coreclr/jit/targetarm64.h +++ b/src/coreclr/jit/targetarm64.h @@ -28,6 +28,7 @@ #define FEATURE_FASTTAILCALL 1 // Tail calls made as epilog+jmp #define FEATURE_TAILCALL_OPT 1 // opportunistic Tail calls (i.e. without ".tail" prefix) made as fast tail calls. #define FEATURE_SET_FLAGS 0 // Set to true to force the JIT to mark the trees with GTF_SET_FLAGS when the flags need to be set + #define FEATURE_IMPLICIT_BYREFS 1 // Support for struct parameters passed via pointers to shadow copies #define FEATURE_MULTIREG_ARGS_OR_RET 1 // Support for passing and/or returning single values in more than one register #define FEATURE_MULTIREG_ARGS 1 // Support for passing a single argument in more than one register #define FEATURE_MULTIREG_RET 1 // Support for returning a single value in more than one register diff --git a/src/coreclr/jit/targetloongarch64.h b/src/coreclr/jit/targetloongarch64.h index f704b4b256afbf..4190420dc5b691 100644 --- a/src/coreclr/jit/targetloongarch64.h +++ b/src/coreclr/jit/targetloongarch64.h @@ -31,6 +31,7 @@ #define FEATURE_FASTTAILCALL 1 // Tail calls made as epilog+jmp #define FEATURE_TAILCALL_OPT 1 // opportunistic Tail calls (i.e. without ".tail" prefix) made as fast tail calls. #define FEATURE_SET_FLAGS 0 // Set to true to force the JIT to mark the trees with GTF_SET_FLAGS when the flags need to be set + #define FEATURE_IMPLICIT_BYREFS 1 // Support for struct parameters passed via pointers to shadow copies #define FEATURE_MULTIREG_ARGS_OR_RET 1 // Support for passing and/or returning single values in more than one register #define FEATURE_MULTIREG_ARGS 1 // Support for passing a single argument in more than one register #define FEATURE_MULTIREG_RET 1 // Support for returning a single value in more than one register diff --git a/src/coreclr/jit/targetx86.h b/src/coreclr/jit/targetx86.h index 044b9f201d5e32..727275654930f1 100644 --- a/src/coreclr/jit/targetx86.h +++ b/src/coreclr/jit/targetx86.h @@ -30,6 +30,7 @@ #define FEATURE_TAILCALL_OPT 0 // opportunistic Tail calls (without ".tail" prefix) made as fast tail calls. #define FEATURE_SET_FLAGS 0 // Set to true to force the JIT to mark the trees with GTF_SET_FLAGS when // the flags need to be set + #define FEATURE_IMPLICIT_BYREFS 0 // Support for struct parameters passed via pointers to shadow copies #define FEATURE_MULTIREG_ARGS_OR_RET 1 // Support for passing and/or returning single values in more than one register #define FEATURE_MULTIREG_ARGS 0 // Support for passing a single argument in more than one register #define FEATURE_MULTIREG_RET 1 // Support for returning a single value in more than one register diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 802115117e706e..295d3339dfe206 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -8192,9 +8192,6 @@ void Compiler::fgValueNumberAssignment(GenTreeOp* tree) break; case GT_OBJ: - noway_assert(!"GT_OBJ can not be LHS when (tree->TypeGet() != TYP_STRUCT)!"); - break; - case GT_BLK: case GT_IND: { From 4501e3903cbb04138bb85b4910993c1b660e3f36 Mon Sep 17 00:00:00 2001 From: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> Date: Wed, 15 Jun 2022 03:41:43 +0300 Subject: [PATCH 121/337] Do not change `gtRetClsHnd` in `impNormStructVal` (#70699) * Do not change "gtRetClsHdl" in "impNormStructVal" Doing so leads breaking the proper ABI handling for the call. * Add a test --- src/coreclr/jit/importer.cpp | 14 ++------- .../Directed/StructABI/TypeMismatchedArgs.cs | 31 +++++++++++++++++++ 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 0a774bdfcc7b70..64be5105099f8f 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -1723,21 +1723,14 @@ GenTree* Compiler::impNormStructVal(GenTree* structVal, genTreeOps oper = structVal->OperGet(); switch (oper) { - // GT_RETURN and GT_MKREFANY don't capture the handle. - case GT_RETURN: - break; + // GT_MKREFANY is supported directly by args morphing. case GT_MKREFANY: alreadyNormalized = true; break; case GT_CALL: - structVal->AsCall()->gtRetClsHnd = structHnd; - makeTemp = true; - break; - case GT_RET_EXPR: - structVal->AsRetExpr()->gtRetClsHnd = structHnd; - makeTemp = true; + makeTemp = true; break; case GT_FIELD: @@ -1758,7 +1751,6 @@ GenTree* Compiler::impNormStructVal(GenTree* structVal, case GT_OBJ: case GT_BLK: - case GT_ASG: // These should already have the appropriate type. assert(structVal->gtType == structType); alreadyNormalized = true; @@ -1771,10 +1763,8 @@ GenTree* Compiler::impNormStructVal(GenTree* structVal, break; case GT_CNS_VEC: - { assert(varTypeIsSIMD(structVal) && (structVal->gtType == structType)); break; - } #ifdef FEATURE_SIMD case GT_SIMD: diff --git a/src/tests/JIT/Directed/StructABI/TypeMismatchedArgs.cs b/src/tests/JIT/Directed/StructABI/TypeMismatchedArgs.cs index eb31300a4c320f..c450040daace48 100644 --- a/src/tests/JIT/Directed/StructABI/TypeMismatchedArgs.cs +++ b/src/tests/JIT/Directed/StructABI/TypeMismatchedArgs.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.Numerics; +using System.Runtime.Intrinsics; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; @@ -10,6 +12,7 @@ public unsafe class TypeMismatchedArgs private static readonly HfaUnion s_hfaDblFlt = new HfaUnion { DblHfa = { FirstDblValue = 1.0, SecondDblValue = 2.0 } }; private static readonly HfaDblLngUnion s_dblLngHfa = new HfaDblLngUnion { DblLng = { FirstLngValue = 10, SecondLngValue = 20 } }; private static readonly FourDblLngUnion s_fourDblLngHfa = new FourDblLngUnion { Lngs = { LongOne = 30 } }; + private static readonly Vtor128Union s_vtor128 = new Vtor128Union { Vtor4 = new Vector4(4, 3, 2, 1) }; public static int Main() { @@ -33,6 +36,11 @@ public static int Main() return 104; } + if (ProblemWithVectorCallArg()) + { + return 105; + } + return 100; } @@ -70,6 +78,20 @@ private static bool ProblemWithSplitStructHfaMismatch(FourDoublesHfaStruct fourD return result != s_fourDblLngHfa.Lngs.LongOne; } + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool ProblemWithVectorCallArg() + { + var result = CallForVector4(GetVector128().AsVector4()); + + return result != s_vtor128.Vtor4.X; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static float CallForVector4(Vector4 value) => value.X; + + [MethodImpl(MethodImplOptions.NoInlining)] + private static Vector128 GetVector128() => s_vtor128.Vtor128; + [MethodImpl(MethodImplOptions.NoInlining)] private static double CallForHfaDblStruct(HfaDblStruct value) => value.FirstDblValue; @@ -77,6 +99,15 @@ private static bool ProblemWithSplitStructHfaMismatch(FourDoublesHfaStruct fourD private static long CallForSplitStructWithFourLongs(int arg0, int arg1, StructWithFourLongs splitArg) => splitArg.LongOne; } +[StructLayout(LayoutKind.Explicit)] +struct Vtor128Union +{ + [FieldOffset(0)] + public Vector4 Vtor4; + [FieldOffset(0)] + public Vector128 Vtor128; +} + [StructLayout(LayoutKind.Explicit)] struct HfaDblLngUnion { From 010eb6314f2dc16b3194859a6ca044fb0f9fa79a Mon Sep 17 00:00:00 2001 From: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> Date: Wed, 15 Jun 2022 04:11:57 +0300 Subject: [PATCH 122/337] Support `PUTARG_STK(STRUCT LCL_VAR/LCL_FLD)` on ARM/64 (#70256) * Separate out LowerPutArgStk Call it from "LowerArg" instead of "ContainCheckCallOperands", as it does more than just containment analysis. * Support "PUTARG_STK(STRUCT LCL_VAR/LCL_FLD)" on ARM/64 To test this, transform "OBJ(LCL_VAR|FLD_ADDR)" to "LCL_FLD" on lowering. This additionally simplified the codegen code as it doesn't have to support two representations of the same thing. --- src/coreclr/jit/codegenarmarch.cpp | 172 ++++++++------------------- src/coreclr/jit/lower.cpp | 43 +++---- src/coreclr/jit/lowerarmarch.cpp | 38 ++++++ src/coreclr/jit/lowerloongarch64.cpp | 24 ++++ src/coreclr/jit/lowerxarch.cpp | 21 +--- src/coreclr/jit/lsraarmarch.cpp | 44 +++---- 6 files changed, 146 insertions(+), 196 deletions(-) diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index bbaba6051a0f33..c01127ed79d514 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -770,9 +770,7 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode) GenTree* source = treeNode->gtGetOp1(); - bool isStruct = source->TypeIs(TYP_STRUCT) || (source->OperGet() == GT_FIELD_LIST); - - if (!isStruct) // a normal non-Struct argument + if (!source->TypeIs(TYP_STRUCT)) // a normal non-Struct argument { if (varTypeIsSIMD(source->TypeGet())) { @@ -864,9 +862,9 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode) { genPutArgStkFieldList(treeNode, varNumOut); } - else // We must have a GT_OBJ or a GT_LCL_VAR + else { - noway_assert(source->OperIs(GT_LCL_VAR, GT_OBJ)); + noway_assert(source->OperIsLocalRead() || source->OperIs(GT_OBJ)); var_types targetType = source->TypeGet(); noway_assert(varTypeIsStruct(targetType)); @@ -879,96 +877,42 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode) #ifdef TARGET_ARM64 regNumber hiReg = treeNode->GetSingleTempReg(); #endif // TARGET_ARM64 - regNumber addrReg = REG_NA; - GenTreeLclVarCommon* varNode = nullptr; - GenTree* addrNode = nullptr; + GenTreeLclVarCommon* srcLclNode = nullptr; + regNumber addrReg = REG_NA; + ClassLayout* layout = nullptr; - if (source->OperGet() == GT_LCL_VAR) + // Setup "layout", "srcLclNode" and "addrReg". + if (source->OperIsLocalRead()) { - varNode = source->AsLclVarCommon(); + srcLclNode = source->AsLclVarCommon(); + layout = srcLclNode->GetLayout(compiler); + LclVarDsc* varDsc = compiler->lvaGetDesc(srcLclNode); + + // This struct must live on the stack frame. + assert(varDsc->lvOnFrame && !varDsc->lvRegister); } else // we must have a GT_OBJ { - assert(source->OperGet() == GT_OBJ); - - addrNode = source->AsOp()->gtOp1; + layout = source->AsObj()->GetLayout(); + addrReg = genConsumeReg(source->AsObj()->Addr()); - // addrNode can either be a GT_LCL_VAR_ADDR or an address expression - // - if (addrNode->OperGet() == GT_LCL_VAR_ADDR) +#ifdef TARGET_ARM64 + // If addrReg equal to loReg, swap(loReg, hiReg) + // This reduces code complexity by only supporting one addrReg overwrite case + if (loReg == addrReg) { - // We have a GT_OBJ(GT_LCL_VAR_ADDR) - // - // We will treat this case the same as above - // (i.e if we just had this GT_LCL_VAR directly as the source) - // so update 'source' to point this GT_LCL_VAR_ADDR node - // and continue to the codegen for the LCL_VAR node below - // - assert(addrNode->isContained()); - varNode = addrNode->AsLclVarCommon(); - addrNode = nullptr; + loReg = hiReg; + hiReg = addrReg; } - else // addrNode is used - { - // TODO-Cleanup: `Lowering::NewPutArg` marks only `LCL_VAR_ADDR` as contained nowadays, - // but we use `genConsumeAddress` as a precaution, use `genConsumeReg()` instead. - assert(!addrNode->isContained()); - // Generate code to load the address that we need into a register - genConsumeAddress(addrNode); - addrReg = addrNode->GetRegNum(); - -#ifdef TARGET_ARM64 - // If addrReg equal to loReg, swap(loReg, hiReg) - // This reduces code complexity by only supporting one addrReg overwrite case - if (loReg == addrReg) - { - loReg = hiReg; - hiReg = addrReg; - } #endif // TARGET_ARM64 - } - } - - // Either varNode or addrNOde must have been setup above, - // the xor ensures that only one of the two is setup, not both - assert((varNode != nullptr) ^ (addrNode != nullptr)); - - ClassLayout* layout; - unsigned srcSize; - bool isHfa; - - // Setup the srcSize, isHFa, and gcPtrCount - if (source->OperGet() == GT_LCL_VAR) - { - assert(varNode != nullptr); - LclVarDsc* varDsc = compiler->lvaGetDesc(varNode); - - // This struct also must live in the stack frame - // And it can't live in a register (SIMD) - assert(varDsc->lvType == TYP_STRUCT); - assert(varDsc->lvOnFrame && !varDsc->lvRegister); - - srcSize = varDsc->lvSize(); - isHfa = varDsc->lvIsHfa(); - layout = varDsc->GetLayout(); } - else // we must have a GT_OBJ - { - assert(source->OperGet() == GT_OBJ); - // If the source is an OBJ node then we need to use the type information - // it provides (size and GC layout) even if the node wraps a lclvar. Due - // to struct reinterpretation (e.g. Unsafe.As) it is possible that - // the OBJ node has a different type than the lclvar. - layout = source->AsObj()->GetLayout(); - srcSize = layout->GetSize(); - isHfa = compiler->IsHfa(layout->GetClassHandle()); - } + unsigned srcSize = layout->GetSize(); // If we have an HFA we can't have any GC pointers, // if not then the max size for the struct is 16 bytes - if (isHfa) + if (compiler->IsHfa(layout->GetClassHandle())) { noway_assert(!layout->HasGCPtr()); } @@ -981,45 +925,32 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode) noway_assert(srcSize <= MAX_PASS_MULTIREG_BYTES); #endif // TARGET_ARM64 - unsigned structSize; - unsigned dstSize = treeNode->GetStackByteSize(); - if (dstSize != srcSize) + + // We can generate smaller code if store size is a multiple of TARGET_POINTER_SIZE. + // The dst size can be rounded up to PUTARG_STK size. The src size can be rounded up + // if it reads a local variable because reading "too much" from a local cannot fault. + // We must also be careful to check for the arm64 apple case where arguments can be + // passed without padding. + // + if ((dstSize != srcSize) && (srcLclNode != nullptr)) { - // We can generate a smaller code if store size is a multiple of TARGET_POINTER_SIZE. - // The dst size can be rounded up to PUTARG_STK size. - // The src size can be rounded up if it reads a local variable slot because the local - // variable stack allocation size is rounded up to be a multiple of the TARGET_POINTER_SIZE. - // The exception is arm64 apple arguments because they can be passed without padding. - if (varNode != nullptr) + unsigned widenedSrcSize = roundUp(srcSize, TARGET_POINTER_SIZE); + if (widenedSrcSize <= dstSize) { - // If we have a varNode, even if it was casted using `OBJ`, we can read its original memory size. - const LclVarDsc* varDsc = compiler->lvaGetDesc(varNode); - const unsigned varStackSize = varDsc->lvSize(); - if (varStackSize >= srcSize) - { - srcSize = varStackSize; - } + srcSize = widenedSrcSize; } } - if (dstSize == srcSize) - { - structSize = dstSize; - } - else - { - // With Unsafe object cast we can have different strange combinations: - // PutArgStk<8>(Obj<16>(LclVar<8>)) -> copy 8 bytes; - // PutArgStk<16>(Obj<16>(LclVar<8>)) -> copy 16 bytes, reading undefined memory after the local. - structSize = min(dstSize, srcSize); - } - int remainingSize = structSize; + assert(srcSize <= dstSize); + + int remainingSize = srcSize; unsigned structOffset = 0; + unsigned lclOffset = (srcLclNode != nullptr) ? srcLclNode->GetLclOffs() : 0; unsigned nextIndex = 0; #ifdef TARGET_ARM64 - // For a >= 16-byte structSize we will generate a ldp and stp instruction each loop + // For a >= 16-byte sizes we will generate a ldp and stp instruction each loop // ldp x2, x3, [x0] // stp x2, x3, [sp, #16] @@ -1028,11 +959,11 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode) var_types type0 = layout->GetGCPtrType(nextIndex + 0); var_types type1 = layout->GetGCPtrType(nextIndex + 1); - if (varNode != nullptr) + if (srcLclNode != nullptr) { - // Load from our varNumImp source + // Load from our local source emit->emitIns_R_R_S_S(INS_ldp, emitTypeSize(type0), emitTypeSize(type1), loReg, hiReg, - varNode->GetLclNum(), structOffset); + srcLclNode->GetLclNum(), lclOffset + structOffset); } else { @@ -1056,17 +987,18 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode) nextIndex += 2; } #else // TARGET_ARM - // For a >= 4 byte structSize we will generate a ldr and str instruction each loop + // For a >= 4 byte sizes we will generate a ldr and str instruction each loop // ldr r2, [r0] // str r2, [sp, #16] while (remainingSize >= TARGET_POINTER_SIZE) { var_types type = layout->GetGCPtrType(nextIndex); - if (varNode != nullptr) + if (srcLclNode != nullptr) { - // Load from our varNumImp source - emit->emitIns_R_S(INS_ldr, emitTypeSize(type), loReg, varNode->GetLclNum(), structOffset); + // Load from our local source + emit->emitIns_R_S(INS_ldr, emitTypeSize(type), loReg, srcLclNode->GetLclNum(), + lclOffset + structOffset); } else { @@ -1088,7 +1020,7 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode) } #endif // TARGET_ARM - // For a 12-byte structSize we will generate two load instructions + // For a 12-byte size we will generate two load instructions // ldr x2, [x0] // ldr w3, [x0, #8] // str x2, [sp, #16] @@ -1129,10 +1061,10 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode) remainingSize -= moveSize; instruction loadIns = ins_Load(type); - if (varNode != nullptr) + if (srcLclNode != nullptr) { - // Load from our varNumImp source - emit->emitIns_R_S(loadIns, attr, loReg, varNode->GetLclNum(), structOffset); + // Load from our local source + emit->emitIns_R_S(loadIns, attr, loReg, srcLclNode->GetLclNum(), lclOffset + structOffset); } else { diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index f6626dc3e6f7b0..e0cba5273da7fb 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -1031,9 +1031,6 @@ bool Lowering::TryLowerSwitchToBitTest( #endif // TARGET_XARCH } -// NOTE: this method deliberately does not update the call arg table. It must only -// be used by NewPutArg and LowerArg; these functions are responsible for updating -// the call arg table as necessary. void Lowering::ReplaceArgWithPutArgOrBitcast(GenTree** argSlot, GenTree* putArgOrBitcast) { assert(argSlot != nullptr); @@ -1069,12 +1066,7 @@ void Lowering::ReplaceArgWithPutArgOrBitcast(GenTree** argSlot, GenTree* putArgO // Notes: // For System V systems with native struct passing (i.e. UNIX_AMD64_ABI defined) // this method allocates a single GT_PUTARG_REG for 1 eightbyte structs and a GT_FIELD_LIST of two GT_PUTARG_REGs -// for two eightbyte structs. -// -// For STK passed structs the method generates GT_PUTARG_STK tree. For System V systems with native struct passing -// (i.e. UNIX_AMD64_ABI defined) this method also sets the GC pointers count and the pointers -// layout object, so the codegen of the GT_PUTARG_STK could use this for optimizing copying to the stack by value. -// (using block copy primitives for non GC pointers and a single TARGET_POINTER_SIZE copy with recording GC info.) +// for two eightbyte structs. For STK passed structs the method generates GT_PUTARG_STK tree. // GenTree* Lowering::NewPutArg(GenTreeCall* call, GenTree* arg, CallArg* callArg, var_types type) { @@ -1086,19 +1078,6 @@ GenTree* Lowering::NewPutArg(GenTreeCall* call, GenTree* arg, CallArg* callArg, bool isOnStack = (callArg->AbiInfo.GetRegNum() == REG_STK); -#if defined(TARGET_ARMARCH) || defined(TARGET_LOONGARCH64) - // Mark contained when we pass struct - // GT_FIELD_LIST is always marked contained when it is generated - if (type == TYP_STRUCT) - { - arg->SetContained(); - if ((arg->OperGet() == GT_OBJ) && (arg->AsObj()->Addr()->OperGet() == GT_LCL_VAR_ADDR)) - { - MakeSrcContained(arg, arg->AsObj()->Addr()); - } - } -#endif - #if FEATURE_ARG_SPLIT // Struct can be split into register(s) and stack on ARM if (compFeatureArgSplit() && callArg->AbiInfo.IsSplit()) @@ -1120,10 +1099,7 @@ GenTree* Lowering::NewPutArg(GenTreeCall* call, GenTree* arg, CallArg* callArg, callArg->AbiInfo.GetStackByteSize(), #endif callArg->AbiInfo.NumRegs, call, putInIncomingArgArea); - // If struct argument is morphed to GT_FIELD_LIST node(s), - // we can know GC info by type of each GT_FIELD_LIST node. - // So we skip setting GC Pointer info. - // + GenTreePutArgSplit* argSplit = putArg->AsPutArgSplit(); for (unsigned regIndex = 0; regIndex < callArg->AbiInfo.NumRegs; regIndex++) { @@ -1132,6 +1108,12 @@ GenTree* Lowering::NewPutArg(GenTreeCall* call, GenTree* arg, CallArg* callArg, if (arg->OperGet() == GT_OBJ) { + arg->SetContained(); + if (arg->AsObj()->Addr()->OperGet() == GT_LCL_VAR_ADDR) + { + MakeSrcContained(arg, arg->AsObj()->Addr()); + } + ClassLayout* layout = arg->AsObj()->GetLayout(); // Set type of registers @@ -1206,8 +1188,6 @@ GenTree* Lowering::NewPutArg(GenTreeCall* call, GenTree* arg, CallArg* callArg, #ifdef DEBUG // Make sure state is correct. The PUTARG_STK has TYP_VOID, as it doesn't produce // a result. So the type of its operand must be the correct type to push on the stack. - // For a FIELD_LIST, this will be the type of the field (not the type of the arg), - // but otherwise it is generally the type of the operand. callArg->CheckIsStruct(); #endif @@ -1459,6 +1439,13 @@ void Lowering::LowerArg(GenTreeCall* call, CallArg* callArg, bool late) ReplaceArgWithPutArgOrBitcast(ppArg, putArg); } } + + arg = *ppArg; + + if (arg->OperIs(GT_PUTARG_STK)) + { + LowerPutArgStk(arg->AsPutArgStk()); + } } #if defined(TARGET_ARMARCH) || defined(TARGET_LOONGARCH64) diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp index 5b50f178e7c6ca..177034fabe709b 100644 --- a/src/coreclr/jit/lowerarmarch.cpp +++ b/src/coreclr/jit/lowerarmarch.cpp @@ -574,6 +574,44 @@ void Lowering::ContainBlockStoreAddress(GenTreeBlk* blkNode, unsigned size, GenT addr->SetContained(); } +//------------------------------------------------------------------------ +// LowerPutArgStk: Lower a GT_PUTARG_STK. +// +// Arguments: +// putArgStk - The node to lower +// +void Lowering::LowerPutArgStk(GenTreePutArgStk* putArgStk) +{ + GenTree* src = putArgStk->Data(); + + if (src->TypeIs(TYP_STRUCT)) + { + // STRUCT args (FIELD_LIST / OBJ / LCL_VAR / LCL_FLD) will always be contained. + MakeSrcContained(putArgStk, src); + + // TODO-ADDR: always perform this transformation in local morph and delete this code. + if (src->OperIs(GT_OBJ) && src->AsObj()->Addr()->OperIsLocalAddr()) + { + GenTreeLclVarCommon* lclAddrNode = src->AsObj()->Addr()->AsLclVarCommon(); + unsigned lclNum = lclAddrNode->GetLclNum(); + unsigned lclOffs = lclAddrNode->GetLclOffs(); + ClassLayout* layout = src->AsObj()->GetLayout(); + + src->ChangeOper(GT_LCL_FLD); + src->AsLclFld()->SetLclNum(lclNum); + src->AsLclFld()->SetLclOffs(lclOffs); + src->AsLclFld()->SetLayout(layout); + + BlockRange().Remove(lclAddrNode); + } + else if (src->OperIs(GT_LCL_VAR)) + { + // TODO-1stClassStructs: support struct enregistration here by retyping "src" to its register type. + comp->lvaSetVarDoNotEnregister(src->AsLclVar()->GetLclNum() DEBUGARG(DoNotEnregisterReason::IsStructArg)); + } + } +} + //------------------------------------------------------------------------ // LowerCast: Lower GT_CAST(srcType, DstType) nodes. // diff --git a/src/coreclr/jit/lowerloongarch64.cpp b/src/coreclr/jit/lowerloongarch64.cpp index 7a2cde0c4f5fbe..1de03b57e8e92a 100644 --- a/src/coreclr/jit/lowerloongarch64.cpp +++ b/src/coreclr/jit/lowerloongarch64.cpp @@ -416,6 +416,30 @@ void Lowering::ContainBlockStoreAddress(GenTreeBlk* blkNode, unsigned size, GenT addr->SetContained(); } +//------------------------------------------------------------------------ +// LowerPutArgStk: Lower a GT_PUTARG_STK. +// +// Arguments: +// putArgStk - The node to lower +// +void Lowering::LowerPutArgStk(GenTreePutArgStk* putArgStk) +{ + GenTree* src = putArgStk->Data(); + + if (src->TypeIs(TYP_STRUCT)) + { + // STRUCT args (FIELD_LIST / OBJ) will always be contained. + MakeSrcContained(putArgStk, src); + + // Additionally, codegen supports containment of local addresses under OBJs. + if (src->OperIs(GT_OBJ) && src->AsObj()->Addr()->OperIs(GT_LCL_VAR_ADDR)) + { + // TODO-LOONGARCH64-CQ: support containment of LCL_FLD_ADDR too. + MakeSrcContained(src, src->AsObj()->Addr()); + } + } +} + //------------------------------------------------------------------------ // LowerCast: Lower GT_CAST(srcType, DstType) nodes. // diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp index ee9b370d61866b..8d8cbce63276ba 100644 --- a/src/coreclr/jit/lowerxarch.cpp +++ b/src/coreclr/jit/lowerxarch.cpp @@ -466,10 +466,7 @@ void Lowering::ContainBlockStoreAddress(GenTreeBlk* blkNode, unsigned size, GenT // LowerPutArgStk: Lower a GT_PUTARG_STK. // // Arguments: -// tree - The node of interest -// -// Return Value: -// None. +// putArgStk - The node of interest // void Lowering::LowerPutArgStk(GenTreePutArgStk* putArgStk) { @@ -4705,22 +4702,6 @@ void Lowering::ContainCheckCallOperands(GenTreeCall* call) MakeSrcContained(call, ctrlExpr); } } - - for (CallArg& arg : call->gtArgs.EarlyArgs()) - { - if (arg.GetEarlyNode()->OperIs(GT_PUTARG_STK)) - { - LowerPutArgStk(arg.GetEarlyNode()->AsPutArgStk()); - } - } - - for (CallArg& arg : call->gtArgs.LateArgs()) - { - if (arg.GetLateNode()->OperIs(GT_PUTARG_STK)) - { - LowerPutArgStk(arg.GetLateNode()->AsPutArgStk()); - } - } } //------------------------------------------------------------------------ diff --git a/src/coreclr/jit/lsraarmarch.cpp b/src/coreclr/jit/lsraarmarch.cpp index 4a9eefef350c57..1ae93e96435486 100644 --- a/src/coreclr/jit/lsraarmarch.cpp +++ b/src/coreclr/jit/lsraarmarch.cpp @@ -403,20 +403,19 @@ int LinearScan::BuildPutArgStk(GenTreePutArgStk* argNode) { assert(argNode->gtOper == GT_PUTARG_STK); - GenTree* putArgChild = argNode->gtGetOp1(); - - int srcCount = 0; + GenTree* src = argNode->Data(); + int srcCount = 0; - // Do we have a TYP_STRUCT argument (or a GT_FIELD_LIST), if so it must be a multireg pass-by-value struct - if (putArgChild->TypeIs(TYP_STRUCT) || putArgChild->OperIs(GT_FIELD_LIST)) + // Do we have a TYP_STRUCT argument, if so it must be a multireg pass-by-value struct + if (src->TypeIs(TYP_STRUCT)) { // We will use store instructions that each write a register sized value - if (putArgChild->OperIs(GT_FIELD_LIST)) + if (src->OperIs(GT_FIELD_LIST)) { - assert(putArgChild->isContained()); + assert(src->isContained()); // We consume all of the items in the GT_FIELD_LIST - for (GenTreeFieldList::Use& use : putArgChild->AsFieldList()->Uses()) + for (GenTreeFieldList::Use& use : src->AsFieldList()->Uses()) { BuildUse(use.GetNode()); srcCount++; @@ -443,36 +442,25 @@ int LinearScan::BuildPutArgStk(GenTreePutArgStk* argNode) buildInternalIntRegisterDefForNode(argNode); #endif // TARGET_ARM64 - if (putArgChild->OperGet() == GT_OBJ) + assert(src->isContained()); + + if (src->OperIs(GT_OBJ)) { - assert(putArgChild->isContained()); - GenTree* objChild = putArgChild->gtGetOp1(); - if (objChild->OperGet() == GT_LCL_VAR_ADDR) - { - // We will generate all of the code for the GT_PUTARG_STK, the GT_OBJ and the GT_LCL_VAR_ADDR - // as one contained operation, and there are no source registers. - // - assert(objChild->isContained()); - } - else - { - // We will generate all of the code for the GT_PUTARG_STK and its child node - // as one contained operation - // - srcCount = BuildOperandUses(objChild); - } + // Build uses for the address to load from. + // + srcCount = BuildOperandUses(src->AsObj()->Addr()); } else { // No source registers. - putArgChild->OperIs(GT_LCL_VAR); + assert(src->OperIs(GT_LCL_VAR, GT_LCL_FLD)); } } } else { - assert(!putArgChild->isContained()); - srcCount = BuildOperandUses(putArgChild); + assert(!src->isContained()); + srcCount = BuildOperandUses(src); #if defined(FEATURE_SIMD) if (compMacOsArm64Abi() && argNode->GetStackByteSize() == 12) { From b9d9b0e561ffc226e066ce4cddd2ac8e6813ee2d Mon Sep 17 00:00:00 2001 From: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> Date: Wed, 15 Jun 2022 04:33:45 +0300 Subject: [PATCH 123/337] Support `PUTARG_STK(STRUCT LCL_VAR/LCL_FLD)` on x86/Unix x64 (#70702) * Add GenTree::GetLayout * x86/Unix x64: lowering * x86/Unix x64: "genConsumePutStructArgStk" * x86/Unix x64: "genStructPutArgUnroll" * x86/Unix x64: codegen asserts * x86: "genStructPutArgPush" * Unix x64: "genStructPutArgPartialRepMovs" --- src/coreclr/jit/codegen.h | 8 +-- src/coreclr/jit/codegenlinear.cpp | 35 ++++------ src/coreclr/jit/codegenxarch.cpp | 111 ++++++++++++++---------------- src/coreclr/jit/gentree.cpp | 37 +++++++++- src/coreclr/jit/gentree.h | 2 + src/coreclr/jit/jit.h | 3 +- src/coreclr/jit/lower.cpp | 69 ++----------------- src/coreclr/jit/lowerxarch.cpp | 37 +++++++--- 8 files changed, 140 insertions(+), 162 deletions(-) diff --git a/src/coreclr/jit/codegen.h b/src/coreclr/jit/codegen.h index 8646d9191edcf1..47abb2f25ac06c 100644 --- a/src/coreclr/jit/codegen.h +++ b/src/coreclr/jit/codegen.h @@ -1335,10 +1335,10 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX void genPutStructArgStk(GenTreePutArgStk* treeNode); - unsigned genMove8IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset); - unsigned genMove4IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset); - unsigned genMove2IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset); - unsigned genMove1IfNeeded(unsigned size, regNumber tmpReg, GenTree* srcAddr, unsigned offset); + unsigned genMove8IfNeeded(unsigned size, regNumber tmpReg, GenTree* src, unsigned offset); + unsigned genMove4IfNeeded(unsigned size, regNumber tmpReg, GenTree* src, unsigned offset); + unsigned genMove2IfNeeded(unsigned size, regNumber tmpReg, GenTree* src, unsigned offset); + unsigned genMove1IfNeeded(unsigned size, regNumber tmpReg, GenTree* src, unsigned offset); void genCodeForLoadOffset(instruction ins, emitAttr size, regNumber dst, GenTree* base, unsigned offset); void genStoreRegToStackArg(var_types type, regNumber reg, int offset); void genStructPutArgRepMovs(GenTreePutArgStk* putArgStkNode); diff --git a/src/coreclr/jit/codegenlinear.cpp b/src/coreclr/jit/codegenlinear.cpp index 6a44f1db324de1..f2528f6f3c628d 100644 --- a/src/coreclr/jit/codegenlinear.cpp +++ b/src/coreclr/jit/codegenlinear.cpp @@ -1762,21 +1762,21 @@ void CodeGen::genConsumePutStructArgStk(GenTreePutArgStk* putArgNode, regNumber sizeReg) { // The putArgNode children are always contained. We should not consume any registers. - assert(putArgNode->gtGetOp1()->isContained()); + assert(putArgNode->Data()->isContained()); - // Get the source address. - GenTree* src = putArgNode->gtGetOp1(); + // Get the source. + GenTree* src = putArgNode->Data(); + regNumber srcAddrReg = REG_NA; assert(varTypeIsStruct(src)); - assert((src->gtOper == GT_OBJ) || ((src->gtOper == GT_IND && varTypeIsSIMD(src)))); - GenTree* srcAddr = src->gtGetOp1(); + assert(src->OperIs(GT_OBJ) || src->OperIsLocalRead() || (src->OperIs(GT_IND) && varTypeIsSIMD(src))); assert(dstReg != REG_NA); assert(srcReg != REG_NA); - // Consume the registers only if they are not contained or set to REG_NA. - if (srcAddr->GetRegNum() != REG_NA) + // Consume the register for the source address if needed. + if (src->OperIsIndir()) { - genConsumeReg(srcAddr); + srcAddrReg = genConsumeReg(src->AsIndir()->Addr()); } // If the op1 is already in the dstReg - nothing to do. @@ -1798,22 +1798,17 @@ void CodeGen::genConsumePutStructArgStk(GenTreePutArgStk* putArgNode, } #endif // !TARGET_X86 - if (srcAddr->OperIsLocalAddr()) + if (srcAddrReg != REG_NA) { - // The OperLocalAddr is always contained. - assert(srcAddr->isContained()); - const GenTreeLclVarCommon* lclNode = srcAddr->AsLclVarCommon(); - - // Generate LEA instruction to load the LclVar address in RSI. - // Source is known to be on the stack. Use EA_PTRSIZE. - unsigned int offset = lclNode->GetLclOffs(); - GetEmitter()->emitIns_R_S(INS_lea, EA_PTRSIZE, srcReg, lclNode->GetLclNum(), offset); + // Source is not known to be on the stack. Use EA_BYREF. + GetEmitter()->emitIns_Mov(INS_mov, EA_BYREF, srcReg, srcAddrReg, /* canSkip */ true); } else { - assert(srcAddr->GetRegNum() != REG_NA); - // Source is not known to be on the stack. Use EA_BYREF. - GetEmitter()->emitIns_Mov(INS_mov, EA_BYREF, srcReg, srcAddr->GetRegNum(), /* canSkip */ true); + // Generate LEA instruction to load the LclVar address in RSI. + // Source is known to be on the stack. Use EA_PTRSIZE. + GetEmitter()->emitIns_R_S(INS_lea, EA_PTRSIZE, srcReg, src->AsLclVarCommon()->GetLclNum(), + src->AsLclVarCommon()->GetLclOffs()); } if (sizeReg != REG_NA) diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index 4435e2aea5f691..e4123e64f5291a 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -3053,21 +3053,19 @@ void CodeGen::genCodeForInitBlkHelper(GenTreeBlk* initBlkNode) #ifdef FEATURE_PUT_STRUCT_ARG_STK // Generate code for a load from some address + offset -// baseNode: tree node which can be either a local address or arbitrary node -// offset: distance from the baseNode from which to load -void CodeGen::genCodeForLoadOffset(instruction ins, emitAttr size, regNumber dst, GenTree* baseNode, unsigned offset) +// base: tree node which can be either a local or an indir +// offset: distance from the "base" location from which to load +// +void CodeGen::genCodeForLoadOffset(instruction ins, emitAttr size, regNumber dst, GenTree* base, unsigned offset) { - emitter* emit = GetEmitter(); - - if (baseNode->OperIsLocalAddr()) + if (base->OperIsLocalRead()) { - const GenTreeLclVarCommon* lclVar = baseNode->AsLclVarCommon(); - offset += lclVar->GetLclOffs(); - emit->emitIns_R_S(ins, size, dst, lclVar->GetLclNum(), offset); + GetEmitter()->emitIns_R_S(ins, size, dst, base->AsLclVarCommon()->GetLclNum(), + offset + base->AsLclVarCommon()->GetLclOffs()); } else { - emit->emitIns_R_AR(ins, size, dst, baseNode->GetRegNum(), offset); + GetEmitter()->emitIns_R_AR(ins, size, dst, base->AsIndir()->Addr()->GetRegNum(), offset); } } #endif // FEATURE_PUT_STRUCT_ARG_STK @@ -3338,7 +3336,7 @@ void CodeGen::genCodeForCpBlkRepMovs(GenTreeBlk* cpBlkNode) // Arguments: // size - The size of bytes remaining to be moved // longTmpReg - The tmp register to be used for the long value -// srcAddr - The address of the source struct +// src - The source struct node (LCL/OBJ) // offset - The current offset being copied // // Return Value: @@ -3350,7 +3348,7 @@ void CodeGen::genCodeForCpBlkRepMovs(GenTreeBlk* cpBlkNode) // On x86, longTmpReg must be an xmm reg; on x64 it must be an integer register. // This is checked by genStoreRegToStackArg. // -unsigned CodeGen::genMove8IfNeeded(unsigned size, regNumber longTmpReg, GenTree* srcAddr, unsigned offset) +unsigned CodeGen::genMove8IfNeeded(unsigned size, regNumber longTmpReg, GenTree* src, unsigned offset) { #ifdef TARGET_X86 instruction longMovIns = INS_movq; @@ -3359,7 +3357,7 @@ unsigned CodeGen::genMove8IfNeeded(unsigned size, regNumber longTmpReg, GenTree* #endif // !TARGET_X86 if ((size & 8) != 0) { - genCodeForLoadOffset(longMovIns, EA_8BYTE, longTmpReg, srcAddr, offset); + genCodeForLoadOffset(longMovIns, EA_8BYTE, longTmpReg, src, offset); genStoreRegToStackArg(TYP_LONG, longTmpReg, offset); return 8; } @@ -3372,7 +3370,7 @@ unsigned CodeGen::genMove8IfNeeded(unsigned size, regNumber longTmpReg, GenTree* // Arguments: // size - The size of bytes remaining to be moved // intTmpReg - The tmp register to be used for the long value -// srcAddr - The address of the source struct +// src - The source struct node (LCL/OBJ) // offset - The current offset being copied // // Return Value: @@ -3384,11 +3382,11 @@ unsigned CodeGen::genMove8IfNeeded(unsigned size, regNumber longTmpReg, GenTree* // intTmpReg must be an integer register. // This is checked by genStoreRegToStackArg. // -unsigned CodeGen::genMove4IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAddr, unsigned offset) +unsigned CodeGen::genMove4IfNeeded(unsigned size, regNumber intTmpReg, GenTree* src, unsigned offset) { if ((size & 4) != 0) { - genCodeForLoadOffset(INS_mov, EA_4BYTE, intTmpReg, srcAddr, offset); + genCodeForLoadOffset(INS_mov, EA_4BYTE, intTmpReg, src, offset); genStoreRegToStackArg(TYP_INT, intTmpReg, offset); return 4; } @@ -3401,7 +3399,7 @@ unsigned CodeGen::genMove4IfNeeded(unsigned size, regNumber intTmpReg, GenTree* // Arguments: // size - The size of bytes remaining to be moved // intTmpReg - The tmp register to be used for the long value -// srcAddr - The address of the source struct +// src - The source struct node (LCL/OBJ) // offset - The current offset being copied // // Return Value: @@ -3413,11 +3411,11 @@ unsigned CodeGen::genMove4IfNeeded(unsigned size, regNumber intTmpReg, GenTree* // intTmpReg must be an integer register. // This is checked by genStoreRegToStackArg. // -unsigned CodeGen::genMove2IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAddr, unsigned offset) +unsigned CodeGen::genMove2IfNeeded(unsigned size, regNumber intTmpReg, GenTree* src, unsigned offset) { if ((size & 2) != 0) { - genCodeForLoadOffset(INS_mov, EA_2BYTE, intTmpReg, srcAddr, offset); + genCodeForLoadOffset(INS_mov, EA_2BYTE, intTmpReg, src, offset); genStoreRegToStackArg(TYP_SHORT, intTmpReg, offset); return 2; } @@ -3430,7 +3428,7 @@ unsigned CodeGen::genMove2IfNeeded(unsigned size, regNumber intTmpReg, GenTree* // Arguments: // size - The size of bytes remaining to be moved // intTmpReg - The tmp register to be used for the long value -// srcAddr - The address of the source struct +// src - The source struct node (LCL/OBJ) // offset - The current offset being copied // // Return Value: @@ -3442,11 +3440,11 @@ unsigned CodeGen::genMove2IfNeeded(unsigned size, regNumber intTmpReg, GenTree* // intTmpReg must be an integer register. // This is checked by genStoreRegToStackArg. // -unsigned CodeGen::genMove1IfNeeded(unsigned size, regNumber intTmpReg, GenTree* srcAddr, unsigned offset) +unsigned CodeGen::genMove1IfNeeded(unsigned size, regNumber intTmpReg, GenTree* src, unsigned offset) { if ((size & 1) != 0) { - genCodeForLoadOffset(INS_mov, EA_1BYTE, intTmpReg, srcAddr, offset); + genCodeForLoadOffset(INS_mov, EA_1BYTE, intTmpReg, src, offset); genStoreRegToStackArg(TYP_BYTE, intTmpReg, offset); return 1; } @@ -3470,20 +3468,21 @@ unsigned CodeGen::genMove1IfNeeded(unsigned size, regNumber intTmpReg, GenTree* // void CodeGen::genStructPutArgUnroll(GenTreePutArgStk* putArgNode) { - GenTree* src = putArgNode->AsOp()->gtOp1; + GenTree* src = putArgNode->Data(); // We will never call this method for SIMD types, which are stored directly in genPutStructArgStk(). - assert(src->isContained() && src->OperIs(GT_OBJ) && src->TypeIs(TYP_STRUCT)); + assert(src->isContained() && src->TypeIs(TYP_STRUCT) && (src->OperIs(GT_OBJ) || src->OperIsLocalRead())); + #ifdef TARGET_X86 assert(!m_pushStkArg); #endif - if (src->AsOp()->gtOp1->isUsedFromReg()) + if (src->OperIs(GT_OBJ)) { - genConsumeReg(src->AsOp()->gtOp1); + genConsumeReg(src->AsObj()->Addr()); } unsigned loadSize = putArgNode->GetArgLoadSize(); - assert(!src->AsObj()->GetLayout()->HasGCPtr() && (loadSize <= CPBLK_UNROLL_LIMIT)); + assert(!src->GetLayout(compiler)->HasGCPtr() && (loadSize <= CPBLK_UNROLL_LIMIT)); unsigned offset = 0; regNumber xmmTmpReg = REG_NA; @@ -3518,7 +3517,7 @@ void CodeGen::genStructPutArgUnroll(GenTreePutArgStk* putArgNode) // this probably needs to be changed. // Load - genCodeForLoadOffset(INS_movdqu, EA_8BYTE, xmmTmpReg, src->gtGetOp1(), offset); + genCodeForLoadOffset(INS_movdqu, EA_8BYTE, xmmTmpReg, src, offset); // Store genStoreRegToStackArg(TYP_STRUCT, xmmTmpReg, offset); @@ -3528,10 +3527,10 @@ void CodeGen::genStructPutArgUnroll(GenTreePutArgStk* putArgNode) // Fill the remainder (15 bytes or less) if there's one. if ((loadSize % XMM_REGSIZE_BYTES) != 0) { - offset += genMove8IfNeeded(loadSize, longTmpReg, src->AsOp()->gtOp1, offset); - offset += genMove4IfNeeded(loadSize, intTmpReg, src->AsOp()->gtOp1, offset); - offset += genMove2IfNeeded(loadSize, intTmpReg, src->AsOp()->gtOp1, offset); - offset += genMove1IfNeeded(loadSize, intTmpReg, src->AsOp()->gtOp1, offset); + offset += genMove8IfNeeded(loadSize, longTmpReg, src, offset); + offset += genMove4IfNeeded(loadSize, intTmpReg, src, offset); + offset += genMove2IfNeeded(loadSize, intTmpReg, src, offset); + offset += genMove1IfNeeded(loadSize, intTmpReg, src, offset); assert(offset == loadSize); } } @@ -3548,8 +3547,7 @@ void CodeGen::genStructPutArgUnroll(GenTreePutArgStk* putArgNode) void CodeGen::genStructPutArgRepMovs(GenTreePutArgStk* putArgNode) { GenTree* src = putArgNode->gtGetOp1(); - assert(src->TypeGet() == TYP_STRUCT); - assert(!src->AsObj()->GetLayout()->HasGCPtr()); + assert(src->TypeIs(TYP_STRUCT) && !src->GetLayout(compiler)->HasGCPtr()); // Make sure we got the arguments of the cpblk operation in the right registers, and that // 'src' is contained as expected. @@ -3583,27 +3581,22 @@ void CodeGen::genStructPutArgPush(GenTreePutArgStk* putArgNode) // future. assert(m_pushStkArg); - GenTree* src = putArgNode->Data(); - GenTree* srcAddr = putArgNode->Data()->AsObj()->Addr(); - - regNumber srcAddrReg = srcAddr->GetRegNum(); - const bool srcAddrInReg = srcAddrReg != REG_NA; - - unsigned srcLclNum = 0; - unsigned srcLclOffset = 0; - if (srcAddrInReg) + GenTree* src = putArgNode->Data(); + regNumber srcAddrReg = REG_NA; + unsigned srcLclNum = BAD_VAR_NUM; + unsigned srcLclOffs = BAD_LCL_OFFSET; + if (src->OperIsLocalRead()) { - srcAddrReg = genConsumeReg(srcAddr); + assert(src->isContained()); + srcLclNum = src->AsLclVarCommon()->GetLclNum(); + srcLclOffs = src->AsLclVarCommon()->GetLclOffs(); } else { - assert(srcAddr->OperIsLocalAddr()); - - srcLclNum = srcAddr->AsLclVarCommon()->GetLclNum(); - srcLclOffset = srcAddr->AsLclVarCommon()->GetLclOffs(); + srcAddrReg = genConsumeReg(src->AsObj()->Addr()); } - ClassLayout* layout = src->AsObj()->GetLayout(); + ClassLayout* layout = src->GetLayout(compiler); const unsigned loadSize = putArgNode->GetArgLoadSize(); assert(((loadSize < XMM_REGSIZE_BYTES) || layout->HasGCPtr()) && ((loadSize % TARGET_POINTER_SIZE) == 0)); const unsigned numSlots = loadSize / TARGET_POINTER_SIZE; @@ -3612,13 +3605,13 @@ void CodeGen::genStructPutArgPush(GenTreePutArgStk* putArgNode) { emitAttr slotAttr = emitTypeSize(layout->GetGCPtrType(i)); const unsigned byteOffset = i * TARGET_POINTER_SIZE; - if (srcAddrInReg) + if (srcAddrReg != REG_NA) { GetEmitter()->emitIns_AR_R(INS_push, slotAttr, REG_NA, srcAddrReg, byteOffset); } else { - GetEmitter()->emitIns_S(INS_push, slotAttr, srcLclNum, srcLclOffset + byteOffset); + GetEmitter()->emitIns_S(INS_push, slotAttr, srcLclNum, srcLclOffs + byteOffset); } AddStackLevel(TARGET_POINTER_SIZE); @@ -3643,10 +3636,9 @@ void CodeGen::genStructPutArgPartialRepMovs(GenTreePutArgStk* putArgNode) // They may now contain gc pointers (depending on their type; gcMarkRegPtrVal will "do the right thing"). genConsumePutStructArgStk(putArgNode, REG_RDI, REG_RSI, REG_NA); - GenTreeObj* src = putArgNode->gtGetOp1()->AsObj(); - ClassLayout* layout = src->GetLayout(); - const bool srcIsLocal = src->Addr()->OperIsLocalAddr(); - const emitAttr srcAddrAttr = srcIsLocal ? EA_PTRSIZE : EA_BYREF; + GenTree* src = putArgNode->Data(); + ClassLayout* layout = src->GetLayout(compiler); + const emitAttr srcAddrAttr = src->OperIsLocalRead() ? EA_PTRSIZE : EA_BYREF; #if DEBUG unsigned numGCSlotsCopied = 0; @@ -5533,7 +5525,7 @@ void CodeGen::genCall(GenTreeCall* call) #ifdef FEATURE_PUT_STRUCT_ARG_STK if (source->TypeIs(TYP_STRUCT) && !source->OperIs(GT_FIELD_LIST)) { - unsigned loadSize = source->AsObj()->GetLayout()->GetSize(); + unsigned loadSize = source->GetLayout(compiler)->GetSize(); assert(argSize == roundUp(loadSize, TARGET_POINTER_SIZE)); } #endif // FEATURE_PUT_STRUCT_ARG_STK @@ -7790,11 +7782,11 @@ bool CodeGen::genAdjustStackForPutArgStk(GenTreePutArgStk* putArgStk) { case GenTreePutArgStk::Kind::RepInstr: case GenTreePutArgStk::Kind::Unroll: - assert(!source->AsObj()->GetLayout()->HasGCPtr()); + assert(!source->GetLayout(compiler)->HasGCPtr()); break; case GenTreePutArgStk::Kind::Push: - assert(source->OperIs(GT_FIELD_LIST) || source->AsObj()->GetLayout()->HasGCPtr() || + assert(source->OperIs(GT_FIELD_LIST) || source->GetLayout(compiler)->HasGCPtr() || (argSize < XMM_REGSIZE_BYTES)); break; @@ -8308,14 +8300,11 @@ void CodeGen::genPutStructArgStk(GenTreePutArgStk* putArgStk) assert(targetType == TYP_STRUCT); - ClassLayout* layout = source->AsObj()->GetLayout(); - switch (putArgStk->gtPutArgStkKind) { case GenTreePutArgStk::Kind::RepInstr: genStructPutArgRepMovs(putArgStk); break; - #ifndef TARGET_X86 case GenTreePutArgStk::Kind::PartialRepInstr: genStructPutArgPartialRepMovs(putArgStk); diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 2e79010de076e3..61144862e338b3 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -567,14 +567,47 @@ void Compiler::fgWalkAllTreesPre(fgWalkPreFn* visitor, void* pCallBackData) } } +//----------------------------------------------------------- +// GetLayout: Get the struct layout for this node. +// +// Arguments: +// compiler - The Compiler instance +// +// Return Value: +// The struct layout of this node; it must have one. +// +// Notes: +// This is the "general" method for getting the layout, +// the more efficient node-specific ones should be used +// in case the node's oper is known. +// +ClassLayout* GenTree::GetLayout(Compiler* compiler) const +{ + assert(varTypeIsStruct(TypeGet())); + + switch (OperGet()) + { + case GT_LCL_VAR: + return compiler->lvaGetDesc(AsLclVar())->GetLayout(); + + case GT_LCL_FLD: + return AsLclFld()->GetLayout(); + + case GT_OBJ: + case GT_BLK: + return AsBlk()->GetLayout(); + + default: + unreached(); + } +} + //----------------------------------------------------------- // CopyReg: Copy the _gtRegNum/gtRegTag fields. // // Arguments: // from - GenTree node from which to copy // -// Return Value: -// None void GenTree::CopyReg(GenTree* from) { _gtRegNum = from->_gtRegNum; diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index 578fb725e40777..aa7dba1b2a346b 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -759,6 +759,8 @@ struct GenTree return gtType; } + ClassLayout* GetLayout(Compiler* compiler) const; + #ifdef DEBUG genTreeOps gtOperSave; // Only used to save gtOper when we destroy a node, to aid debugging. #endif diff --git a/src/coreclr/jit/jit.h b/src/coreclr/jit/jit.h index d4ea7ab0dcb910..cf0e7996500c55 100644 --- a/src/coreclr/jit/jit.h +++ b/src/coreclr/jit/jit.h @@ -336,7 +336,8 @@ typedef unsigned IL_OFFSET; const IL_OFFSET BAD_IL_OFFSET = 0xffffffff; -const unsigned BAD_VAR_NUM = UINT_MAX; +const unsigned BAD_VAR_NUM = UINT_MAX; +const uint16_t BAD_LCL_OFFSET = UINT16_MAX; // Code can't be more than 2^31 in any direction. This is signed, so it should be used for anything that is // relative to something else. diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index e0cba5273da7fb..393b31478024e7 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -388,16 +388,6 @@ GenTree* Lowering::LowerNode(GenTree* node) break; #endif -#if !defined(TARGET_ARMARCH) && !defined(TARGET_LOONGARCH64) - // TODO-ARMARCH-CQ: We should contain this as long as the offset fits. - case GT_OBJ: - if (node->AsObj()->Addr()->OperIsLocalAddr()) - { - node->AsObj()->Addr()->SetContained(); - } - break; -#endif // !TARGET_ARMARCH - case GT_KEEPALIVE: node->gtGetOp1()->SetRegOptional(); break; @@ -1225,64 +1215,15 @@ GenTree* Lowering::NewPutArg(GenTreeCall* call, GenTree* arg, CallArg* callArg, #endif call, putInIncomingArgArea); -#ifdef FEATURE_PUT_STRUCT_ARG_STK - // If the ArgTabEntry indicates that this arg is a struct - // get and store the number of slots that are references. - // This is later used in the codegen for PUT_ARG_STK implementation - // for struct to decide whether and how many single eight-byte copies - // to be done (only for reference slots), so gcinfo is emitted. - // For non-reference slots faster/smaller size instructions are used - - // pair copying using XMM registers or rep mov instructions. +#if defined(DEBUG) && defined(FEATURE_PUT_STRUCT_ARG_STK) if (callArg->AbiInfo.IsStruct) { - // We use GT_OBJ only for non-lclVar, non-SIMD, non-FIELD_LIST struct arguments. - if (arg->OperIsLocal()) - { - // This must have a type with a known size (SIMD or has been morphed to a primitive type). - assert(arg->TypeGet() != TYP_STRUCT); - } - else if (arg->OperIs(GT_OBJ)) + // We use GT_OBJ only for non-SIMD struct arguments. + if (arg->OperIs(GT_OBJ)) { assert(!varTypeIsSIMD(arg)); - -#ifdef TARGET_X86 - // On x86 VM lies about the type of a struct containing a pointer sized - // integer field by returning the type of its field as the type of struct. - // Such struct can be passed in a register depending its position in - // parameter list. VM does this unwrapping only one level and therefore - // a type like Struct Foo { Struct Bar { int f}} awlays needs to be - // passed on stack. Also, VM doesn't lie about type of such a struct - // when it is a field of another struct. That is VM doesn't lie about - // the type of Foo.Bar - // - // We now support the promotion of fields that are of type struct. - // However we only support a limited case where the struct field has a - // single field and that single field must be a scalar type. Say Foo.Bar - // field is getting passed as a parameter to a call, Since it is a TYP_STRUCT, - // as per x86 ABI it should always be passed on stack. Therefore GenTree - // node under a PUTARG_STK could be GT_OBJ(GT_LCL_VAR_ADDR(v1)), where - // local v1 could be a promoted field standing for Foo.Bar. Note that - // the type of v1 will be the type of field of Foo.Bar.f when Foo is - // promoted. That is v1 will be a scalar type. In this case we need to - // pass v1 on stack instead of in a register. - // - // TODO-PERF: replace GT_OBJ(GT_LCL_VAR_ADDR(v1)) with v1 if v1 is - // a scalar type and the width of GT_OBJ matches the type size of v1. - // Note that this cannot be done till call node arguments are morphed - // because we should not lose the fact that the type of argument is - // a struct so that the arg gets correctly marked to be passed on stack. - GenTree* objOp1 = arg->gtGetOp1(); - if (objOp1->OperGet() == GT_LCL_VAR_ADDR) - { - unsigned lclNum = objOp1->AsLclVarCommon()->GetLclNum(); - if (comp->lvaTable[lclNum].lvType != TYP_STRUCT) - { - comp->lvaSetVarDoNotEnregister(lclNum DEBUGARG(DoNotEnregisterReason::VMNeedsStackAddr)); - } - } -#endif // TARGET_X86 } - else if (!arg->OperIs(GT_FIELD_LIST)) + else if (!arg->TypeIs(TYP_STRUCT)) { #ifdef TARGET_ARM assert((callArg->AbiInfo.GetStackSlotsNumber() == 1) || @@ -1292,7 +1233,7 @@ GenTree* Lowering::NewPutArg(GenTreeCall* call, GenTree* arg, CallArg* callArg, #endif } } -#endif // FEATURE_PUT_STRUCT_ARG_STK +#endif // defined(DEBUG) && defined(FEATURE_PUT_STRUCT_ARG_STK) } } diff --git a/src/coreclr/jit/lowerxarch.cpp b/src/coreclr/jit/lowerxarch.cpp index 8d8cbce63276ba..e8be8b615c6d85 100644 --- a/src/coreclr/jit/lowerxarch.cpp +++ b/src/coreclr/jit/lowerxarch.cpp @@ -470,7 +470,7 @@ void Lowering::ContainBlockStoreAddress(GenTreeBlk* blkNode, unsigned size, GenT // void Lowering::LowerPutArgStk(GenTreePutArgStk* putArgStk) { - GenTree* src = putArgStk->gtGetOp1(); + GenTree* src = putArgStk->Data(); bool srcIsLocal = src->OperIsLocalRead(); if (src->OperIs(GT_FIELD_LIST)) @@ -541,9 +541,11 @@ void Lowering::LowerPutArgStk(GenTreePutArgStk* putArgStk) #ifdef FEATURE_PUT_STRUCT_ARG_STK if (src->TypeIs(TYP_STRUCT)) { - ClassLayout* layout = src->AsObj()->GetLayout(); + assert(src->OperIs(GT_OBJ) || src->OperIsLocalRead()); + + ClassLayout* layout = src->GetLayout(comp); var_types regType = layout->GetRegisterType(); - srcIsLocal |= src->AsObj()->Addr()->OperIsLocalAddr(); + srcIsLocal |= src->OperIs(GT_OBJ) && src->AsObj()->Addr()->OperIsLocalAddr(); if (regType == TYP_UNDEF) { @@ -591,14 +593,25 @@ void Lowering::LowerPutArgStk(GenTreePutArgStk* putArgStk) #endif // !TARGET_X86 } - // Always mark the OBJ and ADDR as contained trees by the putarg_stk. The codegen will deal with this tree. - MakeSrcContained(putArgStk, src); if (src->OperIs(GT_OBJ) && src->AsObj()->Addr()->OperIsLocalAddr()) { - // If the source address is the address of a lclVar, make the source address contained to avoid - // unnecessary copies. - MakeSrcContained(putArgStk, src->AsObj()->Addr()); + // TODO-ADDR: always perform this transformation in local morph and delete this code. + GenTreeLclVarCommon* lclAddrNode = src->AsObj()->Addr()->AsLclVarCommon(); + BlockRange().Remove(lclAddrNode); + + src->ChangeOper(GT_LCL_FLD); + src->AsLclFld()->SetLclNum(lclAddrNode->GetLclNum()); + src->AsLclFld()->SetLclOffs(lclAddrNode->GetLclOffs()); + src->AsLclFld()->SetLayout(layout); } + else if (src->OperIs(GT_LCL_VAR)) + { + comp->lvaSetVarDoNotEnregister(src->AsLclVar()->GetLclNum() + DEBUGARG(DoNotEnregisterReason::IsStructArg)); + } + + // Always mark the OBJ/LCL_VAR/LCL_FLD as contained trees. + MakeSrcContained(putArgStk, src); } else { @@ -610,9 +623,13 @@ void Lowering::LowerPutArgStk(GenTreePutArgStk* putArgStk) regType = TYP_INT; } - src->SetOper(GT_IND); src->ChangeType(regType); - LowerIndir(src->AsIndir()); + + if (src->OperIs(GT_OBJ)) + { + src->SetOper(GT_IND); + LowerIndir(src->AsIndir()); + } } } From 344c79227e845a57eb86a57ce46e4f3c47961cfe Mon Sep 17 00:00:00 2001 From: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> Date: Wed, 15 Jun 2022 04:40:41 +0300 Subject: [PATCH 124/337] Allow `TYP_STRUCT` `LCL_FLD` on the RHS of block copies (#70633) * Delete the unused "GTF_USE_FLAGS" It used to indicate that a branch operation didn't need to materialize its operand and could just "use flags" instead, but that purpose has long been lost now that we have explicit SETCC nodes in lowering. * Make GTF_DONT_EXTEND a shared flag So that it can be used for "LCL_FLD" as well as "GT_IND". No diffs. * Enable TYP_STRUCT on the RHS * fgMorphBlockOperand * Tweak TYP_STRUCT LCL_FLD costs Model it as two load, like OBJ. Note we could be more precise here, by using the register type of the layout. For now, we defer. * Block CSE Preserve previous behavior to avoid diffs. --- src/coreclr/jit/codegenarm64.cpp | 2 +- src/coreclr/jit/codegenxarch.cpp | 14 ++------ src/coreclr/jit/decomposelongs.cpp | 3 -- src/coreclr/jit/gentree.cpp | 5 +++ src/coreclr/jit/gentree.h | 52 +++++++++++++++--------------- src/coreclr/jit/lclmorph.cpp | 30 ++++++++--------- src/coreclr/jit/lower.cpp | 21 ++++-------- src/coreclr/jit/lowerarmarch.cpp | 1 - src/coreclr/jit/morph.cpp | 5 +++ src/coreclr/jit/optcse.cpp | 5 +-- 10 files changed, 65 insertions(+), 73 deletions(-) diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index b891e640cad592..9bf45ab0ffad7f 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -10283,7 +10283,7 @@ void CodeGen::genCodeForAddEx(GenTreeOp* tree) void CodeGen::genCodeForCond(GenTreeOp* tree) { assert(tree->OperIs(GT_CSNEG_MI)); - assert(!(tree->gtFlags & GTF_SET_FLAGS) && (tree->gtFlags & GTF_USE_FLAGS)); + assert(!(tree->gtFlags & GTF_SET_FLAGS)); genConsumeOperands(tree); instruction ins; diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index e4123e64f5291a..4f709482128770 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -4755,7 +4755,8 @@ void CodeGen::genCodeForLclFld(GenTreeLclFld* tree) unsigned varNum = tree->GetLclNum(); assert(varNum < compiler->lvaCount); - GetEmitter()->emitIns_R_S(ins_Load(targetType), size, targetReg, varNum, offs); + instruction loadIns = tree->DontExtend() ? INS_mov : ins_Load(targetType); + GetEmitter()->emitIns_R_S(loadIns, size, targetReg, varNum, offs); genProduceReg(tree); } @@ -5106,16 +5107,7 @@ void CodeGen::genCodeForIndir(GenTreeIndir* tree) else { genConsumeAddress(addr); - instruction loadIns = ins_Load(targetType); - if (tree->DontExtend()) - { - assert(varTypeIsSmall(tree)); - // The user of this IND does not need - // the upper bits to be set, so we don't need to use longer - // INS_movzx/INS_movsx and can use INS_mov instead. - // It usually happens when the real type is a small struct. - loadIns = INS_mov; - } + instruction loadIns = tree->DontExtend() ? INS_mov : ins_Load(targetType); emit->emitInsLoadInd(loadIns, emitTypeSize(tree), tree->GetRegNum(), tree); } diff --git a/src/coreclr/jit/decomposelongs.cpp b/src/coreclr/jit/decomposelongs.cpp index 781afe9dfbf328..d3be8577df4b4a 100644 --- a/src/coreclr/jit/decomposelongs.cpp +++ b/src/coreclr/jit/decomposelongs.cpp @@ -931,7 +931,6 @@ GenTree* DecomposeLongs::DecomposeNeg(LIR::Use& use) Range().InsertAfter(loResult, zero, hiAdjust, hiResult); loResult->gtFlags |= GTF_SET_FLAGS; - hiAdjust->gtFlags |= GTF_USE_FLAGS; #elif defined(TARGET_ARM) @@ -942,7 +941,6 @@ GenTree* DecomposeLongs::DecomposeNeg(LIR::Use& use) Range().InsertAfter(loResult, hiResult); loResult->gtFlags |= GTF_SET_FLAGS; - hiResult->gtFlags |= GTF_USE_FLAGS; #endif @@ -997,7 +995,6 @@ GenTree* DecomposeLongs::DecomposeArith(LIR::Use& use) if ((oper == GT_ADD) || (oper == GT_SUB)) { loResult->gtFlags |= GTF_SET_FLAGS; - hiResult->gtFlags |= GTF_USE_FLAGS; if ((loResult->gtFlags & GTF_OVERFLOW) != 0) { diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 61144862e338b3..33f6db9749f21a 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -4680,6 +4680,11 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) costEx += 1; costSz += 1; } + else if (tree->TypeIs(TYP_STRUCT)) + { + costEx += IND_COST_EX; + costSz += 2; + } break; case GT_LCL_FLD_ADDR: diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index aa7dba1b2a346b..69e6b88df49727 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -408,7 +408,12 @@ enum GenTreeFlags : unsigned int GTF_NOREG_AT_USE = 0x00000100, // tree node is in memory at the point of use GTF_SET_FLAGS = 0x00000200, // Requires that codegen for this node set the flags. Use gtSetFlags() to check this flag. - GTF_USE_FLAGS = 0x00000400, // Indicates that this node uses the flags bits. + +#ifdef TARGET_XARCH + GTF_DONT_EXTEND = 0x00000400, // This small-typed tree produces a value with undefined upper bits. Used on x86/x64 as a + // lowering optimization and tells the codegen to use instructions like "mov al, [addr]" + // instead of "movzx/movsx", when the user node doesn't need the upper bits. +#endif // TARGET_XARCH GTF_MAKE_CSE = 0x00000800, // Hoisted expression: try hard to make this into CSE (see optPerformHoistExpr) GTF_DONT_CSE = 0x00001000, // Don't bother CSE'ing this expr @@ -526,16 +531,9 @@ enum GenTreeFlags : unsigned int // alignment of 1 byte) GTF_IND_INVARIANT = 0x01000000, // GT_IND -- the target is invariant (a prejit indirection) GTF_IND_NONNULL = 0x00400000, // GT_IND -- the indirection never returns null (zero) -#if defined(TARGET_XARCH) - GTF_IND_DONT_EXTEND = 0x00200000, // GT_IND -- the indirection does not need to extend for small types -#endif // TARGET_XARCH GTF_IND_FLAGS = GTF_IND_VOLATILE | GTF_IND_NONFAULTING | GTF_IND_TLS_REF | GTF_IND_UNALIGNED | GTF_IND_INVARIANT | - GTF_IND_NONNULL | GTF_IND_TGT_NOT_HEAP | GTF_IND_TGT_HEAP -#if defined(TARGET_XARCH) - | GTF_IND_DONT_EXTEND -#endif // TARGET_XARCH - , + GTF_IND_NONNULL | GTF_IND_TGT_NOT_HEAP | GTF_IND_TGT_HEAP, GTF_ADDRMODE_NO_CSE = 0x80000000, // GT_ADD/GT_MUL/GT_LSH -- Do not CSE this node only, forms complex // addressing mode @@ -2007,6 +2005,25 @@ struct GenTree gtFlags &= ~GTF_REVERSE_OPS; } +#if defined(TARGET_XARCH) + void SetDontExtend() + { + assert(varTypeIsSmall(TypeGet()) && OperIs(GT_IND, GT_LCL_FLD)); + gtFlags |= GTF_DONT_EXTEND; + } + + void ClearDontExtend() + { + gtFlags &= ~GTF_DONT_EXTEND; + } + + bool DontExtend() const + { + assert(varTypeIsSmall(TypeGet()) || ((gtFlags & GTF_DONT_EXTEND) == 0)); + return (gtFlags & GTF_DONT_EXTEND) != 0; + } +#endif // TARGET_XARCH + bool IsUnsigned() const { return ((gtFlags & GTF_UNSIGNED) != 0); @@ -6762,23 +6779,6 @@ struct GenTreeIndir : public GenTreeOp return (gtFlags & GTF_IND_UNALIGNED) != 0; } -#if defined(TARGET_XARCH) - void SetDontExtend() - { - gtFlags |= GTF_IND_DONT_EXTEND; - } - - void ClearDontExtend() - { - gtFlags &= ~GTF_IND_DONT_EXTEND; - } - - bool DontExtend() const - { - return (gtFlags & GTF_IND_DONT_EXTEND) != 0; - } -#endif // TARGET_XARCH - #if DEBUGGABLE_GENTREE // Used only for GenTree::GetVtableForOper() GenTreeIndir() : GenTreeOp() diff --git a/src/coreclr/jit/lclmorph.cpp b/src/coreclr/jit/lclmorph.cpp index 358383b6afece7..5629c19b5db48b 100644 --- a/src/coreclr/jit/lclmorph.cpp +++ b/src/coreclr/jit/lclmorph.cpp @@ -1098,21 +1098,21 @@ class LocalAddressVisitor final : public GenTreeVisitor // Current matrix of matches/users/types: // - // |------------|------|---------|---------| - // | STRUCT | CALL | ASG | RETURN | - // |------------|------|---------|---------| - // | Exact | None | LCL_VAR | LCL_VAR | - // | Compatible | None | LCL_VAR | LCL_VAR | - // | Partial | None | OBJ | LCL_FLD | - // |------------|------|---------|---------| + // |------------|------|-------------|---------| + // | STRUCT | CALL | ASG | RETURN | + // |------------|------|-------------|---------| + // | Exact | None | LCL_VAR | LCL_VAR | + // | Compatible | None | LCL_VAR | LCL_VAR | + // | Partial | None | OBJ/LCL_FLD | LCL_FLD | + // |------------|------|-------------|---------| // - // |------------|------|---------|---------|----------| - // | SIMD | CALL | ASG | RETURN | HWI/SIMD | - // |------------|------|---------|---------|----------| - // | Exact | None | None | None | None | - // | Compatible | None | None | None | None | - // | Partial | None | None | None | None | - // |------------|------|---------|---------|----------| + // |------------|------|------|--------|----------| + // | SIMD | CALL | ASG | RETURN | HWI/SIMD | + // |------------|------|------|--------|----------| + // | Exact | None | None | None | None | + // | Compatible | None | None | None | None | + // | Partial | None | None | None | None | + // |------------|------|------|--------|----------| // // TODO-ADDR: delete all the "None" entries and always // transform local nodes into LCL_VAR or LCL_FLD. @@ -1126,7 +1126,7 @@ class LocalAddressVisitor final : public GenTreeVisitor return IndirTransform::LclVar; } - if (user->OperIs(GT_ASG)) + if (user->OperIs(GT_ASG) && (indir == user->AsOp()->gtGetOp1())) { return IndirTransform::ObjAddrLclFld; } diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index 393b31478024e7..fb8e0104d34d7c 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -1013,7 +1013,6 @@ bool Lowering::TryLowerSwitchToBitTest( GenTree* bitTest = comp->gtNewOperNode(GT_BT, TYP_VOID, bitTableIcon, switchValue); bitTest->gtFlags |= GTF_SET_FLAGS; GenTreeCC* jcc = new (comp, GT_JCC) GenTreeCC(GT_JCC, bbSwitchCondition); - jcc->gtFlags |= GTF_USE_FLAGS; LIR::AsRange(bbSwitch).InsertAfter(switchValue, bitTableIcon, bitTest, jcc); @@ -2703,7 +2702,6 @@ GenTree* Lowering::DecomposeLongCompare(GenTree* cmp) GenTree* jcc = cmpUse.User(); jcc->AsOp()->gtOp1 = nullptr; jcc->ChangeOper(GT_JCC); - jcc->gtFlags |= GTF_USE_FLAGS; jcc->AsCC()->gtCondition = GenCondition::FromIntegralRelop(condition, cmp->IsUnsigned()); } else @@ -2711,7 +2709,6 @@ GenTree* Lowering::DecomposeLongCompare(GenTree* cmp) cmp->AsOp()->gtOp1 = nullptr; cmp->AsOp()->gtOp2 = nullptr; cmp->ChangeOper(GT_SETCC); - cmp->gtFlags |= GTF_USE_FLAGS; cmp->AsCC()->gtCondition = GenCondition::FromIntegralRelop(condition, cmp->IsUnsigned()); } @@ -2959,8 +2956,6 @@ GenTree* Lowering::OptimizeConstCompare(GenTree* cmp) cmpUse.ReplaceWith(cc); } - cc->gtFlags |= GTF_USE_FLAGS; - return cmp->gtNext; } #endif // TARGET_XARCH @@ -3028,7 +3023,6 @@ GenTree* Lowering::OptimizeConstCompare(GenTree* cmp) GenCondition condition = GenCondition::FromIntegralRelop(cmp); cc->ChangeOper(ccOp); cc->AsCC()->gtCondition = condition; - cc->gtFlags |= GTF_USE_FLAGS; return next; } @@ -3246,7 +3240,6 @@ GenTreeCC* Lowering::LowerNodeCC(GenTree* node, GenCondition condition) if (cc != nullptr) { node->gtFlags |= GTF_SET_FLAGS; - cc->gtFlags |= GTF_USE_FLAGS; } // Remove the chain of EQ/NE(x, 0) relop nodes, if any. Note that if a SETCC was @@ -3515,13 +3508,13 @@ void Lowering::LowerStoreLocCommon(GenTreeLclVarCommon* lclStore) // Do it now. GenTreeIndir* indir = src->AsIndir(); LowerIndir(indir); + } #if defined(TARGET_XARCH) - if (varTypeIsSmall(lclRegType)) - { - indir->SetDontExtend(); - } -#endif // TARGET_XARCH + if (varTypeIsSmall(lclRegType)) + { + src->SetDontExtend(); } +#endif // TARGET_XARCH } convertToStoreObj = false; #else // TARGET_ARM64 @@ -7351,9 +7344,9 @@ bool Lowering::TryTransformStoreObjAsStoreInd(GenTreeBlk* blkNode) } #if defined(TARGET_XARCH) - if (varTypeIsSmall(regType) && src->OperIs(GT_IND)) + if (varTypeIsSmall(regType) && src->OperIs(GT_IND, GT_LCL_FLD)) { - src->AsIndir()->SetDontExtend(); + src->SetDontExtend(); } #endif // TARGET_XARCH diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp index 177034fabe709b..8598efb8adbec9 100644 --- a/src/coreclr/jit/lowerarmarch.cpp +++ b/src/coreclr/jit/lowerarmarch.cpp @@ -760,7 +760,6 @@ void Lowering::LowerModPow2(GenTree* node) mod->ChangeOper(GT_CSNEG_MI); mod->gtOp1 = trueExpr; mod->gtOp2 = falseExpr; - mod->gtFlags |= GTF_USE_FLAGS; JITDUMP("Lower: optimize X MOD POW2"); DISPNODE(mod); diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index d8a0fed4d1d029..61230a0e8292c8 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -9681,6 +9681,11 @@ GenTree* Compiler::fgMorphBlockOperand(GenTree* tree, var_types asgType, ClassLa { lclNode = effectiveVal->AsLclVarCommon(); } + else if (effectiveVal->OperIs(GT_LCL_FLD)) + { + needsIndirection = false; + assert(ClassLayout::AreCompatible(effectiveVal->AsLclFld()->GetLayout(), blockLayout)); + } else if (effectiveVal->IsCall()) { needsIndirection = false; diff --git a/src/coreclr/jit/optcse.cpp b/src/coreclr/jit/optcse.cpp index 6898c5ae62a44d..6bbb6fcb3e0cfa 100644 --- a/src/coreclr/jit/optcse.cpp +++ b/src/coreclr/jit/optcse.cpp @@ -3584,7 +3584,6 @@ bool Compiler::optIsCSEcandidate(GenTree* tree) case GT_ARR_ELEM: case GT_ARR_LENGTH: - case GT_LCL_FLD: return true; case GT_LCL_VAR: @@ -3687,7 +3686,9 @@ bool Compiler::optIsCSEcandidate(GenTree* tree) return true; // allow Intrinsics to be CSE-ed case GT_OBJ: - return varTypeIsEnregisterable(type); // Allow enregisterable GT_OBJ's to be CSE-ed. (i.e. SIMD types) + case GT_LCL_FLD: + // TODO-1stClassStructs: support CSE for enregisterable TYP_STRUCTs. + return varTypeIsEnregisterable(type); case GT_COMMA: return true; // Allow GT_COMMA nodes to be CSE-ed. From eeb0c1551b5fc9ccd6ceeaf5d2b1504afab249d7 Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Wed, 15 Jun 2022 04:32:53 +0200 Subject: [PATCH 125/337] Revert "Fix usage of GSS_KRB5_CRED_NO_CI_FLAGS_X (#70447)" (#70747) This reverts commit 84f7cad00ad834c365b5cd1297e1166525146b50. --- .../System.Net.Security.Native/pal_gssapi.c | 70 ++++--------------- src/native/libs/configure.cmake | 13 ---- 2 files changed, 15 insertions(+), 68 deletions(-) diff --git a/src/native/libs/System.Net.Security.Native/pal_gssapi.c b/src/native/libs/System.Net.Security.Native/pal_gssapi.c index 9d0c2fce2c4a56..6206fa0fa0ce42 100644 --- a/src/native/libs/System.Net.Security.Native/pal_gssapi.c +++ b/src/native/libs/System.Net.Security.Native/pal_gssapi.c @@ -58,21 +58,7 @@ static gss_OID_desc gss_mech_ntlm_OID_desc = {.length = STRING_LENGTH(gss_ntlm_o #if defined(GSS_SHIM) -#if HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X - -#define FOR_ALL_OPTIONAL_GSS_FUNCTIONS \ - PER_FUNCTION_BLOCK(gss_set_cred_option) \ - PER_FUNCTION_BLOCK(GSS_KRB5_CRED_NO_CI_FLAGS_X) - -#define GSS_KRB5_CRED_NO_CI_FLAGS_X_AVAILABLE (gss_set_cred_option_ptr != NULL && GSS_KRB5_CRED_NO_CI_FLAGS_X_ptr != NULL) - -#else - -#define FOR_ALL_OPTIONAL_GSS_FUNCTIONS - -#endif //HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X - -#define FOR_ALL_REQUIRED_GSS_FUNCTIONS \ +#define FOR_ALL_GSS_FUNCTIONS \ PER_FUNCTION_BLOCK(gss_accept_sec_context) \ PER_FUNCTION_BLOCK(gss_acquire_cred) \ PER_FUNCTION_BLOCK(gss_acquire_cred_with_password) \ @@ -92,11 +78,14 @@ static gss_OID_desc gss_mech_ntlm_OID_desc = {.length = STRING_LENGTH(gss_ntlm_o PER_FUNCTION_BLOCK(gss_unwrap) \ PER_FUNCTION_BLOCK(gss_wrap) \ PER_FUNCTION_BLOCK(GSS_C_NT_USER_NAME) \ - PER_FUNCTION_BLOCK(GSS_C_NT_HOSTBASED_SERVICE) \ + PER_FUNCTION_BLOCK(GSS_C_NT_HOSTBASED_SERVICE) -#define FOR_ALL_GSS_FUNCTIONS \ - FOR_ALL_REQUIRED_GSS_FUNCTIONS \ - FOR_ALL_OPTIONAL_GSS_FUNCTIONS +#if HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X + +#define FOR_ALL_GSS_FUNCTIONS FOR_ALL_GSS_FUNCTIONS \ + PER_FUNCTION_BLOCK(gss_set_cred_option) + +#endif //HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X // define indirection pointers for all functions, like // static TYPEOF(gss_accept_sec_context)* gss_accept_sec_context_ptr; @@ -129,7 +118,6 @@ static void* volatile s_gssLib = NULL; #if HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X #define gss_set_cred_option(...) gss_set_cred_option_ptr(__VA_ARGS__) -#define GSS_KRB5_CRED_NO_CI_FLAGS_X (*GSS_KRB5_CRED_NO_CI_FLAGS_X_ptr) #endif //HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X @@ -150,27 +138,19 @@ static int32_t ensure_gss_shim_initialized() dlclose(lib); } - // initialize indirection pointers for all required functions, like: + // initialize indirection pointers for all functions, like: // gss_accept_sec_context_ptr = (TYPEOF(gss_accept_sec_context)*)dlsym(s_gssLib, "gss_accept_sec_context"); // if (gss_accept_sec_context_ptr == NULL) { fprintf(stderr, "Cannot get symbol %s from %s \nError: %s\n", "gss_accept_sec_context", gss_lib_name, dlerror()); return -1; } #define PER_FUNCTION_BLOCK(fn) \ fn##_ptr = (TYPEOF(fn)*)dlsym(s_gssLib, #fn); \ if (fn##_ptr == NULL) { fprintf(stderr, "Cannot get symbol " #fn " from %s \nError: %s\n", gss_lib_name, dlerror()); return -1; } -FOR_ALL_REQUIRED_GSS_FUNCTIONS -#undef PER_FUNCTION_BLOCK - // for optional functions skip the error check -#define PER_FUNCTION_BLOCK(fn) \ - fn##_ptr = (TYPEOF(fn)*)dlsym(s_gssLib, #fn); -FOR_ALL_OPTIONAL_GSS_FUNCTIONS + + FOR_ALL_GSS_FUNCTIONS #undef PER_FUNCTION_BLOCK return 0; } -#else // GSS_SHIM - -#define GSS_KRB5_CRED_NO_CI_FLAGS_X_AVAILABLE 1 - #endif // GSS_SHIM // transfers ownership of the underlying data from gssBuffer to PAL_GssBuffer @@ -203,20 +183,10 @@ static uint32_t AcquireCredSpNego(uint32_t* minorStatus, // call gss_set_cred_option with GSS_KRB5_CRED_NO_CI_FLAGS_X to support Kerberos Sign Only option from *nix client against a windows server #if HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X - if (majorStatus == GSS_S_COMPLETE && GSS_KRB5_CRED_NO_CI_FLAGS_X_AVAILABLE) + if (majorStatus == GSS_S_COMPLETE) { GssBuffer emptyBuffer = GSS_C_EMPTY_BUFFER; - uint32_t tempMinorStatus; - majorStatus = gss_set_cred_option(&tempMinorStatus, outputCredHandle, GSS_KRB5_CRED_NO_CI_FLAGS_X, &emptyBuffer); - if (majorStatus == GSS_S_UNAVAILABLE || majorStatus == GSS_S_COMPLETE) - { - // preserve the original majorStatus/minorStatus from gss_acquire_cred - majorStatus = GSS_S_COMPLETE; - } - else - { - *minorStatus = tempMinorStatus; - } + majorStatus = gss_set_cred_option(minorStatus, outputCredHandle, GSS_KRB5_CRED_NO_CI_FLAGS_X, &emptyBuffer); } #endif @@ -636,20 +606,10 @@ static uint32_t AcquireCredWithPassword(uint32_t* minorStatus, // call gss_set_cred_option with GSS_KRB5_CRED_NO_CI_FLAGS_X to support Kerberos Sign Only option from *nix client against a windows server #if HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X - if (!isNtlm && majorStatus == GSS_S_COMPLETE && GSS_KRB5_CRED_NO_CI_FLAGS_X_AVAILABLE) + if (majorStatus == GSS_S_COMPLETE) { GssBuffer emptyBuffer = GSS_C_EMPTY_BUFFER; - uint32_t tempMinorStatus; - majorStatus = gss_set_cred_option(&tempMinorStatus, outputCredHandle, GSS_KRB5_CRED_NO_CI_FLAGS_X, &emptyBuffer); - if (majorStatus == GSS_S_UNAVAILABLE || majorStatus == GSS_S_COMPLETE) - { - // preserve the original majorStatus/minorStatus from gss_acquire_cred_with_password - majorStatus = GSS_S_COMPLETE; - } - else - { - *minorStatus = tempMinorStatus; - } + majorStatus = gss_set_cred_option(minorStatus, outputCredHandle, GSS_KRB5_CRED_NO_CI_FLAGS_X, &emptyBuffer); } #endif diff --git a/src/native/libs/configure.cmake b/src/native/libs/configure.cmake index 4559017946f488..8567842366bc5a 100644 --- a/src/native/libs/configure.cmake +++ b/src/native/libs/configure.cmake @@ -1030,17 +1030,6 @@ check_include_files( GSS/GSS.h HAVE_GSSFW_HEADERS) -if (HAVE_GSSFW_HEADERS) - find_library(LIBGSS NAMES GSS) -elseif (HAVE_HEIMDAL_HEADERS) - find_library(LIBGSS NAMES gssapi) -else () - find_library(LIBGSS NAMES gssapi_krb5) -endif () - -set (PREVIOUS_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}) -set (CMAKE_REQUIRED_LIBRARIES ${LIBGSS}) - if (HAVE_GSSFW_HEADERS) check_symbol_exists( GSS_SPNEGO_MECHANISM @@ -1065,8 +1054,6 @@ else () HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X) endif () -set (CMAKE_REQUIRED_LIBRARIES ${PREVIOUS_CMAKE_REQUIRED_LIBRARIES}) - check_symbol_exists(getauxval sys/auxv.h HAVE_GETAUXVAL) check_include_files(crt_externs.h HAVE_CRT_EXTERNS_H) From 1abd9a166d9d2a2b26b11df6579d677666c1e2cb Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Tue, 14 Jun 2022 20:19:07 -0700 Subject: [PATCH 126/337] Add note about backward branch constraints to ECMA-335 augments (#70760) --- docs/design/specs/Ecma-335-Augments.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/design/specs/Ecma-335-Augments.md b/docs/design/specs/Ecma-335-Augments.md index c0e56c9fa04cf0..876d4a62f58aaa 100644 --- a/docs/design/specs/Ecma-335-Augments.md +++ b/docs/design/specs/Ecma-335-Augments.md @@ -17,6 +17,7 @@ This is a list of additions and edits to be made in ECMA-335 specifications. It - [Rules for IL rewriters](#rules-for-il-rewriters) - [Checked user-defined operators](#checked-user-defined-operators) - [Atomic reads and writes](#atomic-reads-and-writes) +- [Backward branch constraints](#backward-branch-constraints) ## Signatures @@ -1020,3 +1021,7 @@ A checked user-defined operator is expected to throw an exception when the resul Section "I.12.6.6 Atomic reads and writes" adds clarification that the atomicity guarantees apply to built-in primitive value types and pointers only. A conforming CLI shall guarantee that read and write access of *built-in primitive value types and pointers* to properly aligned memory locations no larger than the native word size (the size of type native int) is atomic (see §I.12.6.2) when all the write accesses to a location are the same size. + +## Backward branch constraints + +Section "II.1.7.5 Backward branch constraints" is deleted. These constraints were not enforced by any mainstream .NET runtime and they are not respected by .NET compilers. It means that it is not possible to infer the exact state of the evaluation stack at every instruction with a single forward-pass through the CIL instruction stream. From e30570d90fb609b6fc6410942e4db9446656ce09 Mon Sep 17 00:00:00 2001 From: Vladimir Sadov Date: Tue, 14 Jun 2022 22:57:42 -0700 Subject: [PATCH 127/337] [NativeAOT] Enabling return address hijacking on ARM64 Windows (#70740) * Enabling return address hijacking on ARM64 Windows * pass right flags to the GcInfoDecoder --- .../Runtime/windows/CoffNativeCodeManager.cpp | 61 ++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/src/coreclr/nativeaot/Runtime/windows/CoffNativeCodeManager.cpp b/src/coreclr/nativeaot/Runtime/windows/CoffNativeCodeManager.cpp index 4010dbea5241fe..7738a7455c757c 100644 --- a/src/coreclr/nativeaot/Runtime/windows/CoffNativeCodeManager.cpp +++ b/src/coreclr/nativeaot/Runtime/windows/CoffNativeCodeManager.cpp @@ -693,7 +693,6 @@ bool CoffNativeCodeManager::GetReturnAddressHijackInfo(MethodInfo * pMethodIn PTR_PTR_VOID * ppvRetAddrLocation, // out GCRefKind * pRetValueKind) // out { -#if defined(TARGET_AMD64) CoffNativeMethodInfo * pNativeMethodInfo = (CoffNativeMethodInfo *)pMethodInfo; size_t unwindDataBlobSize; @@ -719,7 +718,11 @@ bool CoffNativeCodeManager::GetReturnAddressHijackInfo(MethodInfo * pMethodIn p += sizeof(int32_t); // Decode the GC info for the current method to determine its return type - GcInfoDecoder decoder(GCInfoToken(p), DECODE_RETURN_KIND); + GcInfoDecoderFlags flags = DECODE_RETURN_KIND; +#if defined(TARGET_ARM) || defined(TARGET_ARM64) + flags = (GcInfoDecoderFlags)(flags | DECODE_HAS_TAILCALLS); +#endif // TARGET_ARM || TARGET_ARM64 + GcInfoDecoder decoder(GCInfoToken(p), flags); GCRefKind gcRefKind = GetGcRefKind(decoder.GetReturnKind()); @@ -728,6 +731,11 @@ bool CoffNativeCodeManager::GetReturnAddressHijackInfo(MethodInfo * pMethodIn SIZE_T EstablisherFrame; PVOID HandlerData; CONTEXT context; +#ifdef _DEBUG + memset(&context, 0xDD, sizeof(context)); +#endif + +#if defined(TARGET_AMD64) context.Rsp = pRegisterSet->GetSP(); context.Rbp = pRegisterSet->GetFP(); context.Rip = pRegisterSet->GetIP(); @@ -744,6 +752,55 @@ bool CoffNativeCodeManager::GetReturnAddressHijackInfo(MethodInfo * pMethodIn *ppvRetAddrLocation = (PTR_PTR_VOID)(context.Rsp - sizeof (PVOID)); *pRetValueKind = gcRefKind; return true; +#elif defined(TARGET_ARM64) + + if (decoder.HasTailCalls()) + { + // Do not hijack functions that have tail calls, since there are two problems: + // 1. When a function that tail calls another one is hijacked, the LR may be + // stored at a different location in the stack frame of the tail call target. + // So just by performing tail call, the hijacked location becomes invalid and + // unhijacking would corrupt stack by writing to that location. + // 2. There is a small window after the caller pops LR from the stack in its + // epilog and before the tail called function pushes LR in its prolog when + // the hijacked return address would not be not on the stack and so we would + // not be able to unhijack. + return false; + } + + context.Sp = pRegisterSet->GetSP(); + context.Fp = pRegisterSet->GetFP(); + context.Pc = pRegisterSet->GetIP(); + context.Lr = *pRegisterSet->pLR; + + KNONVOLATILE_CONTEXT_POINTERS contextPointers; +#ifdef _DEBUG + memset(&contextPointers, 0xDD, sizeof(contextPointers)); +#endif + contextPointers.Lr = pRegisterSet->pLR; + + RtlVirtualUnwind(NULL, + dac_cast(m_moduleBase), + pRegisterSet->IP, + (PRUNTIME_FUNCTION)pNativeMethodInfo->runtimeFunction, + &context, + &HandlerData, + &EstablisherFrame, + &contextPointers); + + if (contextPointers.Lr == pRegisterSet->pLR) + { + // This is the case when we are either: + // + // 1) In a leaf method that does not push LR on stack, OR + // 2) In the prolog/epilog of a non-leaf method that has not yet pushed LR on stack + // or has LR already popped off. + return false; + } + + *ppvRetAddrLocation = (PTR_PTR_VOID)contextPointers.Lr; + *pRetValueKind = gcRefKind; + return true; #else return false; #endif // defined(TARGET_AMD64) From cd60639f541c736c4a4de8eac0fccae098d34981 Mon Sep 17 00:00:00 2001 From: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> Date: Wed, 15 Jun 2022 11:41:35 +0300 Subject: [PATCH 128/337] Fix value numbering of HWI loads (#70621) * Fix numbering of HWI loads Take into account all operands and describe the exception sets precisely. * Add a test * Recast the check --- src/coreclr/jit/gentree.cpp | 171 +++++++++---- src/coreclr/jit/gentree.h | 13 +- src/coreclr/jit/valuenum.cpp | 240 ++++++++++-------- src/coreclr/jit/valuenum.h | 5 +- .../General/HwiOp/HwiValueNumbering.cs | 218 ++++++++++++++++ .../General/HwiOp/HwiValueNumbering.csproj | 11 + 6 files changed, 503 insertions(+), 155 deletions(-) create mode 100644 src/tests/JIT/HardwareIntrinsics/General/HwiOp/HwiValueNumbering.cs create mode 100644 src/tests/JIT/HardwareIntrinsics/General/HwiOp/HwiValueNumbering.csproj diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 33f6db9749f21a..9e56b90be61a43 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -18457,14 +18457,16 @@ var_types GenTreeJitIntrinsic::GetSimdBaseType() const return JitType2PreciseVarType(simdBaseJitType); } -// Returns true for the SIMD Intrinsic instructions that have MemoryLoad semantics, false otherwise +//------------------------------------------------------------------------ +// OperIsMemoryLoad: Does this SIMD intrinsic have memory load semantics? +// +// Return Value: +// Whether this intrinsic may throw NullReferenceException if the +// address is "null". +// bool GenTreeSIMD::OperIsMemoryLoad() const { - if (GetSIMDIntrinsicId() == SIMDIntrinsicInitArray) - { - return true; - } - return false; + return GetSIMDIntrinsicId() == SIMDIntrinsicInitArray; } // TODO-Review: why are layouts not compared here? @@ -22463,26 +22465,56 @@ GenTreeHWIntrinsic* Compiler::gtNewScalarHWIntrinsicNode( /* isSimdAsHWIntrinsic */ false, op1, op2, op3); } -// Returns true for the HW Intrinsic instructions that have MemoryLoad semantics, false otherwise -bool GenTreeHWIntrinsic::OperIsMemoryLoad() const +//------------------------------------------------------------------------ +// OperIsMemoryLoad: Does this HWI node have memory load semantics? +// +// Arguments: +// pAddr - optional [out] parameter for the address +// +// Return Value: +// Whether this intrinsic may throw NullReferenceException if the +// address is "null". +// +bool GenTreeHWIntrinsic::OperIsMemoryLoad(GenTree** pAddr) const { + GenTree* addr = nullptr; + #if defined(TARGET_XARCH) || defined(TARGET_ARM64) NamedIntrinsic intrinsicId = GetHWIntrinsicId(); HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsicId); if (category == HW_Category_MemoryLoad) { - return true; + switch (intrinsicId) + { +#ifdef TARGET_XARCH + case NI_SSE_LoadLow: + case NI_SSE_LoadHigh: + case NI_SSE2_LoadLow: + case NI_SSE2_LoadHigh: + addr = Op(2); + break; +#endif // TARGET_XARCH + +#ifdef TARGET_ARM64 + case NI_AdvSimd_LoadAndInsertScalar: + addr = Op(3); + break; +#endif // TARGET_ARM64 + + default: + addr = Op(1); + break; + } } #ifdef TARGET_XARCH - else if (HWIntrinsicInfo::MaybeMemoryLoad(GetHWIntrinsicId())) + else if (HWIntrinsicInfo::MaybeMemoryLoad(intrinsicId)) { // Some intrinsics (without HW_Category_MemoryLoad) also have MemoryLoad semantics // This is generally because they have both vector and pointer overloads, e.g., // * Vector128 BroadcastScalarToVector128(Vector128 value) // * Vector128 BroadcastScalarToVector128(byte* source) - // So, we need to check the argument's type is memory-reference or Vector128 - + // if ((category == HW_Category_SimpleSIMD) || (category == HW_Category_SIMDScalar)) { assert(GetOperandCount() == 1); @@ -22497,53 +22529,91 @@ bool GenTreeHWIntrinsic::OperIsMemoryLoad() const case NI_AVX2_ConvertToVector256Int16: case NI_AVX2_ConvertToVector256Int32: case NI_AVX2_ConvertToVector256Int64: - { - CorInfoType auxiliaryType = GetAuxiliaryJitType(); - - if (auxiliaryType == CORINFO_TYPE_PTR) + if (GetAuxiliaryJitType() == CORINFO_TYPE_PTR) { - return true; + addr = Op(1); } - - assert(auxiliaryType == CORINFO_TYPE_UNDEF); - return false; - } + else + { + assert(GetAuxiliaryJitType() == CORINFO_TYPE_UNDEF); + } + break; default: - { unreached(); - } } } else if (category == HW_Category_IMM) { - // Do we have less than 3 operands? - if (GetOperandCount() < 3) - { - return false; - } - else if (HWIntrinsicInfo::isAVX2GatherIntrinsic(GetHWIntrinsicId())) + switch (intrinsicId) { - return true; + case NI_AVX2_GatherVector128: + case NI_AVX2_GatherVector256: + addr = Op(1); + break; + + case NI_AVX2_GatherMaskVector128: + case NI_AVX2_GatherMaskVector256: + addr = Op(2); + break; + + default: + break; } } } #endif // TARGET_XARCH #endif // TARGET_XARCH || TARGET_ARM64 + + if (pAddr != nullptr) + { + *pAddr = addr; + } + + if (addr != nullptr) + { + assert(varTypeIsI(addr)); + return true; + } + return false; } -// Returns true for the HW Intrinsic instructions that have MemoryStore semantics, false otherwise -bool GenTreeHWIntrinsic::OperIsMemoryStore() const +//------------------------------------------------------------------------ +// OperIsMemoryLoad: Does this HWI node have memory store semantics? +// +// Arguments: +// pAddr - optional [out] parameter for the address +// +// Return Value: +// Whether this intrinsic may mutate heap state and/or throw a +// NullReferenceException if the address is "null". +// +bool GenTreeHWIntrinsic::OperIsMemoryStore(GenTree** pAddr) const { + GenTree* addr = nullptr; + #if defined(TARGET_XARCH) || defined(TARGET_ARM64) - HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(GetHWIntrinsicId()); + NamedIntrinsic intrinsicId = GetHWIntrinsicId(); + HWIntrinsicCategory category = HWIntrinsicInfo::lookupCategory(intrinsicId); + if (category == HW_Category_MemoryStore) { - return true; + switch (intrinsicId) + { +#ifdef TARGET_XARCH + case NI_SSE2_MaskMove: + addr = Op(3); + break; +#endif // TARGET_XARCH + + default: + addr = Op(1); + break; + } } #ifdef TARGET_XARCH - else if (HWIntrinsicInfo::MaybeMemoryStore(GetHWIntrinsicId()) && + else if (HWIntrinsicInfo::MaybeMemoryStore(intrinsicId) && (category == HW_Category_IMM || category == HW_Category_Scalar)) { // Some intrinsics (without HW_Category_MemoryStore) also have MemoryStore semantics @@ -22554,29 +22624,44 @@ bool GenTreeHWIntrinsic::OperIsMemoryStore() const // So, the 3-argument form is MemoryStore if (GetOperandCount() == 3) { - switch (GetHWIntrinsicId()) + switch (intrinsicId) { case NI_BMI2_MultiplyNoFlags: case NI_BMI2_X64_MultiplyNoFlags: - return true; + addr = Op(3); + break; + default: - return false; + break; } } } #endif // TARGET_XARCH #endif // TARGET_XARCH || TARGET_ARM64 + + if (pAddr != nullptr) + { + *pAddr = addr; + } + + if (addr != nullptr) + { + assert(varTypeIsI(addr)); + return true; + } + return false; } -// Returns true for the HW Intrinsic instructions that have MemoryLoad or MemoryStore semantics, false otherwise +//------------------------------------------------------------------------ +// OperIsMemoryLoadOrStore: Does this HWI node have memory load or store semantics? +// +// Return Value: +// Whether "this" is "OperIsMemoryLoad" or "OperIsMemoryStore". +// bool GenTreeHWIntrinsic::OperIsMemoryLoadOrStore() const { -#if defined(TARGET_XARCH) || defined(TARGET_ARM64) return OperIsMemoryLoad() || OperIsMemoryStore(); -#else - return false; -#endif } NamedIntrinsic GenTreeHWIntrinsic::GetHWIntrinsicId() const diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index 69e6b88df49727..ff72fae3378d16 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -6084,8 +6084,7 @@ struct GenTreeSIMD : public GenTreeJitIntrinsic } #endif - bool OperIsMemoryLoad() const; // Returns true for the SIMD Intrinsic instructions that have MemoryLoad semantics, - // false otherwise + bool OperIsMemoryLoad() const; SIMDIntrinsicID GetSIMDIntrinsicId() const { @@ -6129,12 +6128,10 @@ struct GenTreeHWIntrinsic : public GenTreeJitIntrinsic } #endif - bool OperIsMemoryLoad() const; // Returns true for the HW Intrinsic instructions that have MemoryLoad semantics, - // false otherwise - bool OperIsMemoryStore() const; // Returns true for the HW Intrinsic instructions that have MemoryStore semantics, - // false otherwise - bool OperIsMemoryLoadOrStore() const; // Returns true for the HW Intrinsic instructions that have MemoryLoad or - // MemoryStore semantics, false otherwise + bool OperIsMemoryLoad(GenTree** pAddr = nullptr) const; + bool OperIsMemoryStore(GenTree** pAddr = nullptr) const; + bool OperIsMemoryLoadOrStore() const; + bool IsSimdAsHWIntrinsic() const { return (gtFlags & GTF_SIMDASHW_OP) != 0; diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 295d3339dfe206..3ec54f47e886f6 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -4312,14 +4312,14 @@ ValueNum ValueNumStore::EvalUsingMathIdentity(var_types typ, VNFunc func, ValueN // Arguments: // block - BasicBlock where the expression that produces this value occurs. // May be nullptr to force conservative "could be anywhere" interpretation. -// typ - Type of the expression in the IR +// type - Type of the expression in the IR // // Return Value: // A new value number distinct from any previously generated, that compares as equal // to itself, but not any other value number, and is annotated with the given // type and block. - -ValueNum ValueNumStore::VNForExpr(BasicBlock* block, var_types typ) +// +ValueNum ValueNumStore::VNForExpr(BasicBlock* block, var_types type) { BasicBlock::loopNumber loopNum; if (block == nullptr) @@ -4333,7 +4333,7 @@ ValueNum ValueNumStore::VNForExpr(BasicBlock* block, var_types typ) // VNForFunc(typ, func, vn) but bypasses looking in the cache // - Chunk* const c = GetAllocChunk(typ, CEA_Func1); + Chunk* const c = GetAllocChunk(type, CEA_Func1); unsigned const offsetWithinChunk = c->AllocVN(); VNDefFuncAppFlexible* fapp = c->PointerToFuncApp(offsetWithinChunk, 1); fapp->m_func = VNF_MemOpaque; @@ -4343,6 +4343,19 @@ ValueNum ValueNumStore::VNForExpr(BasicBlock* block, var_types typ) return resultVN; } +//------------------------------------------------------------------------ +// VNPairForExpr - Create a "new, unique" pair of value numbers. +// +// "VNForExpr" equivalent for "ValueNumPair"s. +// +ValueNumPair ValueNumStore::VNPairForExpr(BasicBlock* block, var_types type) +{ + ValueNum uniqVN = VNForExpr(block, type); + ValueNumPair uniqVNP(uniqVN, uniqVN); + + return uniqVNP; +} + //------------------------------------------------------------------------ // VNForLoad: Get the VN for a load from a location (physical map). // @@ -9326,143 +9339,168 @@ void Compiler::fgValueNumberSimd(GenTreeSIMD* tree) #endif // FEATURE_SIMD #ifdef FEATURE_HW_INTRINSICS -// Does value-numbering for a GT_HWINTRINSIC node void Compiler::fgValueNumberHWIntrinsic(GenTreeHWIntrinsic* tree) { - // For safety/correctness we must mutate the global heap valuenumber - // for any HW intrinsic that performs a memory store operation - if (tree->OperIsMemoryStore()) - { - fgMutateGcHeap(tree DEBUGARG("HWIntrinsic - MemoryStore")); - } + NamedIntrinsic intrinsicId = tree->GetHWIntrinsicId(); + GenTree* addr = nullptr; + const bool isMemoryLoad = tree->OperIsMemoryLoad(&addr); + const bool isMemoryStore = !isMemoryLoad && tree->OperIsMemoryStore(&addr); - if ((tree->GetOperandCount() > 2) || ((JitConfig.JitDisableSimdVN() & 2) == 2)) + // We do not model HWI stores precisely. + if (isMemoryStore) { - // TODO-CQ: allow intrinsics with > 2 operands to be properly VN'ed, it will - // allow use to process things like Vector128.Create(1,2,3,4) etc. - // Generate unique VN for now to retaing previous behavior. - ValueNumPair vnpExcSet = vnStore->VNPForEmptyExcSet(); - for (GenTree* operand : tree->Operands()) - { - vnpExcSet = vnStore->VNPUnionExcSet(operand->gtVNPair, vnpExcSet); - } - tree->gtVNPair = vnStore->VNPUniqueWithExc(tree->TypeGet(), vnpExcSet); - return; + fgMutateGcHeap(tree DEBUGARG("HWIntrinsic - MemoryStore")); } - VNFunc func = GetVNFuncForNode(tree); - bool isMemoryLoad = tree->OperIsMemoryLoad(); + ValueNumPair excSetPair = ValueNumStore::VNPForEmptyExcSet(); + ValueNumPair normalPair = ValueNumPair(); - // If we have a MemoryLoad operation we will use the fgValueNumberByrefExposedLoad - // method to assign a value number that depends upon fgCurMemoryVN[ByrefExposed] ValueNumber - // - if (isMemoryLoad) + if ((tree->GetOperandCount() > 2) || ((JitConfig.JitDisableSimdVN() & 2) == 2)) { - ValueNumPair op1vnp = vnStore->VNPNormalPair(tree->Op(1)->gtVNPair); - - // The addrVN incorporates both op1's ValueNumber and the func operation - // The func is used because operations such as LoadLow and LoadHigh perform - // different operations, thus need to compute different ValueNumbers - // We don't need to encode the result type as it will be encoded by the opcode in 'func' - // TODO-Bug: some HWI loads have more than one operand, we need to encode the rest. - ValueNum addrVN = vnStore->VNForFunc(TYP_BYREF, func, op1vnp.GetLiberal()); - - // The address could point anywhere, so it is an ByrefExposed load. - // - ValueNum loadVN = fgValueNumberByrefExposedLoad(tree->TypeGet(), addrVN); - tree->gtVNPair.SetLiberal(loadVN); - tree->gtVNPair.SetConservative(vnStore->VNForExpr(compCurBB, tree->TypeGet())); + // TODO-CQ: allow intrinsics with > 2 operands to be properly VN'ed. + normalPair = vnStore->VNPairForExpr(compCurBB, tree->TypeGet()); for (GenTree* operand : tree->Operands()) { - tree->gtVNPair = vnStore->VNPWithExc(tree->gtVNPair, vnStore->VNPExceptionSet(operand->gtVNPair)); + excSetPair = vnStore->VNPUnionExcSet(operand->gtVNPair, excSetPair); } - fgValueNumberAddExceptionSetForIndirection(tree, tree->Op(1)); - return; } - - bool encodeResultType = vnEncodesResultTypeForHWIntrinsic(tree->GetHWIntrinsicId()); - - ValueNumPair excSetPair = ValueNumStore::VNPForEmptyExcSet(); - ValueNumPair normalPair; - ValueNumPair resvnp = ValueNumPair(); - - if (encodeResultType) + else { - ValueNum simdTypeVN = vnStore->VNForSimdType(tree->GetSimdSize(), tree->GetNormalizedSimdBaseJitType()); - resvnp.SetBoth(simdTypeVN); + VNFunc func = GetVNFuncForNode(tree); + ValueNumPair resultTypeVNPair = ValueNumPair(); + bool encodeResultType = vnEncodesResultTypeForHWIntrinsic(intrinsicId); -#ifdef DEBUG - if (verbose) + if (encodeResultType) { - printf(" simdTypeVN is "); - vnPrint(simdTypeVN, 1); - printf("\n"); + ValueNum simdTypeVN = vnStore->VNForSimdType(tree->GetSimdSize(), tree->GetNormalizedSimdBaseJitType()); + resultTypeVNPair.SetBoth(simdTypeVN); + + JITDUMP(" simdTypeVN is "); + JITDUMPEXEC(vnPrint(simdTypeVN, 1)); + JITDUMP("\n"); } -#endif - } - const bool isVariableNumArgs = HWIntrinsicInfo::lookupNumArgs(tree->GetHWIntrinsicId()) == -1; + auto getOperandVNs = [this, addr](GenTree* operand, ValueNumPair* pNormVNPair, ValueNumPair* pExcVNPair) { + vnStore->VNPUnpackExc(operand->gtVNPair, pNormVNPair, pExcVNPair); - // There are some HWINTRINSICS operations that have zero args, i.e. NI_Vector128_Zero - if (tree->GetOperandCount() == 0) - { - // Currently we don't have intrinsics with variable number of args with a parameter-less option. - assert(!isVariableNumArgs); + // If we have a load operation we will use the fgValueNumberByrefExposedLoad + // method to assign a value number that depends upon the current heap state. + // + if (operand == addr) + { + // We need to "insert" the "ByrefExposedLoad" VN somewhere here. We choose + // to do so by effectively altering the semantics of "addr" operands, making + // them represent "the load", on top of which the HWI func itself is applied. + // This is a workaround, but doing this "properly" would entail adding the + // heap and type VNs to HWI load funcs themselves. + var_types loadType = operand->TypeGet(); + ValueNum loadVN = fgValueNumberByrefExposedLoad(loadType, pNormVNPair->GetLiberal()); - if (encodeResultType) - { - // There are zero arg HWINTRINSICS operations that encode the result type, i.e. Vector128_AllBitSet - normalPair = vnStore->VNPairForFunc(tree->TypeGet(), func, resvnp); - assert(vnStore->VNFuncArity(func) == 1); - } - else - { - normalPair = vnStore->VNPairForFunc(tree->TypeGet(), func); - assert(vnStore->VNFuncArity(func) == 0); - } - } - else // HWINTRINSIC unary or binary operator. - { - ValueNumPair op1vnp; - ValueNumPair op1Xvnp; - vnStore->VNPUnpackExc(tree->Op(1)->gtVNPair, &op1vnp, &op1Xvnp); + pNormVNPair->SetLiberal(loadVN); + pNormVNPair->SetConservative(vnStore->VNForExpr(compCurBB, loadType)); + } + }; - if (tree->GetOperandCount() == 1) + const bool isVariableNumArgs = HWIntrinsicInfo::lookupNumArgs(intrinsicId) == -1; + + // There are some HWINTRINSICS operations that have zero args, i.e. NI_Vector128_Zero + if (tree->GetOperandCount() == 0) { - excSetPair = op1Xvnp; + // Currently we don't have intrinsics with variable number of args with a parameter-less option. + assert(!isVariableNumArgs); if (encodeResultType) { - normalPair = vnStore->VNPairForFunc(tree->TypeGet(), func, op1vnp, resvnp); - assert((vnStore->VNFuncArity(func) == 2) || isVariableNumArgs); + // There are zero arg HWINTRINSICS operations that encode the result type, i.e. Vector128_AllBitSet + normalPair = vnStore->VNPairForFunc(tree->TypeGet(), func, resultTypeVNPair); + assert(vnStore->VNFuncArity(func) == 1); } else { - normalPair = vnStore->VNPairForFunc(tree->TypeGet(), func, op1vnp); - assert((vnStore->VNFuncArity(func) == 1) || isVariableNumArgs); + normalPair = vnStore->VNPairForFunc(tree->TypeGet(), func); + assert(vnStore->VNFuncArity(func) == 0); } } - else + else // HWINTRINSIC unary or binary operator. { - ValueNumPair op2vnp; - ValueNumPair op2Xvnp; - vnStore->VNPUnpackExc(tree->Op(2)->gtVNPair, &op2vnp, &op2Xvnp); + ValueNumPair op1vnp; + ValueNumPair op1Xvnp; + getOperandVNs(tree->Op(1), &op1vnp, &op1Xvnp); - excSetPair = vnStore->VNPExcSetUnion(op1Xvnp, op2Xvnp); - if (encodeResultType) + if (tree->GetOperandCount() == 1) { - normalPair = vnStore->VNPairForFunc(tree->TypeGet(), func, op1vnp, op2vnp, resvnp); - assert((vnStore->VNFuncArity(func) == 3) || isVariableNumArgs); + excSetPair = op1Xvnp; + + if (encodeResultType) + { + normalPair = vnStore->VNPairForFunc(tree->TypeGet(), func, op1vnp, resultTypeVNPair); + assert((vnStore->VNFuncArity(func) == 2) || isVariableNumArgs); + } + else + { + normalPair = vnStore->VNPairForFunc(tree->TypeGet(), func, op1vnp); + assert((vnStore->VNFuncArity(func) == 1) || isVariableNumArgs); + } } else { - normalPair = vnStore->VNPairForFunc(tree->TypeGet(), func, op1vnp, op2vnp); - assert((vnStore->VNFuncArity(func) == 2) || isVariableNumArgs); + ValueNumPair op2vnp; + ValueNumPair op2Xvnp; + getOperandVNs(tree->Op(2), &op2vnp, &op2Xvnp); + + excSetPair = vnStore->VNPExcSetUnion(op1Xvnp, op2Xvnp); + if (encodeResultType) + { + normalPair = vnStore->VNPairForFunc(tree->TypeGet(), func, op1vnp, op2vnp, resultTypeVNPair); + assert((vnStore->VNFuncArity(func) == 3) || isVariableNumArgs); + } + else + { + normalPair = vnStore->VNPairForFunc(tree->TypeGet(), func, op1vnp, op2vnp); + assert((vnStore->VNFuncArity(func) == 2) || isVariableNumArgs); + } } } } + tree->gtVNPair = vnStore->VNPWithExc(normalPair, excSetPair); + + // Currently, the only exceptions these intrinsics could throw are NREs. + // + if (isMemoryLoad || isMemoryStore) + { + // Most load operations are simple "IND(addr)" equivalents. However, there are exceptions such as AVX + // "gather" operations, where the "effective" address - one from which the actual load will be performed and + // NullReferenceExceptions are associated with does not match the value of "addr". We will punt handling those + // precisely for now. + switch (intrinsicId) + { +#ifdef TARGET_XARCH + case NI_SSE2_MaskMove: + case NI_AVX_MaskStore: + case NI_AVX2_MaskStore: + case NI_AVX_MaskLoad: + case NI_AVX2_MaskLoad: + case NI_AVX2_GatherVector128: + case NI_AVX2_GatherVector256: + case NI_AVX2_GatherMaskVector128: + case NI_AVX2_GatherMaskVector256: + { + ValueNumPair uniqAddrVNPair = vnStore->VNPairForExpr(compCurBB, TYP_BYREF); + ValueNumPair uniqExcVNPair = vnStore->VNPairForFunc(TYP_REF, VNF_NullPtrExc, uniqAddrVNPair); + ValueNumPair uniqExcSetVNPair = vnStore->VNPExcSetSingleton(uniqExcVNPair); + + tree->gtVNPair = vnStore->VNPWithExc(tree->gtVNPair, uniqExcSetVNPair); + } + break; +#endif // TARGET_XARCH + + default: + fgValueNumberAddExceptionSetForIndirection(tree, addr); + break; + } + } } #endif // FEATURE_HW_INTRINSICS diff --git a/src/coreclr/jit/valuenum.h b/src/coreclr/jit/valuenum.h index fc9ed09913c630..4741e6150debe8 100644 --- a/src/coreclr/jit/valuenum.h +++ b/src/coreclr/jit/valuenum.h @@ -687,9 +687,8 @@ class ValueNumStore op3VN.GetConservative(), op4VN.GetConservative())); } - // Get a new, unique value number for an expression that we're not equating to some function, - // which is the value of a tree in the given block. - ValueNum VNForExpr(BasicBlock* block, var_types typ = TYP_UNKNOWN); + ValueNum VNForExpr(BasicBlock* block, var_types type = TYP_UNKNOWN); + ValueNumPair VNPairForExpr(BasicBlock* block, var_types type); // This controls extra tracing of the "evaluation" of "VNF_MapSelect" functions. #define FEATURE_VN_TRACE_APPLY_SELECTORS 1 diff --git a/src/tests/JIT/HardwareIntrinsics/General/HwiOp/HwiValueNumbering.cs b/src/tests/JIT/HardwareIntrinsics/General/HwiOp/HwiValueNumbering.cs new file mode 100644 index 00000000000000..fa8ff172370b3c --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/General/HwiOp/HwiValueNumbering.cs @@ -0,0 +1,218 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +using System.Runtime.CompilerServices; + +// Tests that we value number certain intrinsics correctly. +// +unsafe class HwiValueNumbering +{ + public static int Main() + { + if (Sse.IsSupported && ProblemWithLoadLow_Sse()) + { + return 101; + } + + if (Sse2.IsSupported && ProblemWithLoadLow_Sse2()) + { + return 102; + } + + if (Sse.IsSupported && ProblemWithLoadHigh_Sse()) + { + return 103; + } + + if (Sse2.IsSupported && ProblemWithLoadHigh_Sse2()) + { + return 104; + } + + if (Avx.IsSupported && ProblemWithMaskLoad_Avx()) + { + return 105; + } + + if (Avx2.IsSupported && ProblemWithMaskLoad_Avx2()) + { + return 106; + } + + return 100; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool ProblemWithLoadLow_Sse() + { + var data = stackalloc float[2]; + data[0] = 1; + data[1] = 2; + JitUse(data); + + Vector128 a = Vector128.Zero; + Vector128 b = Sse.LoadLow(a, data); + Vector128 c = Sse.LoadLow(a, data + 1); + + // Make sure we take into account the address operand. + if (b.AsInt32().GetElement(0) == c.AsInt32().GetElement(0)) + { + return true; + } + + // Make sure we take the heap state into account. + b = Sse.LoadLow(a, data); + data[0] = 3; + c = Sse.LoadLow(a, data); + if (b.AsInt32().GetElement(0) == c.AsInt32().GetElement(0)) + { + return true; + } + + return false; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool ProblemWithLoadLow_Sse2() + { + var data = stackalloc double[2]; + data[0] = 1; + data[1] = 2; + JitUse(data); + + Vector128 a = Vector128.Zero; + Vector128 b = Sse2.LoadLow(a, data); + Vector128 c = Sse2.LoadLow(a, data + 1); + + // Make sure we take into account the address operand. + if (b.AsInt64().GetElement(0) == c.AsInt64().GetElement(0)) + { + return true; + } + + // Make sure we take the heap state into account. + b = Sse2.LoadLow(a, data); + data[0] = 3; + c = Sse2.LoadLow(a, data); + if (b.AsInt64().GetElement(0) == c.AsInt64().GetElement(0)) + { + return true; + } + + return false; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool ProblemWithLoadHigh_Sse() + { + var data = stackalloc float[2]; + data[0] = 1; + data[1] = 2; + JitUse(data); + + Vector128 a = Vector128.Zero; + Vector128 b = Sse.LoadHigh(a, data); + Vector128 c = Sse.LoadHigh(a, data + 1); + + // Make sure we take into account the address operand. + if (b.AsInt64().GetElement(1) == c.AsInt64().GetElement(1)) + { + return true; + } + + // Make sure we take the heap state into account. + b = Sse.LoadHigh(a, data); + data[0] = 3; + c = Sse.LoadHigh(a, data); + if (b.AsInt64().GetElement(1) == c.AsInt64().GetElement(1)) + { + return true; + } + + return false; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool ProblemWithLoadHigh_Sse2() + { + var data = stackalloc double[2]; + data[0] = 1; + data[1] = 2; + JitUse(data); + + Vector128 a = Vector128.Zero; + Vector128 b = Sse2.LoadHigh(a, data); + Vector128 c = Sse2.LoadHigh(a, data + 1); + + // Make sure we take into account the address operand. + if (b.AsInt64().GetElement(1) == c.AsInt64().GetElement(1)) + { + return true; + } + + // Make sure we take the heap state into account. + b = Sse2.LoadHigh(a, data); + data[0] = 3; + c = Sse2.LoadHigh(a, data); + if (b.AsInt64().GetElement(1) == c.AsInt64().GetElement(1)) + { + return true; + } + + return false; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool ProblemWithMaskLoad_Avx() + { + const double Mask = -0.0; + + var data = stackalloc double[2]; + data[0] = 1; + data[1] = 1; + JitUse(data); + + // Make sure we take mask into account. + var v1 = Avx.MaskLoad(data, Vector128.Create(0, Mask)); + if (v1.GetElement(0) == 0) + { + var v2 = Avx.MaskLoad(data, Vector128.Create(Mask, 0)); + if (v2.GetElement(0) == 0) + { + return true; + } + } + + return false; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool ProblemWithMaskLoad_Avx2() + { + const long Mask = -0x8000000000000000; + + var data = stackalloc long[2]; + data[0] = 1; + data[1] = 1; + JitUse(data); + + // Make sure we take mask into account. + var v1 = Avx2.MaskLoad(data, Vector128.Create(0, Mask)); + if (v1.GetElement(0) == 0) + { + var v2 = Avx2.MaskLoad(data, Vector128.Create(Mask, 0)); + if (v2.GetElement(0) == 0) + { + return true; + } + } + + return false; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void JitUse(T* arg) where T : unmanaged { } +} diff --git a/src/tests/JIT/HardwareIntrinsics/General/HwiOp/HwiValueNumbering.csproj b/src/tests/JIT/HardwareIntrinsics/General/HwiOp/HwiValueNumbering.csproj new file mode 100644 index 00000000000000..9e2219131d3f47 --- /dev/null +++ b/src/tests/JIT/HardwareIntrinsics/General/HwiOp/HwiValueNumbering.csproj @@ -0,0 +1,11 @@ + + + Exe + None + True + true + + + + + From 702c1ea42dcd7c7d0a1ff139bda13b68033dc5ff Mon Sep 17 00:00:00 2001 From: Radek Zikmund <32671551+rzikm@users.noreply.github.com> Date: Wed, 15 Jun 2022 11:01:28 +0200 Subject: [PATCH 129/337] Small MsQuicStream refactorings (#70433) * Inline state transition helpers Fixes #55437 * Add high level comments for HandleEventReceive and ReadAsync --- .../Implementations/MsQuic/MsQuicStream.cs | 108 +++++++++--------- 1 file changed, 52 insertions(+), 56 deletions(-) diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs index 4ad758ef87bc27..2b57a49f5bf4a0 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/MsQuicStream.cs @@ -292,52 +292,6 @@ private async ValueTask WriteAsync(Action stateSetup, T { ThrowIfDisposed(); - using CancellationTokenRegistration registration = SetupWriteStartState(isEmpty, cancellationToken); - - await WriteAsyncCore(stateSetup, buffer, isEmpty, endStream).ConfigureAwait(false); - - CleanupWriteCompletedState(); - } - - private unsafe ValueTask WriteAsyncCore(Action stateSetup, TBuffer buffer, bool isEmpty, bool endStream) - { - if (isEmpty) - { - if (endStream) - { - // Start graceful shutdown sequence if passed in the fin flag and there is an empty buffer. - StartShutdown(QUIC_STREAM_SHUTDOWN_FLAGS.GRACEFUL, errorCode: 0); - } - return default; - } - - stateSetup(_state, buffer); - - Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)"); - int status = MsQuicApi.Api.ApiTable->StreamSend( - _state.Handle.QuicHandle, - _state.SendBuffers.Buffers, - (uint)_state.SendBuffers.Count, - endStream ? QUIC_SEND_FLAGS.FIN : QUIC_SEND_FLAGS.NONE, - (void*)IntPtr.Zero); - - if (StatusFailed(status)) - { - CleanupWriteFailedState(); - CleanupSendState(_state); - - if (status == QUIC_STATUS_ABORTED) - { - throw ThrowHelper.GetConnectionAbortedException(_state.ConnectionState.AbortErrorCode); - } - ThrowIfFailure(status, "Could not send data to peer."); - } - - return _state.SendResettableCompletionSource.GetTypelessValueTask(); - } - - private CancellationTokenRegistration SetupWriteStartState(bool emptyBuffer, CancellationToken cancellationToken) - { if (cancellationToken.IsCancellationRequested) { lock (_state) @@ -369,7 +323,7 @@ private CancellationTokenRegistration SetupWriteStartState(bool emptyBuffer, Can } // if token was already cancelled, this would execute synchronously - CancellationTokenRegistration registration = cancellationToken.UnsafeRegister(static (s, token) => + using CancellationTokenRegistration registration = cancellationToken.UnsafeRegister(static (s, token) => { var state = (State)s!; bool shouldComplete = false; @@ -417,14 +371,11 @@ private CancellationTokenRegistration SetupWriteStartState(bool emptyBuffer, Can // Change the state in the same lock where we check for final states to prevent coming back from Aborted/ConnectionClosed. Debug.Assert(_state.SendState != SendState.Pending); - _state.SendState = emptyBuffer ? SendState.Finished : SendState.Pending; + _state.SendState = isEmpty ? SendState.Finished : SendState.Pending; } - return registration; - } + await WriteAsyncCore(stateSetup, buffer, isEmpty, endStream).ConfigureAwait(false); - private void CleanupWriteCompletedState() - { lock (_state) { if (_state.SendState == SendState.Finished) @@ -434,19 +385,57 @@ private void CleanupWriteCompletedState() } } - private void CleanupWriteFailedState() + private unsafe ValueTask WriteAsyncCore(Action stateSetup, TBuffer buffer, bool isEmpty, bool endStream) { - lock (_state) + if (isEmpty) { - if (_state.SendState == SendState.Pending) + if (endStream) { - _state.SendState = SendState.Finished; + // Start graceful shutdown sequence if passed in the fin flag and there is an empty buffer. + StartShutdown(QUIC_STREAM_SHUTDOWN_FLAGS.GRACEFUL, errorCode: 0); } + return default; } + + stateSetup(_state, buffer); + + Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)"); + int status = MsQuicApi.Api.ApiTable->StreamSend( + _state.Handle.QuicHandle, + _state.SendBuffers.Buffers, + (uint)_state.SendBuffers.Count, + endStream ? QUIC_SEND_FLAGS.FIN : QUIC_SEND_FLAGS.NONE, + (void*)IntPtr.Zero); + + if (StatusFailed(status)) + { + lock (_state) + { + if (_state.SendState == SendState.Pending) + { + _state.SendState = SendState.Finished; + } + } + + CleanupSendState(_state); + + if (status == QUIC_STATUS_ABORTED) + { + throw ThrowHelper.GetConnectionAbortedException(_state.ConnectionState.AbortErrorCode); + } + ThrowIfFailure(status, "Could not send data to peer."); + } + + return _state.SendResettableCompletionSource.GetTypelessValueTask(); } internal override async ValueTask ReadAsync(Memory destination, CancellationToken cancellationToken = default) { + // + // If MsQuic indicated that some data were received (QUIC_STREAM_EVENT_RECEIVE), we use it to complete the request + // synchronously. Otherwise we setup the request to be completed by the HandleEventReceive handler. + // + ThrowIfDisposed(); if (_state.ReadState == ReadState.Closed) @@ -1009,6 +998,13 @@ private static unsafe int NativeCallback(QUIC_HANDLE* stream, void* context, QUI private static unsafe int HandleEventReceive(State state, ref QUIC_STREAM_EVENT streamEvent) { + // + // Handle MsQuic QUIC_STREAM_EVENT_RECEIVE event + // + // If there is a pending ReadAsync call, then we complete it. Otherwise we keep a pointer to the received data + // and use it to complete the next ReadAsync operation synchronously. + // + ref var receiveEvent = ref streamEvent.RECEIVE; if (NetEventSource.Log.IsEnabled()) From 53e52f28cdc9b800a4b04fee2f200e4087fcfd58 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Wed, 15 Jun 2022 06:30:25 -0700 Subject: [PATCH 130/337] Updating HWIntrinsicInfo::lookupId to not accelerate Vector256 APIs when AVX2 is unsupported (#70686) * Updating HWIntrinsicINfo::lookupId to not accelerate Vector256 APIs when AVX2 is unsupported * Fixing a check in lookupId to properly negate the condition * Ensure the special-cased EA_32BYTE constants only happen when AVX/AVX2 are supported * Fixing a bad assert in morph --- src/coreclr/jit/codegenxarch.cpp | 18 ++++++++++++------ src/coreclr/jit/hwintrinsic.cpp | 27 +++++++++++++++++++++------ src/coreclr/jit/morph.cpp | 4 ++-- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index 4f709482128770..8e00b37a1d52d9 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -517,22 +517,28 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre if (vecCon->IsAllBitsSet()) { + if ((attr != EA_32BYTE) || compiler->compOpportunisticallyDependsOn(InstructionSet_AVX2)) + { #if defined(FEATURE_SIMD) - emit->emitIns_SIMD_R_R_R(INS_pcmpeqd, attr, targetReg, targetReg, targetReg); + emit->emitIns_SIMD_R_R_R(INS_pcmpeqd, attr, targetReg, targetReg, targetReg); #else - emit->emitIns_R_R(INS_pcmpeqd, attr, targetReg, targetReg); + emit->emitIns_R_R(INS_pcmpeqd, attr, targetReg, targetReg); #endif // FEATURE_SIMD - break; + break; + } } if (vecCon->IsZero()) { + if ((attr != EA_32BYTE) || compiler->compOpportunisticallyDependsOn(InstructionSet_AVX)) + { #if defined(FEATURE_SIMD) - emit->emitIns_SIMD_R_R_R(INS_xorps, attr, targetReg, targetReg, targetReg); + emit->emitIns_SIMD_R_R_R(INS_xorps, attr, targetReg, targetReg, targetReg); #else - emit->emitIns_R_R(INS_xorps, attr, targetReg, targetReg); + emit->emitIns_R_R(INS_xorps, attr, targetReg, targetReg); #endif // FEATURE_SIMD - break; + break; + } } switch (tree->TypeGet()) diff --git a/src/coreclr/jit/hwintrinsic.cpp b/src/coreclr/jit/hwintrinsic.cpp index 1cec85df393a1c..6ad3ef37cf8f1f 100644 --- a/src/coreclr/jit/hwintrinsic.cpp +++ b/src/coreclr/jit/hwintrinsic.cpp @@ -314,20 +314,35 @@ NamedIntrinsic HWIntrinsicInfo::lookupId(Compiler* comp, return NI_Throw_PlatformNotSupportedException; } + // Special case: For Vector64/128/256 we currently don't accelerate any of the methods when + // IsHardwareAccelerated reports false. For Vector64 and Vector128 this is when the baseline + // ISA is unsupported. For Vector256 this is when AVX2 is unsupported since integer types + // can't get properly accelerated. + + if (isa == InstructionSet_Vector128) + { + if (!comp->IsBaselineSimdIsaSupported()) + { + return NI_Illegal; + } + } #if defined(TARGET_XARCH) - if ((isa == InstructionSet_Vector128) || (isa == InstructionSet_Vector256)) + else if (isa == InstructionSet_Vector256) + { + if (!comp->compOpportunisticallyDependsOn(InstructionSet_AVX2)) + { + return NI_Illegal; + } + } #elif defined(TARGET_ARM64) - if ((isa == InstructionSet_Vector64) || (isa == InstructionSet_Vector128)) -#endif + else if (isa == InstructionSet_Vector64) { if (!comp->IsBaselineSimdIsaSupported()) { - // Special case: For Vector64/128/256 we currently don't accelerate any of the methods when SSE/SSE2 - // aren't supported since IsHardwareAccelerated reports false. To simplify the importation logic we'll - // just return illegal here and let it fallback to the software path instead. return NI_Illegal; } } +#endif for (int i = 0; i < (NI_HW_INTRINSIC_END - NI_HW_INTRINSIC_START - 1); i++) { diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 61230a0e8292c8..5c8162af104c6a 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -9934,7 +9934,7 @@ GenTree* Compiler::fgMorphFieldToSimdGetElement(GenTree* tree) var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType); GenTree* op2 = gtNewIconNode(index, TYP_INT); - assert(simdSize <= 16); + assert(simdSize <= 32); assert(simdSize >= ((index + 1) * genTypeSize(simdBaseType))); #if defined(TARGET_XARCH) @@ -10009,7 +10009,7 @@ GenTree* Compiler::fgMorphFieldAssignToSimdSetElement(GenTree* tree) var_types simdType = simdStructNode->gtType; var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType); - assert(simdSize <= 16); + assert(simdSize <= 32); assert(simdSize >= ((index + 1) * genTypeSize(simdBaseType))); GenTree* op2 = gtNewIconNode(index, TYP_INT); From b3e606f2389a9535ea2ec3ccec308dede767a427 Mon Sep 17 00:00:00 2001 From: Radek Zikmund <32671551+rzikm@users.noreply.github.com> Date: Wed, 15 Jun 2022 16:35:55 +0200 Subject: [PATCH 131/337] Dsiable CertificateValidationRemoteServer.ConnectWithRevocation_WithCallback on Android (#70768) --- .../tests/FunctionalTests/CertificateValidationRemoteServer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationRemoteServer.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationRemoteServer.cs index e76cdfe77c4b16..5498ca7ce2367d 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationRemoteServer.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationRemoteServer.cs @@ -92,6 +92,7 @@ public async Task DefaultConnect_EndToEnd_Ok(string host) [Theory] [InlineData(true)] [InlineData(false)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/68206", TestPlatforms.Android)] public Task ConnectWithRevocation_WithCallback(bool checkRevocation) { X509RevocationMode mode = checkRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck; From e24242439cdbe04c2e93deada6bc46933c7a857c Mon Sep 17 00:00:00 2001 From: Andrii Kurdiumov Date: Wed, 15 Jun 2022 20:53:12 +0600 Subject: [PATCH 132/337] NativeAOT Unlock assignability comparison in reflection-free (#70726) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * NativeAOT Unlock assignability comparison in reflection-free Closes #69960 * Document support for `IsAssignableFrom` * Document support for `IsInstanceOfType` * Document `IsAssignableTo` * Add suggestion from Michal * Update src/coreclr/nativeaot/System.Private.DisabledReflection/src/Internal/Reflection/RuntimeTypeInfo.cs Co-authored-by: Michal Strehovský * Remove whitespaces Co-authored-by: Michal Strehovský --- .../Internal/Reflection/RuntimeTypeInfo.cs | 30 +++++++++++++++++++ .../nativeaot/docs/reflection-free-mode.md | 2 +- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/coreclr/nativeaot/System.Private.DisabledReflection/src/Internal/Reflection/RuntimeTypeInfo.cs b/src/coreclr/nativeaot/System.Private.DisabledReflection/src/Internal/Reflection/RuntimeTypeInfo.cs index 24506863ab20b2..ad9f79c9be1848 100644 --- a/src/coreclr/nativeaot/System.Private.DisabledReflection/src/Internal/Reflection/RuntimeTypeInfo.cs +++ b/src/coreclr/nativeaot/System.Private.DisabledReflection/src/Internal/Reflection/RuntimeTypeInfo.cs @@ -202,6 +202,36 @@ protected override bool IsPrimitiveImpl() return RuntimeAugments.IsPrimitive(_typeHandle); } + public override bool IsAssignableFrom([NotNullWhen(true)] Type c) + { + if (c == null) + return false; + + if (object.ReferenceEquals(c, this)) + return true; + + c = c.UnderlyingSystemType; + + Type typeInfo = c; + RuntimeTypeInfo toTypeInfo = this; + + if (typeInfo is not RuntimeType) + return false; // Desktop compat: If typeInfo is null, or implemented by a different Reflection implementation, return "false." + + RuntimeTypeInfo fromTypeInfo = (RuntimeTypeInfo)typeInfo; + + RuntimeTypeHandle toTypeHandle = toTypeInfo._typeHandle; + RuntimeTypeHandle fromTypeHandle = fromTypeInfo._typeHandle; + + if (RuntimeAugments.IsGenericTypeDefinition(toTypeHandle) || RuntimeAugments.IsGenericTypeDefinition(fromTypeHandle)) + throw new NotSupportedException(SR.Reflection_Disabled); + + if (RuntimeAugments.IsAssignableFrom(toTypeHandle, fromTypeHandle)) + return true; + + return false; + } + internal static RuntimeTypeInfo GetRuntimeTypeInfo(RuntimeTypeHandle typeHandle) { return RuntimeTypeTable.Table.GetOrAdd(new RuntimeTypeHandleKey(typeHandle)); diff --git a/src/coreclr/nativeaot/docs/reflection-free-mode.md b/src/coreclr/nativeaot/docs/reflection-free-mode.md index 644421e36c1f1c..f4acb394c67c98 100644 --- a/src/coreclr/nativeaot/docs/reflection-free-mode.md +++ b/src/coreclr/nativeaot/docs/reflection-free-mode.md @@ -34,7 +34,7 @@ Think of: Reflection-free mode **supports a limited set of reflection APIs** that keep their expected semantics. * `typeof(SomeType)` will return a `System.Type` that can be compared with results of other `typeof` expressions or results of `Object.GetType()` calls. The patterns commonly used in perf optimizations of generic code (e.g. `typeof(T) == typeof(byte)`) will work fine, and so will `obj.GetType() == typeof(SomeType)`. -* Following APIs on `System.Type` work: `TypeHandle`, `UnderlyingSystemType`, `BaseType`, `IsByRefLike`, `IsValueType`, `GetTypeCode`, `GetHashCode`, `GetElementType`, `GetInterfaces`, `HasElementType`, `IsArray`, `IsByRef`, `IsPointer`, `IsPrimitive`. +* Following APIs on `System.Type` work: `TypeHandle`, `UnderlyingSystemType`, `BaseType`, `IsByRefLike`, `IsValueType`, `GetTypeCode`, `GetHashCode`, `GetElementType`, `GetInterfaces`, `HasElementType`, `IsArray`, `IsByRef`, `IsPointer`, `IsPrimitive`, `IsAssignableFrom`, `IsAssignableTo`, `IsInstanceOfType`. * `Activator.CreateInstance()` will work. The compiler statically analyzes and expands this to efficient code at compile time. No reflection is involved at runtime. * `Assembly.GetExecutingAssembly()` will return a `System.Reflection.Assembly` that can be compared with other runtime `Assembly` instances. This is mostly to make it possible to use the `NativeLibrary.SetDllImportResolver` API. From 82a7ee4418d645aceb07cfbd61dc89280637cd8e Mon Sep 17 00:00:00 2001 From: Fan Yang <52458914+fanyang-mono@users.noreply.github.com> Date: Wed, 15 Jun 2022 11:40:44 -0400 Subject: [PATCH 133/337] [Mono] Fix C4018 round I (#70417) * First round of change of fixing C4018 * Address part of review feedback * Change the type of idx to unsigned for `effective_table_slow` * Add idx range check after the type was changed * Address review feedback for `class-init.c` * Change the return type of `*table_num_rows*` to `guint32`. Deal with the consequence of return type change of `table_info_get_rows`. Correct the type of a few local variables which store the return of `mono_metadata_token_index`. * Update return type * Address review feedbacks of metadata.c * Fix native crash * Make counter private to for-loop * Address review feedbacks * Address review feedbacks --- .../mono/component/debugger-state-machine.c | 2 +- src/mono/mono/component/hot_reload-stub.c | 8 +- src/mono/mono/component/hot_reload.c | 8 +- src/mono/mono/component/hot_reload.h | 4 +- src/mono/mono/eglib/garray.c | 2 +- src/mono/mono/eglib/gfile.c | 2 +- src/mono/mono/eglib/glib.h | 8 ++ src/mono/mono/eglib/gptrarray.c | 2 +- src/mono/mono/eventpipe/ep-rt-mono.c | 10 +- src/mono/mono/eventpipe/ep-rt-mono.h | 2 +- src/mono/mono/metadata/class-init.c | 36 +++---- src/mono/mono/metadata/icall.c | 27 +++--- src/mono/mono/metadata/metadata-internals.h | 18 ++-- src/mono/mono/metadata/metadata-update.c | 4 +- src/mono/mono/metadata/metadata.c | 93 +++++++++---------- src/mono/mono/mini/mini-amd64.c | 43 ++++----- src/mono/mono/mini/mini.h | 2 +- 17 files changed, 133 insertions(+), 138 deletions(-) diff --git a/src/mono/mono/component/debugger-state-machine.c b/src/mono/mono/component/debugger-state-machine.c index a9a5ebb0603806..f36a6c2397dc16 100644 --- a/src/mono/mono/component/debugger-state-machine.c +++ b/src/mono/mono/component/debugger-state-machine.c @@ -298,7 +298,7 @@ mono_debugger_state (JsonWriter *writer) mono_json_writer_object_key(writer, "breakpoints"); mono_json_writer_array_begin (writer); - for (int i=0; i < breakpoint_copy->len; i++) { + for (guint i=0; i < breakpoint_copy->len; i++) { MonoBreakpoint *bp = (MonoBreakpoint *) g_ptr_array_index (breakpoint_copy, i); mono_json_writer_indent (writer); diff --git a/src/mono/mono/component/hot_reload-stub.c b/src/mono/mono/component/hot_reload-stub.c index efe3163a9d825b..630043c6be207b 100644 --- a/src/mono/mono/component/hot_reload-stub.c +++ b/src/mono/mono/component/hot_reload-stub.c @@ -39,7 +39,7 @@ static void hot_reload_stub_cleanup_on_close (MonoImage *image); static void -hot_reload_stub_effective_table_slow (const MonoTableInfo **t, int idx); +hot_reload_stub_effective_table_slow (const MonoTableInfo **t, uint32_t idx); static void hot_reload_stub_close_except_pools_all (MonoImage *base_image); @@ -62,7 +62,7 @@ hot_reload_stub_get_updated_method_ppdb (MonoImage *base_image, uint32_t idx); static gboolean hot_reload_stub_has_modified_rows (const MonoTableInfo *table); -static int +static guint32 hot_reload_stub_table_num_rows_slow (MonoImage *image, int table_index); static uint32_t @@ -187,7 +187,7 @@ hot_reload_stub_cleanup_on_close (MonoImage *image) } void -hot_reload_stub_effective_table_slow (const MonoTableInfo **t, int idx) +hot_reload_stub_effective_table_slow (const MonoTableInfo **t, uint32_t idx) { g_assert_not_reached (); } @@ -238,7 +238,7 @@ hot_reload_stub_has_modified_rows (const MonoTableInfo *table) return FALSE; } -static int +static guint32 hot_reload_stub_table_num_rows_slow (MonoImage *image, int table_index) { g_assert_not_reached (); /* should always take the fast path */ diff --git a/src/mono/mono/component/hot_reload.c b/src/mono/mono/component/hot_reload.c index 6f4696e4ef882c..aafca1e85d0676 100644 --- a/src/mono/mono/component/hot_reload.c +++ b/src/mono/mono/component/hot_reload.c @@ -64,7 +64,7 @@ static void hot_reload_cleanup_on_close (MonoImage *image); static void -hot_reload_effective_table_slow (const MonoTableInfo **t, int idx); +hot_reload_effective_table_slow (const MonoTableInfo **t, uint32_t idx); static void hot_reload_apply_changes (int origin, MonoImage *base_image, gconstpointer dmeta, uint32_t dmeta_len, gconstpointer dil, uint32_t dil_len, gconstpointer dpdb_bytes_orig, uint32_t dpdb_length, MonoError *error); @@ -93,7 +93,7 @@ hot_reload_get_updated_method_ppdb (MonoImage *base_image, uint32_t idx); static gboolean hot_reload_has_modified_rows (const MonoTableInfo *table); -static int +static guint32 hot_reload_table_num_rows_slow (MonoImage *image, int table_index); static GSList* @@ -1057,7 +1057,7 @@ effective_table_mutant (MonoImage *base, BaselineInfo *info, int tbl_index, cons } void -hot_reload_effective_table_slow (const MonoTableInfo **t, int idx) +hot_reload_effective_table_slow (const MonoTableInfo **t, uint32_t idx G_GNUC_UNUSED) { /* FIXME: don't let any thread other than the updater thread see values from a delta image * with a generation past update_published @@ -2694,7 +2694,7 @@ hot_reload_has_modified_rows (const MonoTableInfo *table) return info->any_modified_rows[tbl_index]; } -static int +static guint32 hot_reload_table_num_rows_slow (MonoImage *base, int table_index) { BaselineInfo *base_info = baseline_info_lookup (base); diff --git a/src/mono/mono/component/hot_reload.h b/src/mono/mono/component/hot_reload.h index c2d5b5dcee508e..5a5d00f5aecb67 100644 --- a/src/mono/mono/component/hot_reload.h +++ b/src/mono/mono/component/hot_reload.h @@ -23,7 +23,7 @@ typedef struct _MonoComponentHotReload { uint32_t (*thread_expose_published) (void); uint32_t (*get_thread_generation) (void); void (*cleanup_on_close) (MonoImage *image); - void (*effective_table_slow) (const MonoTableInfo **t, int idx); + void (*effective_table_slow) (const MonoTableInfo **t, uint32_t idx); void (*apply_changes) (int origin, MonoImage *base_image, gconstpointer dmeta, uint32_t dmeta_len, gconstpointer dil, uint32_t dil_len, gconstpointer dpdb_bytes_orig, uint32_t dpdb_length, MonoError *error); void (*image_close_except_pools_all) (MonoImage *base_image); void (*image_close_all) (MonoImage *base_image); @@ -32,7 +32,7 @@ typedef struct _MonoComponentHotReload { gboolean (*delta_heap_lookup) (MonoImage *base_image, MetadataHeapGetterFunc get_heap, uint32_t orig_index, MonoImage **image_out, uint32_t *index_out); gpointer (*get_updated_method_ppdb) (MonoImage *base_image, uint32_t idx); gboolean (*has_modified_rows) (const MonoTableInfo *table); - gboolean (*table_num_rows_slow) (MonoImage *base_image, int table_index); + uint32_t (*table_num_rows_slow) (MonoImage *base_image, int table_index); uint32_t (*method_parent) (MonoImage *base_image, uint32_t method_index); void* (*metadata_linear_search) (MonoImage *base_image, MonoTableInfo *base_table, const void *key, BinarySearchComparer comparer); uint32_t (*field_parent) (MonoImage *base_image, uint32_t method_index); diff --git a/src/mono/mono/eglib/garray.c b/src/mono/mono/eglib/garray.c index 212179043bb03a..8f6e207e6c5e8f 100644 --- a/src/mono/mono/eglib/garray.c +++ b/src/mono/mono/eglib/garray.c @@ -229,7 +229,7 @@ g_array_set_size (GArray *array, gint length) if (length == priv->capacity) return; // nothing to be done - if (length > priv->capacity) { + if (GINT_TO_UINT(length) > priv->capacity) { // grow the array ensure_capacity (priv, length); } diff --git a/src/mono/mono/eglib/gfile.c b/src/mono/mono/eglib/gfile.c index 75f9ccfa47cf45..e4c5d4ede15332 100644 --- a/src/mono/mono/eglib/gfile.c +++ b/src/mono/mono/eglib/gfile.c @@ -133,7 +133,7 @@ g_file_set_contents (const gchar *filename, const gchar *contents, gssize length if (length < 0) length = strlen (contents); - if (fwrite (contents, 1, length, fp) < length) { + if (fwrite (contents, 1, length, fp) < GSSIZE_TO_SIZE(length)) { g_set_error (err, G_FILE_ERROR, g_file_error_from_errno (ferror (fp)), "%s", g_strerror (ferror (fp))); g_unlink (path); g_free (path); diff --git a/src/mono/mono/eglib/glib.h b/src/mono/mono/eglib/glib.h index bbd94988576fa5..86c57baf6faf3e 100644 --- a/src/mono/mono/eglib/glib.h +++ b/src/mono/mono/eglib/glib.h @@ -1440,6 +1440,9 @@ __CAST_STYPE_TO_UTYPE(gssize, guint32, UINT32_MAX) __CAST_STYPE_TO_STYPE(gssize, gint, INT_MIN, INT_MAX) __CAST_STYPE_TO_UTYPE(gssize, guint, UINT_MAX) +__CAST_STYPE_TO_UTYPE(gssize, gsize, SIZE_MAX) +__CAST_UTYPE_TO_STYPE(gsize, gssize, PTRDIFF_MIN, PTRDIFF_MAX) + __CAST_STYPE_TO_STYPE(gdouble, gint64, INT64_MIN, INT64_MAX) __CAST_STYPE_TO_UTYPE(gdouble, guint64, UINT64_MAX) __CAST_STYPE_TO_STYPE(gdouble, gint32, INT32_MIN, INT32_MAX) @@ -1487,6 +1490,7 @@ __CAST_STYPE_TO_UTYPE(gint32, guint8, UINT8_MAX) __CAST_STYPE_TO_UTYPE(gint32, guint, UINT_MAX) +__CAST_UTYPE_TO_UTYPE(guint32, guint, UINT_MAX) __CAST_UTYPE_TO_STYPE(guint32, gint32, INT32_MIN, INT32_MAX) __CAST_UTYPE_TO_STYPE(guint32, gint16, INT16_MIN, INT16_MAX) __CAST_UTYPE_TO_UTYPE(guint32, guint16, UINT16_MAX) @@ -1617,6 +1621,9 @@ __CAST_UTYPE_TO_STYPE(gunichar, gchar, CHAR_MIN, CHAR_MAX) #define GSSIZE_TO_INT(v) G_CAST_TYPE_TO_TYPE(gssize, gint, v) #define GSSIZE_TO_UINT(v) G_CAST_TYPE_TO_TYPE(gssize, guint, v) +#define GSSIZE_TO_SIZE(v) G_CAST_TYPE_TO_TYPE(gssize, gsize, v) +#define GSIZE_TO_SSIZE(v) G_CAST_TYPE_TO_TYPE(gsize, gssize, v) + #define GDOUBLE_TO_INT64(v) G_CAST_TYPE_TO_TYPE(gdouble, gint64, v) #define GDOUBLE_TO_UINT64(v) G_CAST_TYPE_TO_TYPE(gdouble, guint64, v) #define GDOUBLE_TO_INT32(v) G_CAST_TYPE_TO_TYPE(gdouble, gint32, v) @@ -1670,6 +1677,7 @@ __CAST_UTYPE_TO_STYPE(gunichar, gchar, CHAR_MIN, CHAR_MAX) #define GINT32_TO_UINT(v) G_CAST_TYPE_TO_TYPE(gint32, guint, v) +#define GUINT32_TO_UINT(v) G_CAST_TYPE_TO_TYPE(guint32, guint, v) #define GUINT32_TO_INT32(v) G_CAST_TYPE_TO_TYPE(guint32, gint32, v) #define GUINT32_TO_INT16(v) G_CAST_TYPE_TO_TYPE(guint32, gint16, v) #define GUINT32_TO_UINT16(v) G_CAST_TYPE_TO_TYPE(guint32, guint16, v) diff --git a/src/mono/mono/eglib/gptrarray.c b/src/mono/mono/eglib/gptrarray.c index 86a5d714553ccf..08203bb1079124 100644 --- a/src/mono/mono/eglib/gptrarray.c +++ b/src/mono/mono/eglib/gptrarray.c @@ -226,7 +226,7 @@ gboolean g_ptr_array_find (GPtrArray *array, gconstpointer needle, guint *index) { g_assert (array); - for (int i = 0; i < array->len; i++) { + for (guint i = 0; i < array->len; i++) { if (array->pdata [i] == needle) { if (index) *index = i; diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index ff7b69ab4ea305..367d6b429bdb40 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -1469,7 +1469,7 @@ eventpipe_fire_method_events ( il_offsets = (uint32_t*)events_data->buffer; native_offsets = il_offsets + offset_entries; - for (int32_t offset_count = 0; offset_count < offset_entries; ++offset_count) { + for (uint32_t offset_count = 0; offset_count < offset_entries; ++offset_count) { il_offsets [offset_count] = debug_info->line_numbers [offset_count].il_offset; native_offsets [offset_count] = debug_info->line_numbers [offset_count].native_offset; } @@ -3106,7 +3106,7 @@ ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *type_logger) char *ptr = (char *)type_logger->bulk_type_event_buffer; - for (int type_value_index = 0; type_value_index < type_logger->bulk_type_value_count; type_value_index++) { + for (uint32_t type_value_index = 0; type_value_index < type_logger->bulk_type_value_count; type_value_index++) { BulkTypeValue *target = &type_logger->bulk_type_values [type_value_index]; values_element_size += write_event_buffer_int64 (target->fixed_sized_data.type_id, ptr, &ptr); @@ -3120,7 +3120,7 @@ ep_rt_mono_fire_bulk_type_event (BulkTypeEventLogger *type_logger) values_element_size += write_event_buffer_int32 (target->type_parameters_count, ptr, &ptr); - for (int i = 0; i < target->type_parameters_count; i++) { + for (uint32_t i = 0; i < target->type_parameters_count; i++) { uint64_t type_parameter = get_typeid_for_type (target->mono_type_parameters [i]); values_element_size += write_event_buffer_int64 ((int64_t)type_parameter, ptr, &ptr); } @@ -3413,7 +3413,7 @@ ep_rt_mono_send_method_details_event (MonoMethod *method) method_inst_parameter_types_count = method_inst->type_argc; uint64_t *method_inst_parameters_type_ids = mono_mempool_alloc0 (type_logger->mem_pool, method_inst_parameter_types_count * sizeof (uint64_t)); - for (int i = 0; i < method_inst_parameter_types_count; i++) { + for (uint32_t i = 0; i < method_inst_parameter_types_count; i++) { method_inst_parameters_type_ids [i] = get_typeid_for_type (method_inst->type_argv [i]); ep_rt_mono_log_type_and_parameters_if_necessary (type_logger, method_inst->type_argv [i]); @@ -3524,7 +3524,7 @@ ep_rt_mono_write_event_method_il_to_native_map ( } if (il_offsets) { native_offsets = il_offsets + offset_entries; - for (int32_t offset_count = 0; offset_count < offset_entries; ++offset_count) { + for (uint32_t offset_count = 0; offset_count < offset_entries; ++offset_count) { il_offsets [offset_count] = debug_info->line_numbers [offset_count].il_offset; native_offsets [offset_count] = debug_info->line_numbers [offset_count].native_offset; } diff --git a/src/mono/mono/eventpipe/ep-rt-mono.h b/src/mono/mono/eventpipe/ep-rt-mono.h index d50d019762ba23..669e2457bae0c6 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.h +++ b/src/mono/mono/eventpipe/ep-rt-mono.h @@ -1460,7 +1460,7 @@ ep_rt_temp_path_get ( const ep_char8_t *path = g_get_tmp_dir (); int32_t result = snprintf (buffer, buffer_len, "%s", path); - if (result <= 0 || result > buffer_len) + if (result <= 0 || GINT32_TO_UINT32(result) > buffer_len) ep_raise_error (); if (buffer [result - 1] != G_DIR_SEPARATOR) { diff --git a/src/mono/mono/metadata/class-init.c b/src/mono/mono/metadata/class-init.c index 823a2f814fcad1..7619ebecdc4e39 100644 --- a/src/mono/mono/metadata/class-init.c +++ b/src/mono/mono/metadata/class-init.c @@ -436,7 +436,7 @@ mono_class_create_from_typedef (MonoImage *image, guint32 type_token, MonoError MonoClass *klass, *parent = NULL; guint32 cols [MONO_TYPEDEF_SIZE]; guint32 cols_next [MONO_TYPEDEF_SIZE]; - guint tidx = mono_metadata_token_index (type_token); + guint32 tidx = mono_metadata_token_index (type_token); MonoGenericContext *context = NULL; const char *name, *nspace; guint icount = 0; @@ -2020,7 +2020,8 @@ mono_class_layout_fields (MonoClass *klass, int base_instance_size, int packing_ int i; const int top = mono_class_get_field_count (klass); guint32 layout = mono_class_get_flags (klass) & TYPE_ATTRIBUTE_LAYOUT_MASK; - guint32 pass, passes, real_size; + guint32 pass, passes; + gint32 real_size; gboolean gc_aware_layout = FALSE; gboolean has_static_fields = FALSE; gboolean has_references = FALSE; @@ -2270,8 +2271,7 @@ mono_class_layout_fields (MonoClass *klass, int base_instance_size, int packing_ case TYPE_ATTRIBUTE_EXPLICIT_LAYOUT: { real_size = 0; for (i = 0; i < top; i++) { - gint32 align; - guint32 size; + gint32 align, size; MonoType *ftype; field = &klass->fields [i]; @@ -2815,7 +2815,7 @@ mono_get_unique_iid (MonoClass *klass) iid = mono_bitset_find_first_unset (global_interface_bitset, -1); if (iid < 0) { - int old_size = mono_bitset_size (global_interface_bitset); + guint32 old_size = mono_bitset_size (global_interface_bitset); MonoBitSet *new_set = mono_bitset_clone (global_interface_bitset, old_size * 2); mono_bitset_free (global_interface_bitset); global_interface_bitset = new_set; @@ -2825,7 +2825,7 @@ mono_get_unique_iid (MonoClass *klass) /* set the bit also in the per-image set */ if (!mono_class_is_ginst (klass)) { if (klass->image->interface_bitset) { - if (iid >= mono_bitset_size (klass->image->interface_bitset)) { + if (GINT_TO_UINT32(iid) >= mono_bitset_size (klass->image->interface_bitset)) { MonoBitSet *new_set = mono_bitset_clone (klass->image->interface_bitset, iid + 1); mono_bitset_free (klass->image->interface_bitset); klass->image->interface_bitset = new_set; @@ -3567,12 +3567,11 @@ mono_class_setup_methods (MonoClass *klass) void mono_class_setup_properties (MonoClass *klass) { - guint startm, endm, i, j; + guint startm, endm; guint32 cols [MONO_PROPERTY_SIZE]; MonoTableInfo *msemt = &klass->image->tables [MONO_TABLE_METHODSEMANTICS]; MonoProperty *properties; - guint32 last; - int first, count; + guint32 first, last, count; MonoClassPropertyInfo *info; info = mono_class_get_property_info (klass); @@ -3590,7 +3589,7 @@ mono_class_setup_properties (MonoClass *klass) MonoClassPropertyInfo *ginfo = mono_class_get_property_info (gklass); properties = mono_class_new0 (klass, MonoProperty, ginfo->count + 1); - for (i = 0; i < ginfo->count; i++) { + for (guint32 i = 0; i < ginfo->count; i++) { ERROR_DECL (error); MonoProperty *prop = &properties [i]; @@ -3611,6 +3610,7 @@ mono_class_setup_properties (MonoClass *klass) count = ginfo->count; } else { first = mono_metadata_properties_from_typedef (klass->image, mono_metadata_token_index (klass->type_token) - 1, &last); + g_assert ((last - first) >= 0); count = last - first; if (count) { @@ -3620,7 +3620,7 @@ mono_class_setup_properties (MonoClass *klass) } properties = (MonoProperty *)mono_class_alloc0 (klass, sizeof (MonoProperty) * count); - for (i = first; i < last; ++i) { + for (guint32 i = first; i < last; ++i) { mono_metadata_decode_table_row (klass->image, MONO_TABLE_PROPERTY, i, cols, MONO_PROPERTY_SIZE); properties [i - first].parent = klass; properties [i - first].attrs = cols [MONO_PROPERTY_FLAGS]; @@ -3628,7 +3628,7 @@ mono_class_setup_properties (MonoClass *klass) startm = mono_metadata_methods_from_property (klass->image, i, &endm); int first_idx = mono_class_get_first_method_idx (klass); - for (j = startm; j < endm; ++j) { + for (guint j = startm; j < endm; ++j) { MonoMethod *method; mono_metadata_decode_row (msemt, j, cols, MONO_METHOD_SEMA_SIZE); @@ -3690,11 +3690,10 @@ inflate_method_listz (MonoMethod **methods, MonoClass *klass, MonoGenericContext void mono_class_setup_events (MonoClass *klass) { - int first, count; - guint startm, endm, i, j; + guint32 first, last, count; + guint startm, endm; guint32 cols [MONO_EVENT_SIZE]; MonoTableInfo *msemt = &klass->image->tables [MONO_TABLE_METHODSEMANTICS]; - guint32 last; MonoEvent *events; MonoClassEventInfo *info = mono_class_get_event_info (klass); @@ -3718,7 +3717,7 @@ mono_class_setup_events (MonoClass *klass) if (count) context = mono_class_get_context (klass); - for (i = 0; i < count; i++) { + for (guint32 i = 0; i < count; i++) { ERROR_DECL (error); MonoEvent *event = &events [i]; MonoEvent *gevent = &ginfo->events [i]; @@ -3739,6 +3738,7 @@ mono_class_setup_events (MonoClass *klass) } } else { first = mono_metadata_events_from_typedef (klass->image, mono_metadata_token_index (klass->type_token) - 1, &last); + g_assert ((last - first) >= 0); count = last - first; if (count) { @@ -3749,7 +3749,7 @@ mono_class_setup_events (MonoClass *klass) } events = (MonoEvent *)mono_class_alloc0 (klass, sizeof (MonoEvent) * count); - for (i = first; i < last; ++i) { + for (guint32 i = first; i < last; ++i) { MonoEvent *event = &events [i - first]; mono_metadata_decode_table_row (klass->image, MONO_TABLE_EVENT, i, cols, MONO_EVENT_SIZE); @@ -3759,7 +3759,7 @@ mono_class_setup_events (MonoClass *klass) startm = mono_metadata_methods_from_event (klass->image, i, &endm); int first_idx = mono_class_get_first_method_idx (klass); - for (j = startm; j < endm; ++j) { + for (guint j = startm; j < endm; ++j) { MonoMethod *method; mono_metadata_decode_row (msemt, j, cols, MONO_METHOD_SEMA_SIZE); diff --git a/src/mono/mono/metadata/icall.c b/src/mono/mono/metadata/icall.c index dfee0edc45df73..e86a99cde62ffc 100644 --- a/src/mono/mono/metadata/icall.c +++ b/src/mono/mono/metadata/icall.c @@ -5044,17 +5044,18 @@ static MonoArrayHandle mono_module_get_types (MonoImage *image, MonoArrayHandleOut exceptions, MonoBoolean exportedOnly, MonoError *error) { MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF]; - int rows = mono_metadata_table_num_rows (image, MONO_TABLE_TYPEDEF); - int i, count; + guint32 rows = mono_metadata_table_num_rows (image, MONO_TABLE_TYPEDEF); + guint32 count; /* we start the count from 1 because we skip the special type */ if (exportedOnly) { count = 0; - for (i = 1; i < rows; ++i) { + for (guint32 i = 1; i < rows; ++i) { if (mono_module_type_is_visible (tdef, image, i + 1)) count++; } } else { + g_assert (rows > 0); count = rows - 1; } MonoArrayHandle res = mono_array_new_handle (mono_defaults.runtimetype_class, count, error); @@ -5062,7 +5063,7 @@ mono_module_get_types (MonoImage *image, MonoArrayHandleOut exceptions, MonoBool MONO_HANDLE_ASSIGN (exceptions, mono_array_new_handle (mono_defaults.exception_class, count, error)); return_val_if_nok (error, NULL_HANDLE_ARRAY); count = 0; - for (i = 1; i < rows; ++i) { + for (guint32 i = 1; i < rows; ++i) { if (!exportedOnly || mono_module_type_is_visible (tdef, image, i+1)) { image_get_type (image, tdef, i + 1, count, res, exceptions, exportedOnly, error); return_val_if_nok (error, NULL_HANDLE_ARRAY); @@ -5430,8 +5431,8 @@ static gboolean mono_memberref_is_method (MonoImage *image, guint32 token) { if (!image_is_dynamic (image)) { - int idx = mono_metadata_token_index (token); - if (idx <= 0 || mono_metadata_table_bounds_check (image, MONO_TABLE_MEMBERREF, idx)) { + uint32_t idx = mono_metadata_token_index (token); + if (idx == 0 || mono_metadata_table_bounds_check (image, MONO_TABLE_MEMBERREF, idx)) { return FALSE; } @@ -5500,7 +5501,7 @@ module_resolve_type_token (MonoImage *image, guint32 token, MonoArrayHandle type MonoType *result = NULL; MonoClass *klass; int table = mono_metadata_token_table (token); - int index = mono_metadata_token_index (token); + uint32_t index = mono_metadata_token_index (token); MonoGenericContext context; *resolve_error = ResolveTokenError_Other; @@ -5529,7 +5530,7 @@ module_resolve_type_token (MonoImage *image, guint32 token, MonoArrayHandle type goto leave; } - if ((index <= 0) || mono_metadata_table_bounds_check (image, table, index)) { + if ((index == 0) || mono_metadata_table_bounds_check (image, table, index)) { *resolve_error = ResolveTokenError_OutOfRange; goto leave; } @@ -5558,7 +5559,7 @@ module_resolve_method_token (MonoImage *image, guint32 token, MonoArrayHandle ty HANDLE_FUNCTION_ENTER (); MonoMethod *method = NULL; int table = mono_metadata_token_table (token); - int index = mono_metadata_token_index (token); + uint32_t index = mono_metadata_token_index (token); MonoGenericContext context; *resolve_error = ResolveTokenError_Other; @@ -5590,7 +5591,7 @@ module_resolve_method_token (MonoImage *image, guint32 token, MonoArrayHandle ty goto leave; } - if ((index <= 0) || mono_metadata_table_bounds_check (image, table, index)) { + if ((index == 0) || mono_metadata_table_bounds_check (image, table, index)) { *resolve_error = ResolveTokenError_OutOfRange; goto leave; } @@ -5649,7 +5650,7 @@ module_resolve_field_token (MonoImage *image, guint32 token, MonoArrayHandle typ HANDLE_FUNCTION_ENTER (); MonoClass *klass; int table = mono_metadata_token_table (token); - int index = mono_metadata_token_index (token); + uint32_t index = mono_metadata_token_index (token); MonoGenericContext context; MonoClassField *field = NULL; @@ -5681,7 +5682,7 @@ module_resolve_field_token (MonoImage *image, guint32 token, MonoArrayHandle typ goto leave; } - if ((index <= 0) || mono_metadata_table_bounds_check (image, table, index)) { + if ((index == 0) || mono_metadata_table_bounds_check (image, table, index)) { *resolve_error = ResolveTokenError_OutOfRange; goto leave; } @@ -5766,7 +5767,7 @@ MonoArrayHandle ves_icall_System_Reflection_RuntimeModule_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error, MonoError *error) { int table = mono_metadata_token_table (token); - int idx = mono_metadata_token_index (token); + uint32_t idx = mono_metadata_token_index (token); MonoTableInfo *tables = image->tables; guint32 sig, len; const char *ptr; diff --git a/src/mono/mono/metadata/metadata-internals.h b/src/mono/mono/metadata/metadata-internals.h index 7539845aa17e3b..973dcded724ba5 100644 --- a/src/mono/mono/metadata/metadata-internals.h +++ b/src/mono/mono/metadata/metadata-internals.h @@ -697,7 +697,7 @@ assembly_is_dynamic (MonoAssembly *assembly) #endif } -static inline int +static inline uint32_t table_info_get_rows (const MonoTableInfo *table) { return table->rows_; @@ -793,16 +793,16 @@ gboolean mono_metadata_has_updates_api (void); void -mono_image_effective_table_slow (const MonoTableInfo **t, int idx); +mono_image_effective_table_slow (const MonoTableInfo **t, uint32_t idx); gboolean mono_metadata_update_has_modified_rows (const MonoTableInfo *t); static inline void -mono_image_effective_table (const MonoTableInfo **t, int idx) +mono_image_effective_table (const MonoTableInfo **t, uint32_t idx) { if (G_UNLIKELY (mono_metadata_has_updates ())) { - if (G_UNLIKELY (idx >= table_info_get_rows ((*t)) || mono_metadata_update_has_modified_rows (*t))) { + if (G_UNLIKELY (idx >= table_info_get_rows (*t) || mono_metadata_update_has_modified_rows (*t))) { mono_image_effective_table_slow (t, idx); } } @@ -836,7 +836,7 @@ void mono_metadata_decode_row_raw (const MonoTableInfo *t, int idx, uint32_t *res, int res_size); gboolean -mono_metadata_decode_row_dynamic_checked (const MonoDynamicImage *image, const MonoDynamicTable *t, int idx, guint32 *res, int res_size, MonoError *error); +mono_metadata_decode_row_dynamic_checked (const MonoDynamicImage *image, const MonoDynamicTable *t, guint idx, guint32 *res, int res_size, MonoError *error); MonoType* mono_metadata_get_shared_type (MonoType *type); @@ -847,10 +847,10 @@ mono_metadata_clean_generic_classes_for_image (MonoImage *image); gboolean mono_metadata_table_bounds_check_slow (MonoImage *image, int table_index, int token_index); -int +guint32 mono_metadata_table_num_rows_slow (MonoImage *image, int table_index); -static inline int +static inline guint32 mono_metadata_table_num_rows (MonoImage *image, int table_index) { if (G_LIKELY (!image->has_updates)) @@ -864,7 +864,7 @@ static inline gboolean mono_metadata_table_bounds_check (MonoImage *image, int table_index, int token_index) { /* returns true if given index is not in bounds with provided table/index pair */ - if (G_LIKELY (token_index <= table_info_get_rows (&image->tables [table_index]))) + if (G_LIKELY (GINT_TO_UINT32(token_index) <= table_info_get_rows (&image->tables [table_index]))) return FALSE; if (G_LIKELY (!image->has_updates)) return TRUE; @@ -905,7 +905,7 @@ MonoMethodSignature *mono_metadata_parse_signature_checked (MonoImage *image, gboolean mono_method_get_header_summary (MonoMethod *method, MonoMethodHeaderSummary *summary); -int* mono_metadata_get_param_attrs (MonoImage *m, int def, int param_count); +int* mono_metadata_get_param_attrs (MonoImage *m, int def, guint32 param_count); gboolean mono_metadata_method_has_param_attrs (MonoImage *m, int def); guint diff --git a/src/mono/mono/metadata/metadata-update.c b/src/mono/mono/metadata/metadata-update.c index 553310708523ab..490c91779f1819 100644 --- a/src/mono/mono/metadata/metadata-update.c +++ b/src/mono/mono/metadata/metadata-update.c @@ -62,7 +62,7 @@ mono_metadata_update_cleanup_on_close (MonoImage *base_image) } void -mono_image_effective_table_slow (const MonoTableInfo **t, int idx) +mono_image_effective_table_slow (const MonoTableInfo **t, uint32_t idx) { mono_component_hot_reload ()->effective_table_slow (t, idx); } @@ -143,7 +143,7 @@ mono_metadata_has_updates_api (void) * Returns the number of rows from the specified table that the current thread can see. * If there's a EnC metadata update, this number may change. */ -int +guint32 mono_metadata_table_num_rows_slow (MonoImage *base_image, int table_index) { return mono_component_hot_reload()->table_num_rows_slow (base_image, table_index); diff --git a/src/mono/mono/metadata/metadata.c b/src/mono/mono/metadata/metadata.c index 302b923bcbd77a..1d8d07490c7c0f 100644 --- a/src/mono/mono/metadata/metadata.c +++ b/src/mono/mono/metadata/metadata.c @@ -990,7 +990,7 @@ mono_metadata_compute_size (MonoImage *meta, int tableindex, guint32 *result_bit gboolean mono_metadata_table_bounds_check_slow (MonoImage *image, int table_index, int token_index) { - if (G_LIKELY (token_index <= table_info_get_rows (&image->tables [table_index]))) + if (G_LIKELY (GINT_TO_UINT32(token_index) <= table_info_get_rows (&image->tables [table_index]))) return FALSE; if (G_LIKELY (!image->has_updates)) @@ -1037,7 +1037,7 @@ mono_metadata_locate (MonoImage *meta, int table, int idx) { /* FIXME: metadata-update */ /* idx == 0 refers always to NULL */ - g_return_val_if_fail (idx > 0 && idx <= table_info_get_rows (&meta->tables [table]), ""); /*FIXME shouldn't we return NULL here?*/ + g_return_val_if_fail (idx > 0 && GINT_TO_UINT32(idx) <= table_info_get_rows (&meta->tables [table]), ""); /*FIXME shouldn't we return NULL here?*/ return meta->tables [table].base + (meta->tables [table].row_size * (idx - 1)); } @@ -1303,6 +1303,7 @@ mono_metadata_decode_row (const MonoTableInfo *t, int idx, guint32 *res, int res void mono_metadata_decode_row_slow (const MonoTableInfo *t, int idx, guint32 *res, int res_size) { + g_assert (idx >= 0); mono_image_effective_table (&t, idx); mono_metadata_decode_row_raw (t, idx, res, res_size); } @@ -1317,7 +1318,7 @@ mono_metadata_decode_row_raw (const MonoTableInfo *t, int idx, guint32 *res, int int i, count = mono_metadata_table_count (bitfield); const char *data; - g_assert (idx < table_info_get_rows (t)); + g_assert (GINT_TO_UINT32(idx) < table_info_get_rows (t)); g_assert (idx >= 0); data = t->base + idx * t->row_size; @@ -1359,12 +1360,13 @@ mono_metadata_decode_row_checked (const MonoImage *image, const MonoTableInfo *t { const char *image_name = image && image->name ? image->name : "unknown image"; + g_assert (idx >= 0); mono_image_effective_table (&t, idx); guint32 bitfield = t->size_bitfield; int i, count = mono_metadata_table_count (bitfield); - if (G_UNLIKELY (! (idx < table_info_get_rows (t) && idx >= 0))) { + if (G_UNLIKELY (! (GINT_TO_UINT32(idx) < table_info_get_rows (t) && idx >= 0))) { mono_error_set_bad_image_by_name (error, image_name, "row index %d out of bounds: %d rows: %s", idx, table_info_get_rows (t), image_name); return FALSE; } @@ -1396,7 +1398,7 @@ mono_metadata_decode_row_checked (const MonoImage *image, const MonoTableInfo *t } gboolean -mono_metadata_decode_row_dynamic_checked (const MonoDynamicImage *image, const MonoDynamicTable *t, int idx, guint32 *res, int res_size, MonoError *error) +mono_metadata_decode_row_dynamic_checked (const MonoDynamicImage *image, const MonoDynamicTable *t, guint idx, guint32 *res, int res_size, MonoError *error) { int i, count = t->columns; @@ -1448,6 +1450,7 @@ mono_metadata_decode_row_col (const MonoTableInfo *t, int idx, guint col) guint32 mono_metadata_decode_row_col_slow (const MonoTableInfo *t, int idx, guint col) { + g_assert (idx >= 0); mono_image_effective_table (&t, idx); return mono_metadata_decode_row_col_raw (t, idx, col); } @@ -1461,18 +1464,17 @@ mono_metadata_decode_row_col_slow (const MonoTableInfo *t, int idx, guint col) guint32 mono_metadata_decode_row_col_raw (const MonoTableInfo *t, int idx, guint col) { - int i; const char *data; int n; guint32 bitfield = t->size_bitfield; - g_assert (idx < table_info_get_rows (t)); + g_assert (GINT_TO_UINT32(idx) < table_info_get_rows (t)); g_assert (col < mono_metadata_table_count (bitfield)); data = t->base + idx * t->row_size; n = mono_metadata_table_size (bitfield, 0); - for (i = 0; i < col; ++i) { + for (guint i = 0; i < col; ++i) { data += n; n = mono_metadata_table_size (bitfield, i + 1); } @@ -1868,11 +1870,10 @@ mono_metadata_generic_inst_hash (gconstpointer data) { const MonoGenericInst *ginst = (const MonoGenericInst *) data; guint hash = 0; - int i; g_assert (ginst); g_assert (ginst->type_argv); - for (i = 0; i < ginst->type_argc; ++i) { + for (guint i = 0; i < ginst->type_argc; ++i) { hash *= 13; g_assert (ginst->type_argv [i]); hash += mono_metadata_type_hash (ginst->type_argv [i]); @@ -1884,8 +1885,6 @@ mono_metadata_generic_inst_hash (gconstpointer data) static gboolean mono_generic_inst_equal_full (const MonoGenericInst *a, const MonoGenericInst *b, gboolean signature_only) { - int i; - // An optimization: if the ids of two insts are the same, we know they are the same inst and don't check contents. // Furthermore, because we perform early de-duping, if the ids differ, we know the contents differ. #ifndef MONO_SMALL_CONFIG // Optimization does not work in MONO_SMALL_CONFIG: There are no IDs @@ -1901,7 +1900,7 @@ mono_generic_inst_equal_full (const MonoGenericInst *a, const MonoGenericInst *b if (a->is_open != b->is_open || a->type_argc != b->type_argc) return FALSE; - for (i = 0; i < a->type_argc; ++i) { + for (guint i = 0; i < a->type_argc; ++i) { if (!do_mono_metadata_type_equal (a->type_argv [i], b->type_argv [i], signature_only)) return FALSE; } @@ -2285,7 +2284,7 @@ mono_metadata_method_has_param_attrs (MonoImage *m, int def) return FALSE; /* FIXME: metadata-update */ - if (def < table_info_get_rows (methodt)) + if (GINT_TO_UINT32(def) < table_info_get_rows (methodt)) lastp = mono_metadata_decode_row_col (methodt, def, MONO_METHOD_PARAMLIST); else lastp = table_info_get_rows (&m->tables [MONO_TABLE_PARAM]) + 1; @@ -2311,7 +2310,7 @@ mono_metadata_method_has_param_attrs (MonoImage *m, int def) * 0, then NULL is returned. */ int* -mono_metadata_get_param_attrs (MonoImage *m, int def, int param_count) +mono_metadata_get_param_attrs (MonoImage *m, int def, guint32 param_count) { MonoTableInfo *paramt = &m->tables [MONO_TABLE_PARAM]; MonoTableInfo *methodt = &m->tables [MONO_TABLE_METHOD]; @@ -2324,8 +2323,7 @@ mono_metadata_get_param_attrs (MonoImage *m, int def, int param_count) return NULL; /* FIXME: metadata-update */ - int rows = mono_metadata_table_num_rows (m, MONO_TABLE_METHOD); - if (def < rows) + if (GINT_TO_UINT32(def) < mono_metadata_table_num_rows (m, MONO_TABLE_METHOD)) lastp = mono_metadata_decode_row_col (methodt, def, MONO_METHOD_PARAMLIST); else lastp = table_info_get_rows (paramt) + 1; @@ -2904,9 +2902,7 @@ signature_in_image (MonoMethodSignature *sig, MonoImage *image) static gboolean ginst_in_image (MonoGenericInst *ginst, MonoImage *image) { - int i; - - for (i = 0; i < ginst->type_argc; ++i) { + for (guint i = 0; i < ginst->type_argc; ++i) { if (type_in_image (ginst->type_argv [i], image)) return TRUE; } @@ -3034,9 +3030,7 @@ collect_type_images (MonoType *type, CollectData *data); static void collect_ginst_images (MonoGenericInst *ginst, CollectData *data) { - int i; - - for (i = 0; i < ginst->type_argc; ++i) { + for (guint i = 0; i < ginst->type_argc; ++i) { collect_type_images (ginst->type_argv [i], data); } } @@ -3233,10 +3227,8 @@ check_gmethod (gpointer key, gpointer value, gpointer data) static void free_generic_inst (MonoGenericInst *ginst) { - int i; - /* The ginst itself is allocated from the image set mempool */ - for (i = 0; i < ginst->type_argc; ++i) + for (guint i = 0; i < ginst->type_argc; ++i) mono_metadata_free_type (ginst->type_argv [i]); } @@ -3569,7 +3561,7 @@ mono_metadata_inflate_generic_inst (MonoGenericInst *ginst, MonoGenericContext * { MonoType **type_argv; MonoGenericInst *nginst = NULL; - int i, count = 0; + guint count = 0; error_init (error); @@ -3578,7 +3570,7 @@ mono_metadata_inflate_generic_inst (MonoGenericInst *ginst, MonoGenericContext * type_argv = g_new0 (MonoType*, ginst->type_argc); - for (i = 0; i < ginst->type_argc; i++) { + for (guint i = 0; i < ginst->type_argc; i++) { type_argv [i] = mono_class_inflate_generic_type_checked (ginst->type_argv [i], context, error); if (!is_ok (error)) goto cleanup; @@ -3588,7 +3580,7 @@ mono_metadata_inflate_generic_inst (MonoGenericInst *ginst, MonoGenericContext * nginst = mono_metadata_get_generic_inst (ginst->type_argc, type_argv); cleanup: - for (i = 0; i < count; i++) + for (guint i = 0; i < count; i++) mono_metadata_free_type (type_argv [i]); g_free (type_argv); @@ -4653,9 +4645,9 @@ mono_metadata_token_from_dor (guint32 dor_index) * We use this to pass context information to the row locator */ typedef struct { - int idx; /* The index that we are trying to locate */ - int col_idx; /* The index in the row where idx may be stored */ - MonoTableInfo *t; /* pointer to the table */ + guint32 idx; /* The index that we are trying to locate */ + guint32 col_idx; /* The index in the row where idx may be stored */ + MonoTableInfo *t; /* pointer to the table */ guint32 result; } locator_t; @@ -4707,7 +4699,8 @@ typedef_locator (const void *a, const void *b) /* * Need to check that the next row is valid. */ - if (typedef_index + 1 < table_info_get_rows (loc->t)) { + g_assert (typedef_index >= 0); + if (GINT_TO_UINT32(typedef_index) + 1 < table_info_get_rows (loc->t)) { col_next = mono_metadata_decode_row_col (loc->t, typedef_index + 1, loc->col_idx); if (loc->idx >= col_next) return 1; @@ -4922,7 +4915,7 @@ mono_metadata_interfaces_from_typedef_full (MonoImage *meta, guint32 index, Mono break; } pos = start; - int rows = mono_metadata_table_num_rows (meta, MONO_TABLE_INTERFACEIMPL); + guint32 rows = mono_metadata_table_num_rows (meta, MONO_TABLE_INTERFACEIMPL); while (pos < rows) { mono_metadata_decode_row (tdef, pos, cols, MONO_INTERFACEIMPL_SIZE); if (cols [MONO_INTERFACEIMPL_CLASS] != loc.idx) @@ -5038,7 +5031,7 @@ mono_metadata_nesting_typedef (MonoImage *meta, guint32 index, guint32 start_ind start = start_index; - int rows = mono_metadata_table_num_rows (meta, MONO_TABLE_NESTEDCLASS); + guint32 rows = mono_metadata_table_num_rows (meta, MONO_TABLE_NESTEDCLASS); while (start <= rows) { if (class_index == mono_metadata_decode_row_col (tdef, start - 1, MONO_NESTED_CLASS_ENCLOSING)) break; @@ -6360,7 +6353,7 @@ guint32 mono_metadata_methods_from_event (MonoImage *meta, guint32 index, guint *end_idx) { locator_t loc; - guint start, end; + guint32 start, end; guint32 cols [MONO_METHOD_SEMA_SIZE]; MonoTableInfo *msemt = &meta->tables [MONO_TABLE_METHODSEMANTICS]; @@ -6397,14 +6390,14 @@ mono_metadata_methods_from_event (MonoImage *meta, guint32 index, guint *end_i break; } end = start + 1; - int rows = mono_metadata_table_num_rows (meta, MONO_TABLE_METHODSEMANTICS); + guint32 rows = mono_metadata_table_num_rows (meta, MONO_TABLE_METHODSEMANTICS); while (end < rows) { mono_metadata_decode_row (msemt, end, cols, MONO_METHOD_SEMA_SIZE); if (cols [MONO_METHOD_SEMA_ASSOCIATION] != loc.idx) break; ++end; } - *end_idx = end; + *end_idx = GUINT32_TO_UINT(end); return start; } @@ -6457,7 +6450,7 @@ mono_metadata_properties_from_typedef (MonoImage *meta, guint32 index, guint *en end = mono_metadata_table_num_rows (meta, MONO_TABLE_PROPERTY); } - *end_idx = end; + *end_idx = GUINT32_TO_UINT(end); return start - 1; } @@ -6473,7 +6466,7 @@ guint32 mono_metadata_methods_from_property (MonoImage *meta, guint32 index, guint *end_idx) { locator_t loc; - guint start, end; + guint32 start, end; guint32 cols [MONO_METHOD_SEMA_SIZE]; MonoTableInfo *msemt = &meta->tables [MONO_TABLE_METHODSEMANTICS]; @@ -6510,14 +6503,14 @@ mono_metadata_methods_from_property (MonoImage *meta, guint32 index, guint *en break; } end = start + 1; - int rows = mono_metadata_table_num_rows (meta, MONO_TABLE_METHODSEMANTICS); + guint32 rows = mono_metadata_table_num_rows (meta, MONO_TABLE_METHODSEMANTICS); while (end < rows) { mono_metadata_decode_row (msemt, end, cols, MONO_METHOD_SEMA_SIZE); if (cols [MONO_METHOD_SEMA_ASSOCIATION] != loc.idx) break; ++end; } - *end_idx = end; + *end_idx = GUINT32_TO_UINT(end); return start; } @@ -7043,7 +7036,7 @@ mono_class_get_overrides_full (MonoImage *image, guint32 type_token, MonoMethod else break; } - int rows = table_info_get_rows (tdef); + guint32 rows = table_info_get_rows (tdef); while (end < rows) { if (loc.idx == mono_metadata_decode_row_col (tdef, end, MONO_METHODIMPL_CLASS)) end++; @@ -7126,7 +7119,7 @@ get_constraints (MonoImage *image, int owner, MonoClass ***constraints, MonoGene *constraints = NULL; found = 0; /* FIXME: metadata-update */ - int rows = table_info_get_rows (tdef); + guint32 rows = table_info_get_rows (tdef); for (i = 0; i < rows; ++i) { mono_metadata_decode_row (tdef, i, cols, MONO_GENPARCONSTRAINT_SIZE); if (cols [MONO_GENPARCONSTRAINT_GENERICPAR] == owner) { @@ -7221,12 +7214,12 @@ mono_metadata_load_generic_param_constraints_checked (MonoImage *image, guint32 MonoGenericContainer *container, MonoError *error) { - guint32 start_row, i, owner; + guint32 start_row, owner; error_init (error); if (! (start_row = mono_metadata_get_generic_param_row (image, token, &owner))) return TRUE; - for (i = 0; i < container->type_argc; i++) { + for (int i = 0; i < container->type_argc; i++) { if (!get_constraints (image, start_row + i, &mono_generic_container_get_param_info (container, i)->constraints, container, error)) { return FALSE; } @@ -7256,7 +7249,7 @@ mono_metadata_load_generic_params (MonoImage *image, guint32 token, MonoGenericC { MonoTableInfo *tdef = &image->tables [MONO_TABLE_GENERICPARAM]; guint32 cols [MONO_GENERICPARAM_SIZE]; - guint32 i, owner = 0, n; + guint32 owner = 0, i; MonoGenericContainer *container; MonoGenericParamFull *params; MonoGenericContext *context; @@ -7267,7 +7260,6 @@ mono_metadata_load_generic_params (MonoImage *image, guint32 token, MonoGenericC return NULL; mono_metadata_decode_row (tdef, i - 1, cols, MONO_GENERICPARAM_SIZE); params = NULL; - n = 0; container = (MonoGenericContainer *)mono_image_alloc0 (image, sizeof (MonoGenericContainer)); container->is_anonymous = is_anonymous; if (is_anonymous) { @@ -7279,8 +7271,8 @@ mono_metadata_load_generic_params (MonoImage *image, guint32 token, MonoGenericC container->owner.klass = (MonoClass*)real_owner; } /* first pass over the gparam table - just count how many params we own */ - uint32_t type_argc = 0; - uint32_t i2 = i; + guint32 type_argc = 0; + guint32 i2 = i; do { type_argc++; if (++i2 > mono_metadata_table_num_rows (image, MONO_TABLE_GENERICPARAM)) @@ -7290,6 +7282,7 @@ mono_metadata_load_generic_params (MonoImage *image, guint32 token, MonoGenericC params = (MonoGenericParamFull *)mono_image_alloc0 (image, sizeof (MonoGenericParamFull) * type_argc); /* second pass, fill in the gparam data */ + guint32 n = 0; mono_metadata_decode_row (tdef, i - 1, cols, MONO_GENERICPARAM_SIZE); do { n++; diff --git a/src/mono/mono/mini/mini-amd64.c b/src/mono/mono/mini/mini-amd64.c index 4a9acc0298eeff..6e1057e64282f6 100644 --- a/src/mono/mono/mini/mini-amd64.c +++ b/src/mono/mono/mini/mini-amd64.c @@ -310,9 +310,7 @@ merge_argument_class_from_type (MonoType *type, ArgumentClass class1) /* fall through */ case MONO_TYPE_VALUETYPE: { MonoMarshalType *info = mono_marshal_load_type_info (ptype->data.klass); - int i; - - for (i = 0; i < info->num_fields; ++i) { + for (guint32 i = 0; i < info->num_fields; ++i) { class2 = class1; class2 = merge_argument_class_from_type (info->fields [i].field->type, class2); } @@ -339,7 +337,7 @@ merge_argument_class_from_type (MonoType *type, ArgumentClass class1) typedef struct { MonoType *type; - int size, offset; + guint32 size, offset; } StructFieldInfo; /* @@ -351,12 +349,11 @@ static void collect_field_info_nested (MonoClass *klass, GArray *fields_array, int offset, gboolean pinvoke, gboolean unicode) { MonoMarshalType *info; - int i; if (pinvoke) { info = mono_marshal_load_type_info (klass); g_assert(info); - for (i = 0; i < info->num_fields; ++i) { + for (guint32 i = 0; i < info->num_fields; ++i) { if (MONO_TYPE_ISSTRUCT (info->fields [i].field->type)) { collect_field_info_nested (mono_class_from_mono_type_internal (info->fields [i].field->type), fields_array, info->fields [i].offset, pinvoke, unicode); } else { @@ -417,7 +414,7 @@ collect_field_info_nested (MonoClass *klass, GArray *fields_array, int offset, g #define MONO_WIN64_VALUE_TYPE_FITS_REG(arg_size) (arg_size <= SIZEOF_REGISTER && (arg_size == 1 || arg_size == 2 || arg_size == 4 || arg_size == 8)) static gboolean -allocate_register_for_valuetype_win64 (ArgInfo *arg_info, ArgumentClass arg_class, guint32 arg_size, const AMD64_Reg_No int_regs [], int int_reg_count, const AMD64_XMM_Reg_No float_regs [], int float_reg_count, guint32 *current_int_reg, guint32 *current_float_reg) +allocate_register_for_valuetype_win64 (ArgInfo *arg_info, ArgumentClass arg_class, guint32 arg_size, const AMD64_Reg_No int_regs [], guint32 int_reg_count, const AMD64_XMM_Reg_No float_regs [], guint32 float_reg_count, guint32 *current_int_reg, guint32 *current_float_reg) { gboolean result = FALSE; @@ -1275,7 +1272,7 @@ mono_arch_get_native_call_context_args (CallContext *ccontext, gpointer frame, M gpointer storage; ArgInfo *ainfo; - for (int i = 0; i < sig->param_count + sig->hasthis; i++) { + for (guint i = 0; i < sig->param_count + sig->hasthis; i++) { ainfo = &cinfo->args [i]; if (ainfo->storage == ArgValuetypeAddrInIReg || ainfo->storage == ArgValuetypeAddrOnStack) { @@ -1504,9 +1501,8 @@ GList * mono_arch_get_allocatable_int_vars (MonoCompile *cfg) { GList *vars = NULL; - int i; - for (i = 0; i < cfg->num_varinfo; i++) { + for (guint i = 0; i < cfg->num_varinfo; i++) { MonoInst *ins = cfg->varinfo [i]; MonoMethodVar *vmv = MONO_VARINFO (cfg, i); @@ -1539,7 +1535,6 @@ mono_arch_compute_omit_fp (MonoCompile *cfg) { MonoMethodSignature *sig; MonoMethodHeader *header; - int i; CallInfo *cinfo; if (cfg->arch.omit_fp_computed) @@ -1576,7 +1571,7 @@ mono_arch_compute_omit_fp (MonoCompile *cfg) cfg->arch.omit_fp = FALSE; if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG)) cfg->arch.omit_fp = FALSE; - for (i = 0; i < sig->param_count + sig->hasthis; ++i) { + for (guint i = 0; i < sig->param_count + sig->hasthis; ++i) { ArgInfo *ainfo = &cinfo->args [i]; if (ainfo->storage == ArgOnStack || ainfo->storage == ArgValuetypeAddrInIReg || ainfo->storage == ArgValuetypeAddrOnStack) { @@ -1645,7 +1640,6 @@ mono_arch_fill_argument_info (MonoCompile *cfg) { MonoMethodSignature *sig; MonoInst *ins; - int i; CallInfo *cinfo; sig = mono_method_signature_internal (cfg->method); @@ -1676,7 +1670,7 @@ mono_arch_fill_argument_info (MonoCompile *cfg) g_assert_not_reached (); } - for (i = 0; i < sig->param_count + sig->hasthis; ++i) { + for (guint i = 0; i < sig->param_count + sig->hasthis; ++i) { ArgInfo *ainfo = &cinfo->args [i]; ins = cfg->args [i]; @@ -1709,7 +1703,7 @@ mono_arch_allocate_vars (MonoCompile *cfg) MonoType *sig_ret; MonoMethodSignature *sig; MonoInst *ins; - int i, offset; + int offset; guint32 locals_stack_size, locals_stack_align; gint32 *offsets; CallInfo *cinfo; @@ -1757,7 +1751,7 @@ mono_arch_allocate_vars (MonoCompile *cfg) if (cfg->arch.omit_fp) cfg->arch.reg_save_area_offset = offset; /* Reserve space for callee saved registers */ - for (i = 0; i < AMD64_NREG; ++i) + for (guint i = 0; i < AMD64_NREG; ++i) if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->arch.saved_iregs & (1 << i))) { offset += sizeof (target_mgreg_t); } @@ -1821,7 +1815,7 @@ mono_arch_allocate_vars (MonoCompile *cfg) cfg->locals_max_stack_offset = - offset; } - for (i = cfg->locals_start; i < cfg->num_varinfo; i++) { + for (guint i = cfg->locals_start; i < cfg->num_varinfo; i++) { if (offsets [i] != -1) { ins = cfg->varinfo [i]; ins->opcode = OP_REGOFFSET; @@ -1841,7 +1835,7 @@ mono_arch_allocate_vars (MonoCompile *cfg) cfg->sig_cookie = cinfo->sig_cookie.offset + ARGS_OFFSET; } - for (i = 0; i < sig->param_count + sig->hasthis; ++i) { + for (guint i = 0; i < sig->param_count + sig->hasthis; ++i) { ins = cfg->args [i]; if (ins->opcode != OP_REGVAR) { ArgInfo *ainfo = &cinfo->args [i]; @@ -5419,7 +5413,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) case OP_TAILCALL_REG: case OP_TAILCALL_MEMBASE: { call = (MonoCallInst*)ins; - int i, save_area_offset; + int save_area_offset; gboolean tailcall_membase = (ins->opcode == OP_TAILCALL_MEMBASE); gboolean tailcall_reg = (ins->opcode == OP_TAILCALL_REG); @@ -5456,7 +5450,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) /* Restore callee saved registers */ save_area_offset = cfg->arch.reg_save_area_offset; - for (i = 0; i < AMD64_NREG; ++i) + for (guint i = 0; i < AMD64_NREG; ++i) if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->used_int_regs & ((regmask_t)1 << i))) { amd64_mov_reg_membase (code, i, cfg->frame_reg, save_area_offset, 8); save_area_offset += 8; @@ -5473,7 +5467,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) /* Copy arguments on the stack to our argument area */ // FIXME use rep mov for constant code size, before nonvolatiles // restored, first saving rsi, rdi into volatiles - for (i = 0; i < call->stack_usage; i += sizeof (target_mgreg_t)) { + for (guint i = 0; i < call->stack_usage; i += sizeof (target_mgreg_t)) { amd64_mov_reg_membase (code, AMD64_RAX, AMD64_RSP, i + 8, sizeof (target_mgreg_t)); amd64_mov_membase_reg (code, AMD64_RBP, ARGS_OFFSET + i, AMD64_RAX, sizeof (target_mgreg_t)); } @@ -7861,7 +7855,7 @@ MONO_RESTORE_WARNING } /* Keep this in sync with emit_load_volatile_arguments */ - for (guint16 i = 0; i < sig->param_count + sig->hasthis; ++i) { + for (guint i = 0; i < sig->param_count + sig->hasthis; ++i) { ArgInfo *ainfo = cinfo->args + i; ins = cfg->args [i]; @@ -7981,7 +7975,7 @@ MONO_RESTORE_WARNING if (first_bb->in_count > 1) next = NULL; - for (guint16 i = 0; next && i < sig->param_count + sig->hasthis; ++i) { + for (guint i = 0; next && i < sig->param_count + sig->hasthis; ++i) { ArgInfo *ainfo = cinfo->args + i; gboolean match = FALSE; @@ -8440,7 +8434,6 @@ get_delegate_invoke_impl (MonoTrampInfo **info, gboolean has_target, guint32 par { guint8 *code, *start; GSList *unwind_ops = NULL; - int i; unwind_ops = mono_arch_get_cie_program (); @@ -8461,7 +8454,7 @@ get_delegate_invoke_impl (MonoTrampInfo **info, gboolean has_target, guint32 par } else { /* We have to shift the arguments left */ amd64_mov_reg_reg (code, AMD64_RAX, AMD64_ARG_REG1, 8); - for (i = 0; i < param_count; ++i) { + for (guint32 i = 0; i < param_count; ++i) { #ifdef TARGET_WIN32 if (i < 3) amd64_mov_reg_reg (code, param_regs [i], param_regs [i + 1], 8); diff --git a/src/mono/mono/mini/mini.h b/src/mono/mono/mini/mini.h index 3a4dd3453114be..cfe3d929ac9b22 100644 --- a/src/mono/mono/mini/mini.h +++ b/src/mono/mono/mini/mini.h @@ -1283,7 +1283,7 @@ typedef enum { #define MONO_REGION_FLAGS(region) ((region) & 0x7) #define MONO_REGION_CLAUSE_INDEX(region) (((region) >> 8) - 1) -#define get_vreg_to_inst(cfg, vreg) ((vreg) < (cfg)->vreg_to_inst_len ? (cfg)->vreg_to_inst [(vreg)] : NULL) +#define get_vreg_to_inst(cfg, vreg) (GINT32_TO_UINT32(vreg) < (cfg)->vreg_to_inst_len ? (cfg)->vreg_to_inst [(vreg)] : NULL) #define vreg_is_volatile(cfg, vreg) (G_UNLIKELY (get_vreg_to_inst ((cfg), (vreg)) && (get_vreg_to_inst ((cfg), (vreg))->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)))) From 63bdb98927f1a5b536caad6f1a430430dd278966 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 15 Jun 2022 08:42:50 -0700 Subject: [PATCH 134/337] Fix race condition in LoaderAllocator::CompareExchangeValueInHandle (#70765) The method was not actually using interlocked operation. It made it possible for multiple different values to win. Fixes #70742 --- src/coreclr/vm/loaderallocator.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/coreclr/vm/loaderallocator.cpp b/src/coreclr/vm/loaderallocator.cpp index 9e9c3cba3e6f06..aba0a96586178f 100644 --- a/src/coreclr/vm/loaderallocator.cpp +++ b/src/coreclr/vm/loaderallocator.cpp @@ -919,10 +919,11 @@ OBJECTREF LoaderAllocator::CompareExchangeValueInHandle(LOADERHANDLE handle, OBJ if ((((UINT_PTR)handle) & 1) != 0) { OBJECTREF *ptr = (OBJECTREF *)(((UINT_PTR)handle) - 1); - gc.previous = *ptr; - if ((*ptr) == gc.compare) + + gc.previous = InterlockedCompareExchangeT(ptr, gc.value, gc.compare); + if (gc.previous == gc.compare) { - SetObjectReference(ptr, gc.value); + ErectWriteBarrier(ptr, gc.value); } } else From 2f0a796a2b8873d0a861feeaa0d0136a2a87ca02 Mon Sep 17 00:00:00 2001 From: Vladimir Sadov Date: Wed, 15 Jun 2022 09:59:22 -0700 Subject: [PATCH 135/337] Enable redirection on arm64 (#70769) --- src/coreclr/nativeaot/Runtime/CMakeLists.txt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/coreclr/nativeaot/Runtime/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/CMakeLists.txt index 8ce6ea0d296722..3ad3ceba7c8f0e 100644 --- a/src/coreclr/nativeaot/Runtime/CMakeLists.txt +++ b/src/coreclr/nativeaot/Runtime/CMakeLists.txt @@ -245,10 +245,7 @@ add_definitions(-D_LIB) if(WIN32) add_definitions(-DFEATURE_ETW) add_definitions(-DFEATURE_EVENT_TRACE) - # redirection on ARM64 should work, but needs to be tested - if (CLR_CMAKE_TARGET_ARCH_AMD64) - add_definitions(-DFEATURE_SUSPEND_REDIRECTION) - endif() + add_definitions(-DFEATURE_SUSPEND_REDIRECTION) else() add_definitions(-DNO_UI_ASSERT) include(unix/configure.cmake) From f19d85b2b6673312c557293c5aadaac11dab84d7 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Wed, 15 Jun 2022 19:30:07 +0200 Subject: [PATCH 136/337] Handle HW exceptions on Windows without redirection (#70428) This change modifies the way hardware exceptions are propagated from the vectored exception handler. Until now, runtime was returning from the vectored exception handler with instruction pointer in the context set to an asm helper. That redirected the thread to that helper and we have raised an exception from its call chain. While working on CET support, it was found that propagating exceptions from the vectored exception handler directly works just fine. So this change makes it work that way for all Windows targets. --- .../vm/amd64/RedirectedHandledJITCase.asm | 22 ---- src/coreclr/vm/amd64/excepcpu.h | 2 +- src/coreclr/vm/arm/ehhelpers.asm | 23 ---- src/coreclr/vm/arm/exceparm.cpp | 4 +- src/coreclr/vm/arm/excepcpu.h | 2 +- src/coreclr/vm/arm64/asmhelpers.asm | 23 ---- src/coreclr/vm/arm64/excepcpu.h | 2 +- src/coreclr/vm/excep.cpp | 105 ++---------------- src/coreclr/vm/excep.h | 2 - src/coreclr/vm/exceptionhandling.cpp | 35 ------ src/coreclr/vm/i386/excepx86.cpp | 2 - src/coreclr/vm/loongarch64/excepcpu.h | 2 +- 12 files changed, 15 insertions(+), 209 deletions(-) diff --git a/src/coreclr/vm/amd64/RedirectedHandledJITCase.asm b/src/coreclr/vm/amd64/RedirectedHandledJITCase.asm index 6dededa9ab010e..61146cc6fbe59e 100644 --- a/src/coreclr/vm/amd64/RedirectedHandledJITCase.asm +++ b/src/coreclr/vm/amd64/RedirectedHandledJITCase.asm @@ -6,8 +6,6 @@ include asmconstants.inc Thread__GetAbortContext equ ?GetAbortContext@Thread@@QEAAPEAU_CONTEXT@@XZ -extern FixContextHandler:proc -extern LinkFrameAndThrow:proc extern GetCurrentSavedRedirectContext:proc extern Thread__GetAbortContext:proc extern HijackHandler:proc @@ -206,26 +204,6 @@ NESTED_END RedirectForThrowControl2, _TEXT GenerateRedirectedStubWithFrame RedirectForThrowControl, HijackHandler, RedirectForThrowControl2 -NAKED_THROW_HELPER_FRAME_SIZE = SIZEOF_MAX_OUTGOING_ARGUMENT_HOMES + 8 - -NESTED_ENTRY NakedThrowHelper2, _TEXT - - ; On entry - ; rcx -> FaultingExceptionFrame - - alloc_stack NAKED_THROW_HELPER_FRAME_SIZE - END_PROLOGUE - - call LinkFrameAndThrow - - ; LinkFrameAndThrow doesn't return. - int 3 - -NESTED_END NakedThrowHelper2, _TEXT - -GenerateRedirectedStubWithFrame NakedThrowHelper, FixContextHandler, NakedThrowHelper2 - - ifdef FEATURE_SPECIAL_USER_MODE_APC extern ?ApcActivationCallback@Thread@@CAX_K@Z:proc diff --git a/src/coreclr/vm/amd64/excepcpu.h b/src/coreclr/vm/amd64/excepcpu.h index 8ac8456b70c0ac..8f74f3a4a259d2 100644 --- a/src/coreclr/vm/amd64/excepcpu.h +++ b/src/coreclr/vm/amd64/excepcpu.h @@ -45,7 +45,7 @@ PTR_CONTEXT GetCONTEXTFromRedirectedStubStackFrame(CONTEXT * pContext); // // Retrieves the FaultingExceptionFrame* from the stack frame of -// RedirectForThrowControl or NakedThrowHelper. +// RedirectForThrowControl. // FaultingExceptionFrame *GetFrameFromRedirectedStubStackFrame (DISPATCHER_CONTEXT *pDispatcherContext); diff --git a/src/coreclr/vm/arm/ehhelpers.asm b/src/coreclr/vm/arm/ehhelpers.asm index def725942453a6..e0d17f15eb4d61 100644 --- a/src/coreclr/vm/arm/ehhelpers.asm +++ b/src/coreclr/vm/arm/ehhelpers.asm @@ -7,8 +7,6 @@ #include "asmmacros.h" - IMPORT FixContextHandler - IMPORT LinkFrameAndThrow IMPORT HijackHandler IMPORT ThrowControlForThread @@ -76,27 +74,6 @@ OFFSET_OF_FRAME SETA 4 + SIZEOF__GSCookie MEND -; ------------------------------------------------------------------ -; -; Helpers for async (NullRef, AccessViolation) exceptions -; - - NESTED_ENTRY NakedThrowHelper2,,FixContextHandler - PROLOG_PUSH {r0, lr} - - ; On entry: - ; - ; R0 = Address of FaultingExceptionFrame - bl LinkFrameAndThrow - - ; Target should not return. - EMIT_BREAKPOINT - - NESTED_END NakedThrowHelper2 - - - GenerateRedirectedStubWithFrame NakedThrowHelper, NakedThrowHelper2 - ; ------------------------------------------------------------------ ; ; Helpers for ThreadAbort exceptions diff --git a/src/coreclr/vm/arm/exceparm.cpp b/src/coreclr/vm/arm/exceparm.cpp index 59d61b0e1d60b7..9df2a36a04e0c5 100644 --- a/src/coreclr/vm/arm/exceparm.cpp +++ b/src/coreclr/vm/arm/exceparm.cpp @@ -37,8 +37,8 @@ PTR_CONTEXT GetCONTEXTFromRedirectedStubStackFrame(T_CONTEXT * pContext) // 2) represents the current context in the second pass. // // Since R4 is a non-volatile register, this works for us since we setup the value of R4 -// in the redirection helpers (e.g. NakedThrowHelper or RedirectForThreadAbort) but do not -// change it in their respective callee functions (e.g. NakedThrowHelper2 or RedirectForThreadAbort2) +// in the redirection helpers (e.g. RedirectForThreadAbort) but do not +// change it in their respective callee functions (e.g. RedirectForThreadAbort2) // that have the personality routines associated with them (which perform the collided unwind and also // invoke the two functions below). // diff --git a/src/coreclr/vm/arm/excepcpu.h b/src/coreclr/vm/arm/excepcpu.h index edde9e2f123dac..f0c002e70930ce 100644 --- a/src/coreclr/vm/arm/excepcpu.h +++ b/src/coreclr/vm/arm/excepcpu.h @@ -31,7 +31,7 @@ PTR_CONTEXT GetCONTEXTFromRedirectedStubStackFrame(T_CONTEXT * pContext); // // Retrieves the FaultingExceptionFrame* from the stack frame of -// RedirectForThrowControl or NakedThrowHelper. +// RedirectForThrowControl. // FaultingExceptionFrame *GetFrameFromRedirectedStubStackFrame (T_DISPATCHER_CONTEXT *pDispatcherContext); diff --git a/src/coreclr/vm/arm64/asmhelpers.asm b/src/coreclr/vm/arm64/asmhelpers.asm index 3f80f9db078d94..371790376b5a96 100644 --- a/src/coreclr/vm/arm64/asmhelpers.asm +++ b/src/coreclr/vm/arm64/asmhelpers.asm @@ -16,8 +16,6 @@ IMPORT UMEntryPrestubUnwindFrameChainHandler IMPORT TheUMEntryPrestubWorker IMPORT GetCurrentSavedRedirectContext - IMPORT LinkFrameAndThrow - IMPORT FixContextHandler IMPORT OnHijackWorker #ifdef FEATURE_READYTORUN IMPORT DynamicHelperWorker @@ -1030,27 +1028,6 @@ FaultingExceptionFrame_FrameOffset SETA SIZEOF__GSCookie MEND -; ------------------------------------------------------------------ -; -; Helpers for async (NullRef, AccessViolation) exceptions -; - - NESTED_ENTRY NakedThrowHelper2,,FixContextHandler - PROLOG_SAVE_REG_PAIR fp,lr, #-16! - - ; On entry: - ; - ; X0 = Address of FaultingExceptionFrame - bl LinkFrameAndThrow - - ; Target should not return. - EMIT_BREAKPOINT - - NESTED_END NakedThrowHelper2 - - - GenerateRedirectedStubWithFrame NakedThrowHelper, NakedThrowHelper2 - ; ------------------------------------------------------------------ ; ResolveWorkerChainLookupAsmStub ; diff --git a/src/coreclr/vm/arm64/excepcpu.h b/src/coreclr/vm/arm64/excepcpu.h index 9b73dbae2f779d..eb575235af8feb 100644 --- a/src/coreclr/vm/arm64/excepcpu.h +++ b/src/coreclr/vm/arm64/excepcpu.h @@ -33,7 +33,7 @@ PTR_CONTEXT GetCONTEXTFromRedirectedStubStackFrame(T_CONTEXT * pContext); // // Retrieves the FaultingExceptionFrame* from the stack frame of -// RedirectForThrowControl or NakedThrowHelper. +// RedirectForThrowControl. // FaultingExceptionFrame *GetFrameFromRedirectedStubStackFrame (T_DISPATCHER_CONTEXT *pDispatcherContext); diff --git a/src/coreclr/vm/excep.cpp b/src/coreclr/vm/excep.cpp index ae9e2fa714c226..e375130a04d0be 100644 --- a/src/coreclr/vm/excep.cpp +++ b/src/coreclr/vm/excep.cpp @@ -6582,66 +6582,6 @@ struct SavedExceptionInfo } }; -SavedExceptionInfo g_SavedExceptionInfo; // Globals are guaranteed zero-init; - -void InitSavedExceptionInfo() -{ - g_SavedExceptionInfo.Init(); -} - -EXTERN_C VOID FixContextForFaultingExceptionFrame ( - EXCEPTION_RECORD* pExceptionRecord, - CONTEXT *pContextRecord) -{ - WRAPPER_NO_CONTRACT; - - // don't copy parm args as have already supplied them on the throw - memcpy((void*) pExceptionRecord, - (void*) &g_SavedExceptionInfo.m_ExceptionRecord, - offsetof(EXCEPTION_RECORD, ExceptionInformation) - ); - - ReplaceExceptionContextRecord(pContextRecord, &g_SavedExceptionInfo.m_ExceptionContext); - - g_SavedExceptionInfo.Leave(); - - GetThread()->ResetThreadStateNC(Thread::TSNC_DebuggerIsManagedException); -} - -EXTERN_C VOID __fastcall -LinkFrameAndThrow(FaultingExceptionFrame* pFrame) -{ - WRAPPER_NO_CONTRACT; - - *(TADDR*)pFrame = FaultingExceptionFrame::GetMethodFrameVPtr(); - *pFrame->GetGSCookiePtr() = GetProcessGSCookie(); - - pFrame->InitAndLink(&g_SavedExceptionInfo.m_ExceptionContext); - - GetThread()->SetThreadStateNC(Thread::TSNC_DebuggerIsManagedException); - - ULONG argcount = g_SavedExceptionInfo.m_ExceptionRecord.NumberParameters; - ULONG flags = g_SavedExceptionInfo.m_ExceptionRecord.ExceptionFlags; - ULONG code = g_SavedExceptionInfo.m_ExceptionRecord.ExceptionCode; - ULONG_PTR* args = &g_SavedExceptionInfo.m_ExceptionRecord.ExceptionInformation[0]; - - RaiseException(code, flags, argcount, args); -} - -void SetNakedThrowHelperArgRegistersInContext(CONTEXT* pContext) -{ -#if defined(TARGET_AMD64) - pContext->Rcx = (UINT_PTR)GetIP(pContext); -#elif defined(TARGET_ARM) || defined(TARGET_ARM64) - // Save the original IP in LR - pContext->Lr = (DWORD)GetIP(pContext); -#else - PORTABILITY_WARNING("NakedThrowHelper argument not defined"); -#endif -} - -EXTERN_C VOID STDCALL NakedThrowHelper(VOID); - void HandleManagedFault(EXCEPTION_RECORD* pExceptionRecord, CONTEXT* pContext, EXCEPTION_REGISTRATION_RECORD* pEstablisherFrame, @@ -6650,37 +6590,16 @@ void HandleManagedFault(EXCEPTION_RECORD* pExceptionRecord, WRAPPER_NO_CONTRACT; // Ok. Now we have a brand new fault in jitted code. - if (!Thread::UseContextBasedThreadRedirection()) - { - // Once this code path gets enough bake time, perhaps this path could always be used instead of the alternative path to - // redirect the thread - FrameWithCookie frameWithCookie; - FaultingExceptionFrame *frame = &frameWithCookie; - #if defined(FEATURE_EH_FUNCLETS) - *frame->GetGSCookiePtr() = GetProcessGSCookie(); - #endif // FEATURE_EH_FUNCLETS - frame->InitAndLink(pContext); - - SEHException exception(pExceptionRecord); - OBJECTREF managedException = CLRException::GetThrowableFromException(&exception); - RaiseTheExceptionInternalOnly(managedException, FALSE); - } - else - { - g_SavedExceptionInfo.Enter(); - g_SavedExceptionInfo.SaveExceptionRecord(pExceptionRecord); - g_SavedExceptionInfo.SaveContext(pContext); - - SetNakedThrowHelperArgRegistersInContext(pContext); - - SetIP(pContext, GetEEFuncEntryPoint(NakedThrowHelper)); - } -} - -#else // USE_FEF && !TARGET_UNIX + FrameWithCookie frameWithCookie; + FaultingExceptionFrame *frame = &frameWithCookie; +#if defined(FEATURE_EH_FUNCLETS) + *frame->GetGSCookiePtr() = GetProcessGSCookie(); +#endif // FEATURE_EH_FUNCLETS + frame->InitAndLink(pContext); -void InitSavedExceptionInfo() -{ + SEHException exception(pExceptionRecord); + OBJECTREF managedException = CLRException::GetThrowableFromException(&exception); + RaiseTheExceptionInternalOnly(managedException, FALSE); } #endif // USE_FEF && !TARGET_UNIX @@ -7008,12 +6927,6 @@ LONG WINAPI CLRVectoredExceptionHandlerPhase2(PEXCEPTION_POINTERS pExceptionInfo if (action == VEH_EXECUTE_HANDLE_MANAGED_EXCEPTION) { - // - // If the exception context was unwound by Phase3 then - // we'll jump here to save the managed context and resume execution at - // NakedThrowHelper. This needs to be done outside of any holder's - // scope, because HandleManagedFault may not return. - // HandleManagedFault(pExceptionInfo->ExceptionRecord, pExceptionInfo->ContextRecord, NULL, // establisher frame (x86 only) diff --git a/src/coreclr/vm/excep.h b/src/coreclr/vm/excep.h index dd773bb2434830..9cb33ad6c4a2d8 100644 --- a/src/coreclr/vm/excep.h +++ b/src/coreclr/vm/excep.h @@ -741,8 +741,6 @@ void CPFH_AdjustContextForThreadSuspensionRace(T_CONTEXT *pContext, Thread *pThr DWORD GetGcMarkerExceptionCode(LPVOID ip); bool IsGcMarker(T_CONTEXT *pContext, EXCEPTION_RECORD *pExceptionRecord); -void InitSavedExceptionInfo(); - bool ShouldHandleManagedFault( EXCEPTION_RECORD* pExceptionRecord, T_CONTEXT* pContext, diff --git a/src/coreclr/vm/exceptionhandling.cpp b/src/coreclr/vm/exceptionhandling.cpp index beb8015f598ef4..e70a340b7f99b9 100644 --- a/src/coreclr/vm/exceptionhandling.cpp +++ b/src/coreclr/vm/exceptionhandling.cpp @@ -223,8 +223,6 @@ void InitializeExceptionHandling() { EH_LOG((LL_INFO100, "InitializeExceptionHandling(): ExceptionTracker size: 0x%x bytes\n", sizeof(ExceptionTracker))); - InitSavedExceptionInfo(); - CLRAddVectoredHandlers(); g_theTrackerAllocator.Init(); @@ -5739,39 +5737,6 @@ NOT_BIT64_ARG(IN ULONG MemoryStackFp), } -EXTERN_C VOID FixContextForFaultingExceptionFrame ( - EXCEPTION_RECORD* pExceptionRecord, - CONTEXT *pContextRecord); - -EXTERN_C EXCEPTION_DISPOSITION -FixContextHandler(IN PEXCEPTION_RECORD pExceptionRecord - BIT64_ARG(IN ULONG64 MemoryStackFp) - NOT_BIT64_ARG(IN ULONG MemoryStackFp), - IN OUT PCONTEXT pContextRecord, - IN OUT PDISPATCHER_CONTEXT pDispatcherContext - ) -{ - CONTEXT* pNewContext = NULL; - - if (FirstCallToHandler(pDispatcherContext, &pNewContext)) - { - // - // We've pushed a Frame, but it is not initialized yet, so we - // must not be in preemptive mode - // - CONSISTENCY_CHECK(GetThread()->PreemptiveGCDisabled()); - - FixContextForFaultingExceptionFrame(pExceptionRecord, pNewContext); - } - - FixupDispatcherContext(pDispatcherContext, pNewContext, pContextRecord); - - // Returning ExceptionCollidedUnwind will cause the OS to take our new context record - // and dispatcher context and restart the exception dispatching on this call frame, - // which is exactly the behavior we want in order to restore our thread's unwindability - // (which was broken when we whacked the IP to get control over the thread) - return ExceptionCollidedUnwind; -} #endif // !TARGET_UNIX #ifdef _DEBUG diff --git a/src/coreclr/vm/i386/excepx86.cpp b/src/coreclr/vm/i386/excepx86.cpp index 08282199af41e9..fa928f22c4999f 100644 --- a/src/coreclr/vm/i386/excepx86.cpp +++ b/src/coreclr/vm/i386/excepx86.cpp @@ -1235,8 +1235,6 @@ void InitializeExceptionHandling() { WRAPPER_NO_CONTRACT; - InitSavedExceptionInfo(); - CLRAddVectoredHandlers(); // Initialize the lock used for synchronizing access to the stacktrace in the exception object diff --git a/src/coreclr/vm/loongarch64/excepcpu.h b/src/coreclr/vm/loongarch64/excepcpu.h index 14a8fd19dd8b3f..4146f7c6bd9417 100644 --- a/src/coreclr/vm/loongarch64/excepcpu.h +++ b/src/coreclr/vm/loongarch64/excepcpu.h @@ -29,7 +29,7 @@ PTR_CONTEXT GetCONTEXTFromRedirectedStubStackFrame(T_CONTEXT * pContext); // // Retrieves the FaultingExceptionFrame* from the stack frame of -// RedirectForThrowControl or NakedThrowHelper. +// RedirectForThrowControl. // FaultingExceptionFrame *GetFrameFromRedirectedStubStackFrame (T_DISPATCHER_CONTEXT *pDispatcherContext); From 6a2727f68eb326f5704ba17c922153682faf0f3d Mon Sep 17 00:00:00 2001 From: Aaron Robinson Date: Wed, 15 Jun 2022 11:16:22 -0700 Subject: [PATCH 137/337] Predicate for valid Tracker Reference is inverted (#70709) * Predicate for valid Tracker Reference is inverted * Fix test to not inline wrapper creation function. --- src/coreclr/vm/interoplibinterface_comwrappers.cpp | 7 +++---- src/tests/Interop/COM/ComWrappers/API/Program.cs | 4 ++++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/coreclr/vm/interoplibinterface_comwrappers.cpp b/src/coreclr/vm/interoplibinterface_comwrappers.cpp index 14046a7f16d0f1..2dd8d7364a63e8 100644 --- a/src/coreclr/vm/interoplibinterface_comwrappers.cpp +++ b/src/coreclr/vm/interoplibinterface_comwrappers.cpp @@ -1166,12 +1166,11 @@ namespace InteropLibImports } CONTRACTL_END; - bool isValid = false; ::OBJECTHANDLE objectHandle = static_cast<::OBJECTHANDLE>(handle); - isValid = ObjectHandleIsNull(objectHandle) != FALSE; - - return isValid; + // A valid target is one that is not null. + bool isNotNull = ObjectHandleIsNull(objectHandle) == FALSE; + return isNotNull; } bool GetGlobalPeggingState() noexcept diff --git a/src/tests/Interop/COM/ComWrappers/API/Program.cs b/src/tests/Interop/COM/ComWrappers/API/Program.cs index b5f6b4d09cfdce..377df76e2c5625 100644 --- a/src/tests/Interop/COM/ComWrappers/API/Program.cs +++ b/src/tests/Interop/COM/ComWrappers/API/Program.cs @@ -539,6 +539,10 @@ static void ValidateQueryInterfaceAfterManagedObjectCollected() refCount = MockReferenceTrackerRuntime.TrackerTarget_ReleaseFromReferenceTracker(refTrackerTarget); Assert.Equal(0, refCount); + // Inlining this method could unintentionally extend the lifetime of + // the Test instance. This lifetime extension makes clean-up of the CCW + // impossible when desired because the GC sees the object as reachable. + [MethodImpl(MethodImplOptions.NoInlining)] static IntPtr CreateWrapper(TestComWrappers cw) { return cw.GetOrCreateComInterfaceForObject(new Test(), CreateComInterfaceFlags.TrackerSupport); From 5810b0241a27838c1c4fd48bd32b8774ecdbdea6 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Wed, 15 Jun 2022 21:24:26 +0200 Subject: [PATCH 138/337] JIT: Enable addressing modes for gc types (#70749) --- src/coreclr/jit/codegenarmarch.cpp | 10 ++++++++++ src/coreclr/jit/lower.cpp | 2 +- src/coreclr/jit/morph.cpp | 4 ++-- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index c01127ed79d514..c3955cbcfd90c1 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -4430,6 +4430,16 @@ void CodeGen::genLeaInstruction(GenTreeAddrMode* lea) } else { +#ifdef TARGET_ARM64 + // Handle LEA with "contained" BFIZ + if (index->isContained() && index->OperIs(GT_BFIZ)) + { + assert(scale == 0); + scale = (DWORD)index->gtGetOp2()->AsIntConCommon()->IconValue(); + index = index->gtGetOp1()->gtGetOp1(); + } +#endif + // Then compute target reg from [base + index*scale] genScaledAdd(size, lea->GetRegNum(), memBase->GetRegNum(), index->GetRegNum(), scale); } diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index fb8e0104d34d7c..f5ddb4069ccc2c 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -5364,7 +5364,7 @@ bool Lowering::TryCreateAddrMode(GenTree* addr, bool isContainable, GenTree* par // Check if we can "contain" LEA(BFIZ) in order to extend 32bit index to 64bit as part of load/store. if ((index != nullptr) && index->OperIs(GT_BFIZ) && index->gtGetOp1()->OperIs(GT_CAST) && - index->gtGetOp2()->IsCnsIntOrI() && (varTypeIsIntegral(targetType) || varTypeIsFloating(targetType))) + index->gtGetOp2()->IsCnsIntOrI() && !varTypeIsStruct(targetType)) { // BFIZ node is a binary op where op1 is GT_CAST and op2 is GT_CNS_INT GenTreeCast* cast = index->gtGetOp1()->AsCast(); diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 5c8162af104c6a..ac07cb20ddc18e 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -4728,8 +4728,8 @@ GenTree* Compiler::fgMorphIndexAddr(GenTreeIndexAddr* indexAddr) // we at least will be able to hoist/CSE "index + elemOffset" in some cases. // See https://github.com/dotnet/runtime/pull/61293#issuecomment-964146497 - // Use 2) form only for primitive types for now - it significantly reduced number of size regressions - if (!varTypeIsIntegral(elemTyp) && !varTypeIsFloating(elemTyp)) + // Don't use 2) for structs to reduce number of size regressions + if (varTypeIsStruct(elemTyp)) { groupArrayRefWithElemOffset = false; } From 7198edbb3400c0e4d66025caf58cb50e8007e206 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Wed, 15 Jun 2022 21:53:41 +0200 Subject: [PATCH 139/337] JIT: Faster long->int overflow checks (#69865) --- src/coreclr/jit/codegenarmarch.cpp | 11 +++-------- src/coreclr/jit/codegenxarch.cpp | 13 ++++++++----- src/coreclr/jit/emitarm64.cpp | 6 ++++-- src/coreclr/jit/lsraarmarch.cpp | 7 ------- src/coreclr/jit/lsraxarch.cpp | 4 ++-- 5 files changed, 17 insertions(+), 24 deletions(-) diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index c3955cbcfd90c1..0f87d506b2091d 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -3874,14 +3874,9 @@ void CodeGen::genIntCastOverflowCheck(GenTreeCast* cast, const GenIntCastDesc& d case GenIntCastDesc::CHECK_INT_RANGE: { - const regNumber tempReg = cast->GetSingleTempReg(); - assert(tempReg != reg); - instGen_Set_Reg_To_Imm(EA_8BYTE, tempReg, INT32_MAX); - GetEmitter()->emitIns_R_R(INS_cmp, EA_8BYTE, reg, tempReg); - genJumpToThrowHlpBlk(EJ_gt, SCK_OVERFLOW); - instGen_Set_Reg_To_Imm(EA_8BYTE, tempReg, INT32_MIN); - GetEmitter()->emitIns_R_R(INS_cmp, EA_8BYTE, reg, tempReg); - genJumpToThrowHlpBlk(EJ_lt, SCK_OVERFLOW); + // Emit "if ((long)(int)x != x) goto OVERFLOW" + GetEmitter()->emitIns_R_R(INS_cmp, EA_8BYTE, reg, reg, INS_OPTS_SXTW); + genJumpToThrowHlpBlk(EJ_ne, SCK_OVERFLOW); } break; #endif diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index 8e00b37a1d52d9..ca050dcf49ff90 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -6730,11 +6730,14 @@ void CodeGen::genIntCastOverflowCheck(GenTreeCast* cast, const GenIntCastDesc& d break; case GenIntCastDesc::CHECK_INT_RANGE: - GetEmitter()->emitIns_R_I(INS_cmp, EA_8BYTE, reg, INT32_MAX); - genJumpToThrowHlpBlk(EJ_jg, SCK_OVERFLOW); - GetEmitter()->emitIns_R_I(INS_cmp, EA_8BYTE, reg, INT32_MIN); - genJumpToThrowHlpBlk(EJ_jl, SCK_OVERFLOW); - break; + { + // Emit "if ((long)(int)x != x) goto OVERFLOW" + const regNumber regTmp = cast->GetSingleTempReg(); + GetEmitter()->emitIns_Mov(INS_movsxd, EA_8BYTE, regTmp, reg, true); + GetEmitter()->emitIns_R_R(INS_cmp, EA_8BYTE, reg, regTmp); + genJumpToThrowHlpBlk(EJ_jne, SCK_OVERFLOW); + } + break; #endif default: diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 3940f89302911a..af71e23749400d 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -4508,14 +4508,16 @@ void emitter::emitIns_R_R( case INS_str: case INS_strb: case INS_strh: - - case INS_cmp: case INS_cmn: case INS_tst: assert(insOptsNone(opt)); emitIns_R_R_I(ins, attr, reg1, reg2, 0, INS_OPTS_NONE); return; + case INS_cmp: + emitIns_R_R_I(ins, attr, reg1, reg2, 0, opt); + return; + case INS_staddb: emitIns_R_R_R(INS_ldaddb, attr, reg1, REG_ZR, reg2); return; diff --git a/src/coreclr/jit/lsraarmarch.cpp b/src/coreclr/jit/lsraarmarch.cpp index 1ae93e96435486..3d1cf8540a1423 100644 --- a/src/coreclr/jit/lsraarmarch.cpp +++ b/src/coreclr/jit/lsraarmarch.cpp @@ -808,13 +808,6 @@ int LinearScan::BuildCast(GenTreeCast* cast) buildInternalFloatRegisterDefForNode(cast, RBM_ALLFLOAT); setInternalRegsDelayFree = true; } -#else - // Overflow checking cast from TYP_LONG to TYP_INT requires a temporary register to - // store the min and max immediate values that cannot be encoded in the CMP instruction. - if (cast->gtOverflow() && varTypeIsLong(srcType) && !cast->IsUnsigned() && (castType == TYP_INT)) - { - buildInternalIntRegisterDefForNode(cast); - } #endif int srcCount = BuildOperandUses(src); diff --git a/src/coreclr/jit/lsraxarch.cpp b/src/coreclr/jit/lsraxarch.cpp index 5be7b32972da62..6ed5665febdc51 100644 --- a/src/coreclr/jit/lsraxarch.cpp +++ b/src/coreclr/jit/lsraxarch.cpp @@ -2491,9 +2491,9 @@ int LinearScan::BuildCast(GenTreeCast* cast) assert(!varTypeIsLong(srcType) || (src->OperIs(GT_LONG) && src->isContained())); #else - // Overflow checking cast from TYP_(U)LONG to TYP_UINT requires a temporary + // Overflow checking cast from TYP_(U)LONG to TYP_(U)INT requires a temporary // register to extract the upper 32 bits of the 64 bit source register. - if (cast->gtOverflow() && varTypeIsLong(srcType) && (castType == TYP_UINT)) + if (cast->gtOverflow() && varTypeIsLong(srcType) && varTypeIsInt(castType)) { // Here we don't need internal register to be different from targetReg, // rather require it to be different from operand's reg. From 06c7957e9c49403a880880aa3602e658979a9b37 Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Wed, 15 Jun 2022 13:42:35 -0700 Subject: [PATCH 140/337] Update .net version for asp.net spmi collection script (#70778) --- src/coreclr/scripts/superpmi_aspnet.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/scripts/superpmi_aspnet.py b/src/coreclr/scripts/superpmi_aspnet.py index e2aeecf2a478d8..03f8757a702c9f 100644 --- a/src/coreclr/scripts/superpmi_aspnet.py +++ b/src/coreclr/scripts/superpmi_aspnet.py @@ -132,8 +132,8 @@ def build_and_run(coreclr_args): print ("Executing in " + temp_location) - # install dotnet 5.0 - run_command([dotnet_install_script_path, "-Version", "5.0.3"], temp_location, _exit_on_fail=True) + # install dotnet 6.0 + run_command([dotnet_install_script_path, "-Version", "6.0.4"], temp_location, _exit_on_fail=True) os.environ['DOTNET_MULTILEVEL_LOOKUP'] = '0' os.environ['DOTNET_SKIP_FIRST_TIME_EXPERIENCE'] = '1' dotnet_path = path.join(source_directory, ".dotnet") From 10288c966bfdd46cdc0d612beaa05888819171a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Thu, 16 Jun 2022 05:46:25 +0900 Subject: [PATCH 141/337] Enable IlcTrimMetadata by default (#70201) Enables more aggressive metadata stripping by default. In this mode, the AOT compiler only generates reflection metadata for artifacts that were deemed reflection-visible by either dataflow analysis, or user inputs. Previously we would consider everything that got generated reflection-visible. * Change the defaults within the compiler (making the conservative mode opt-in). * Add tests for scenarios in https://github.com/dotnet/runtimelab/issues/656 (resolves dotnet/runtimelab#656). * Update tests * Do more marking where it was necessary --- .../Microsoft.NETCore.Native.targets | 4 +- src/coreclr/nativeaot/docs/optimizing.md | 19 ++-- .../Dataflow/ReflectionMethodBodyScanner.cs | 6 ++ .../DependencyAnalysis/CanonicalEETypeNode.cs | 5 + .../ConstructedEETypeNode.cs | 5 + .../Compiler/DependencyAnalysis/EETypeNode.cs | 19 +++- .../Compiler/UsageBasedMetadataManager.cs | 50 ++++++++-- src/coreclr/tools/aot/ILCompiler/Program.cs | 19 ++-- .../System.Collections/tests/default.rd.xml | 6 ++ .../tests/default.rd.xml | 18 ++++ .../System.Reflection/tests/default.rd.xml | 4 + .../System.Runtime/tests/default.rd.xml | 1 + .../nativeaot/SmokeTests/Dataflow/Dataflow.cs | 5 +- .../DeadCodeElimination.cs | 63 ++++++++++++ .../SmokeTests/DynamicGenerics/rd.xml | 21 ++++ .../Preinitialization.csproj | 6 ++ .../SmokeTests/Reflection/Reflection.cs | 95 +++++++++++++++++++ .../SmokeTests/Reflection/Reflection.csproj | 1 - ...nly.csproj => Reflection_FromUsage.csproj} | 7 +- 19 files changed, 318 insertions(+), 36 deletions(-) rename src/tests/nativeaot/SmokeTests/Reflection/{Reflection_ReflectedOnly.csproj => Reflection_FromUsage.csproj} (84%) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets index cd57a1ba8b358a..9f079b4323fb8c 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets @@ -232,14 +232,14 @@ The .NET Foundation licenses this file to you under the MIT license. - + - + diff --git a/src/coreclr/nativeaot/docs/optimizing.md b/src/coreclr/nativeaot/docs/optimizing.md index aeee66fa2f41dc..cc31c98df1539d 100644 --- a/src/coreclr/nativeaot/docs/optimizing.md +++ b/src/coreclr/nativeaot/docs/optimizing.md @@ -12,12 +12,6 @@ To specify a switch, add a new property to your project file with one or more of under the `` node of your project file. -## Options related to library features - -Native AOT supports enabling and disabling all [documented framework library features](https://docs.microsoft.com/en-us/dotnet/core/deploying/trimming-options#trimming-framework-library-features). For example, to remove globalization specific code and data, add a `true` property to your project. Disabling a framework feature (or enabling a minimal mode of the feature) can result in significant size savings. - -🛈 Native AOT difference: The `EnableUnsafeBinaryFormatterSerialization` framework switch is already set to the optimal value of `false` (removing the support for [obsolete](https://github.com/dotnet/designs/blob/21b274dbc21e4ae54b7e4c5dbd5ef31e439e78db/accepted/2020/better-obsoletion/binaryformatter-obsoletion.md) binary serialization). - ## Options related to trimming The Native AOT compiler supports the [documented options](https://docs.microsoft.com/en-us/dotnet/core/deploying/trim-self-contained) for removing unused code (trimming). By default, the compiler tries to very conservatively remove some of the unused code. @@ -26,16 +20,21 @@ The Native AOT compiler supports the [documented options](https://docs.microsoft By default, the compiler tries to maximize compatibility with existing .NET code at the expense of compilation speed and size of the output executable. This allows people to use their existing code that worked well in a fully dynamic mode without hitting issues caused by trimming. To read more about reflection, see the [Reflection in AOT mode](reflection-in-aot-mode.md) document. -🛈 Native AOT difference: the `TrimMode` of framework assemblies is set to `link` by default. To compile entire framework assemblies, use `TrimmerRootAssembly` to root the selected assemblies. It's not recommended to root the entire framework. - -To enable more aggressive removal of unreferenced code, set the `` property to `link`. +To enable more aggressive removal of unreferenced code, set the `` property to `link`. To aid in troubleshooting some of the most common problems related to trimming add `true` to your project. This ensures types are preserved in their entirety, but the extra members that would otherwise be trimmed cannot be used in runtime reflection. This mode can turn some spurious `NullReferenceExceptions` (caused by reflection APIs returning a null) caused by trimming into more actionable exceptions. +The Native AOT compiler can remove unused metadata more effectively than non-Native deployment models. For example, it's possible to remove names and metadata for methods while keeping the native code of the method. The higher efficiency of trimming in Native AOT can result in differences in what's visible to reflection at runtime in trimming-unfriendly code. To increase compatibility with the less efficient non-Native trimming, set the `` property to `false`. This compatibility mode is not necessary if there are no trimming warnings. + +## Options related to library features + +Native AOT supports enabling and disabling all [documented framework library features](https://docs.microsoft.com/en-us/dotnet/core/deploying/trimming-options#trimming-framework-library-features). For example, to remove globalization specific code and data, add a `true` property to your project. Disabling a framework feature (or enabling a minimal mode of the feature) can result in significant size savings. + +Since `PublishTrimmed` is implied to be true with Native AOT, some framework features such as binary serialization are disabled by default. + ## Options related to metadata generation * `false`: this disables generation of stack trace metadata that provides textual names in stack traces. This is for example the text string one gets by calling `Exception.ToString()` on a caught exception. With this option disabled, stack traces will still be generated, but will be based on reflection metadata alone (they might be less complete). -* `true`: allows the compiler to remove reflection metadata from things that were not visible targets of reflection. By default, the compiler keeps metadata for everything that was compiled. With this option turned on, reflection metadata (and therefore reflection) will only be available for visible targets of reflection. Visible targets of reflection are things like assemblies rooted from the project file, RD.XML, ILLinkTrim descriptors, DynamicallyAccessedMembers annotations or DynamicDependency annotations. ## Options related to code generation * `Speed`: when generating optimized code, favor code execution speed. diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs index f584f7c5b20233..4343e5352da3bc 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs @@ -597,6 +597,12 @@ public override bool HandleCall(MethodIL callingMethodBody, MethodDesc calledMet if (systemTypeValue.RepresentedType.Type.IsDefType) { _reflectionMarker.Dependencies.Add(_factory.StructMarshallingData((DefType)systemTypeValue.RepresentedType.Type), "Marshal API"); + if (intrinsicId == IntrinsicId.Marshal_PtrToStructure + && systemTypeValue.RepresentedType.Type.GetParameterlessConstructor() is MethodDesc ctorMethod + && !_factory.MetadataManager.IsReflectionBlocked(ctorMethod)) + { + _reflectionMarker.Dependencies.Add(_factory.ReflectableMethod(ctorMethod), "Marshal API"); + } } } else diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs index 845fe201486d34..e2df7d38798e3c 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/CanonicalEETypeNode.cs @@ -77,6 +77,11 @@ protected override ISymbolNode GetBaseTypeNode(NodeFactory factory) return _type.BaseType != null ? factory.NecessaryTypeSymbol(_type.BaseType.NormalizeInstantiation()) : null; } + protected override ISymbolNode GetNonNullableValueTypeArrayElementTypeNode(NodeFactory factory) + { + return factory.ConstructedTypeSymbol(((ArrayType)_type).ElementType); + } + protected override int GCDescSize { get diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs index 4c5d630437a3b2..be5ce0d0dc80b5 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ConstructedEETypeNode.cs @@ -101,6 +101,11 @@ protected override ISymbolNode GetBaseTypeNode(NodeFactory factory) return _type.BaseType != null ? factory.ConstructedTypeSymbol(_type.BaseType) : null; } + protected override ISymbolNode GetNonNullableValueTypeArrayElementTypeNode(NodeFactory factory) + { + return factory.ConstructedTypeSymbol(((ArrayType)_type).ElementType); + } + protected override IEETypeNode GetInterfaceTypeNode(NodeFactory factory, TypeDesc interfaceType) { // The interface type will be visible to reflection and should be considered constructed. diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs index 0ec69a4f29f76a..54b6424032c5b2 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/EETypeNode.cs @@ -757,14 +757,29 @@ protected virtual ISymbolNode GetBaseTypeNode(NodeFactory factory) return _type.BaseType != null ? factory.NecessaryTypeSymbol(_type.BaseType) : null; } + protected virtual ISymbolNode GetNonNullableValueTypeArrayElementTypeNode(NodeFactory factory) + { + return factory.NecessaryTypeSymbol(((ArrayType)_type).ElementType); + } + private ISymbolNode GetRelatedTypeNode(NodeFactory factory) { ISymbolNode relatedTypeNode = null; - if (_type.IsArray || _type.IsPointer || _type.IsByRef) + if (_type.IsParameterizedType) { var parameterType = ((ParameterizedType)_type).ParameterType; - relatedTypeNode = factory.NecessaryTypeSymbol(parameterType); + if (_type.IsArray && parameterType.IsValueType && !parameterType.IsNullable) + { + // This might be a constructed type symbol. There are APIs on Array that allow allocating element + // types through runtime magic ("((Array)new NeverAllocated[1]).GetValue(0)" or IEnumerable) and we don't have + // visibility into that. Conservatively assume element types of constructed arrays are also constructed. + relatedTypeNode = GetNonNullableValueTypeArrayElementTypeNode(factory); + } + else + { + relatedTypeNode = factory.NecessaryTypeSymbol(parameterType); + } } else { diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs index c4fedd71ae1f35..d11c8c8b928861 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs @@ -187,7 +187,7 @@ protected override MetadataCategory GetMetadataCategory(TypeDesc type) return category; } - protected override bool AllMethodsCanBeReflectable => (_generationOptions & UsageBasedMetadataGenerationOptions.ReflectedMembersOnly) == 0; + protected override bool AllMethodsCanBeReflectable => (_generationOptions & UsageBasedMetadataGenerationOptions.CreateReflectableArtifacts) != 0; protected override void ComputeMetadata(NodeFactory factory, out byte[] metadataBlob, @@ -527,7 +527,7 @@ protected override void GetDependenciesDueToMethodCodePresenceInternal(ref Depen } // Presence of code might trigger the reflectability dependencies. - if ((_generationOptions & UsageBasedMetadataGenerationOptions.ReflectedMembersOnly) == 0) + if ((_generationOptions & UsageBasedMetadataGenerationOptions.CreateReflectableArtifacts) != 0) { GetDependenciesDueToReflectability(ref dependencies, factory, method); } @@ -538,7 +538,7 @@ public override void GetConditionalDependenciesDueToMethodCodePresence(ref Combi MethodDesc typicalMethod = method.GetTypicalMethodDefinition(); // Ensure methods with genericness have the same reflectability by injecting a conditional dependency. - if ((_generationOptions & UsageBasedMetadataGenerationOptions.ReflectedMembersOnly) != 0 + if ((_generationOptions & UsageBasedMetadataGenerationOptions.CreateReflectableArtifacts) == 0 && method != typicalMethod) { dependencies ??= new CombinedDependencyList(); @@ -549,7 +549,7 @@ public override void GetConditionalDependenciesDueToMethodCodePresence(ref Combi public override void GetDependenciesDueToVirtualMethodReflectability(ref DependencyList dependencies, NodeFactory factory, MethodDesc method) { - if ((_generationOptions & UsageBasedMetadataGenerationOptions.ReflectedMembersOnly) == 0) + if ((_generationOptions & UsageBasedMetadataGenerationOptions.CreateReflectableArtifacts) != 0) { // If we have a use of an abstract method, GetDependenciesDueToReflectability is not going to see the method // as being used since there's no body. We inject a dependency on a new node that serves as a logical method body @@ -600,8 +600,40 @@ public override void GetDependenciesDueToAccess(ref DependencyList dependencies, dependencies.Add(factory.DataflowAnalyzedMethod(methodIL.GetMethodILDefinition()), "Access to interesting field"); } - if ((_generationOptions & UsageBasedMetadataGenerationOptions.ReflectedMembersOnly) == 0 - && !IsReflectionBlocked(writtenField)) + string reason = "Use of a field"; + + bool generatesMetadata = false; + if (!IsReflectionBlocked(writtenField)) + { + if ((_generationOptions & UsageBasedMetadataGenerationOptions.CreateReflectableArtifacts) != 0) + { + // If access to the field should trigger metadata generation, we should generate the field + generatesMetadata = true; + } + else + { + // There's an invalid suppression in the CoreLib that assumes used fields on attributes will be kept. + // It's used in the reflection-based implementation of Attribute.Equals and Attribute.GetHashCode. + // .NET Native used to have a non-reflection based implementation of Equals/GetHashCode to get around + // this problem. We could explore that as well, but for now, emulate the fact that accessed fields + // on custom attributes will be visible in reflection metadata. + MetadataType currentType = (MetadataType)writtenField.OwningType.BaseType; + while (currentType != null) + { + if (currentType.Module == factory.TypeSystemContext.SystemModule + && currentType.Name == "Attribute" && currentType.Namespace == "System") + { + generatesMetadata = true; + reason = "Field of an attribute"; + break; + } + + currentType = currentType.MetadataBaseType; + } + } + } + + if (generatesMetadata) { FieldDesc fieldToReport = writtenField; @@ -619,7 +651,7 @@ public override void GetDependenciesDueToAccess(ref DependencyList dependencies, } dependencies = dependencies ?? new DependencyList(); - dependencies.Add(factory.ReflectableField(fieldToReport), "Use of a field"); + dependencies.Add(factory.ReflectableField(fieldToReport), reason); } } @@ -1039,9 +1071,9 @@ public enum UsageBasedMetadataGenerationOptions ReflectionILScanning = 4, /// - /// Only members that were seen as reflected on will be reflectable. + /// Consider all native artifacts (native method bodies, etc) visible from reflection. /// - ReflectedMembersOnly = 8, + CreateReflectableArtifacts = 8, /// /// Fully root used assemblies that are not marked IsTrimmable in metadata. diff --git a/src/coreclr/tools/aot/ILCompiler/Program.cs b/src/coreclr/tools/aot/ILCompiler/Program.cs index 925fd5c9a90d81..eb3643851fd50a 100644 --- a/src/coreclr/tools/aot/ILCompiler/Program.cs +++ b/src/coreclr/tools/aot/ILCompiler/Program.cs @@ -53,9 +53,8 @@ internal class Program private string _mapFileName; private string _metadataLogFileName; private bool _noMetadataBlocking; - private bool _disableReflection; + private string _reflectionData; private bool _completeTypesMetadata; - private bool _reflectedOnly; private bool _scanReflection; private bool _methodBodyFolding; private int _parallelism = Environment.ProcessorCount; @@ -159,6 +158,8 @@ private void InitializeDefaultOptions() private ArgumentSyntax ParseCommandLine(string[] args) { + var validReflectionDataOptions = new string[] { "all", "none" }; + IReadOnlyList inputFiles = Array.Empty(); IReadOnlyList referenceFiles = Array.Empty(); @@ -201,9 +202,8 @@ private ArgumentSyntax ParseCommandLine(string[] args) syntax.DefineOption("map", ref _mapFileName, "Generate a map file"); syntax.DefineOption("metadatalog", ref _metadataLogFileName, "Generate a metadata log file"); syntax.DefineOption("nometadatablocking", ref _noMetadataBlocking, "Ignore metadata blocking for internal implementation details"); - syntax.DefineOption("disablereflection", ref _disableReflection, "Disable generation of reflection metadata"); syntax.DefineOption("completetypemetadata", ref _completeTypesMetadata, "Generate complete metadata for types"); - syntax.DefineOption("reflectedonly", ref _reflectedOnly, "Generate metadata only for reflected members"); + syntax.DefineOption("reflectiondata", ref _reflectionData, $"Reflection data to generate (one of: {string.Join(", ", validReflectionDataOptions)})"); syntax.DefineOption("scanreflection", ref _scanReflection, "Scan IL for reflection patterns"); syntax.DefineOption("scan", ref _useScanner, "Use IL scanner to generate optimized code (implied by -O)"); syntax.DefineOption("noscan", ref _noScanner, "Do not use IL scanner to generate optimized code"); @@ -342,6 +342,11 @@ private ArgumentSyntax ParseCommandLine(string[] args) Helpers.MakeReproPackage(_makeReproPath, _outputFilePath, args, argSyntax, new[] { "-r", "-m", "--rdxml", "--directpinvokelist" }); } + if (_reflectionData != null && Array.IndexOf(validReflectionDataOptions, _reflectionData) < 0) + { + Console.WriteLine($"Warning: option '{_reflectionData}' not recognized"); + } + return argSyntax; } @@ -527,7 +532,7 @@ private int Run(string[] args) InstructionSetSupportBuilder.GetNonSpecifiableInstructionSetsForArch(_targetArchitecture), _targetArchitecture); - bool supportsReflection = !_disableReflection && _systemModuleName == DefaultSystemModule; + bool supportsReflection = _reflectionData != "none" && _systemModuleName == DefaultSystemModule; // // Initialize type system context @@ -758,8 +763,8 @@ static string ILLinkify(string rootedAssembly) metadataGenerationOptions |= UsageBasedMetadataGenerationOptions.CompleteTypesOnly; if (_scanReflection) metadataGenerationOptions |= UsageBasedMetadataGenerationOptions.ReflectionILScanning; - if (_reflectedOnly) - metadataGenerationOptions |= UsageBasedMetadataGenerationOptions.ReflectedMembersOnly; + if (_reflectionData == "all") + metadataGenerationOptions |= UsageBasedMetadataGenerationOptions.CreateReflectableArtifacts; if (_rootDefaultAssemblies) metadataGenerationOptions |= UsageBasedMetadataGenerationOptions.RootDefaultAssemblies; } diff --git a/src/libraries/System.Collections/tests/default.rd.xml b/src/libraries/System.Collections/tests/default.rd.xml index eaeb64ebc3137b..cff6d074fe9ae6 100644 --- a/src/libraries/System.Collections/tests/default.rd.xml +++ b/src/libraries/System.Collections/tests/default.rd.xml @@ -150,5 +150,11 @@ + + + + + + diff --git a/src/libraries/System.Linq.Expressions/tests/default.rd.xml b/src/libraries/System.Linq.Expressions/tests/default.rd.xml index ab2f88341472cb..0babcd014cec3b 100644 --- a/src/libraries/System.Linq.Expressions/tests/default.rd.xml +++ b/src/libraries/System.Linq.Expressions/tests/default.rd.xml @@ -1,8 +1,18 @@ + + + + + + + + + + @@ -32,6 +42,13 @@ + + + + + + + @@ -45,6 +62,7 @@ + diff --git a/src/libraries/System.Reflection/tests/default.rd.xml b/src/libraries/System.Reflection/tests/default.rd.xml index de87619639313b..31a940f6e8540e 100644 --- a/src/libraries/System.Reflection/tests/default.rd.xml +++ b/src/libraries/System.Reflection/tests/default.rd.xml @@ -47,5 +47,9 @@ + + + + diff --git a/src/libraries/System.Runtime/tests/default.rd.xml b/src/libraries/System.Runtime/tests/default.rd.xml index b100128a1bd617..b78da0bb4022be 100644 --- a/src/libraries/System.Runtime/tests/default.rd.xml +++ b/src/libraries/System.Runtime/tests/default.rd.xml @@ -501,6 +501,7 @@ + diff --git a/src/tests/nativeaot/SmokeTests/Dataflow/Dataflow.cs b/src/tests/nativeaot/SmokeTests/Dataflow/Dataflow.cs index ea614207540041..0ebfcb06546f2b 100644 --- a/src/tests/nativeaot/SmokeTests/Dataflow/Dataflow.cs +++ b/src/tests/nativeaot/SmokeTests/Dataflow/Dataflow.cs @@ -389,7 +389,10 @@ public static void Run() Assert.Equal(1, typeof(TypeWithSpecificMethodKept).CountMethods()); Assert.Equal(1, typeof(TypeWithSpecificOverloadKept).CountMethods()); Assert.Equal(2, typeof(TypeWithAllOverloadsKept).CountMethods()); - Assert.Equal(2, typeof(TestDynamicDependency).CountMethods()); + + // We only expect DependentMethod. We specifically don't expect to see the Run method (current method). + Assert.Equal(1, typeof(TestDynamicDependency).CountMethods()); + Assert.Equal(1, typeof(TypeWithPublicPropertiesKept).CountProperties()); } } diff --git a/src/tests/nativeaot/SmokeTests/DeadCodeElimination/DeadCodeElimination.cs b/src/tests/nativeaot/SmokeTests/DeadCodeElimination/DeadCodeElimination.cs index f133eb28f5d2b2..b371e2469c24b6 100644 --- a/src/tests/nativeaot/SmokeTests/DeadCodeElimination/DeadCodeElimination.cs +++ b/src/tests/nativeaot/SmokeTests/DeadCodeElimination/DeadCodeElimination.cs @@ -17,6 +17,7 @@ static int Main() TestAbstractNeverDerivedWithDevirtualizedCall.Run(); TestAbstractDerivedByUnrelatedTypeWithDevirtualizedCall.Run(); TestUnusedDefaultInterfaceMethod.Run(); + TestArrayElementTypeOperations.Run(); return 100; } @@ -219,6 +220,60 @@ public static void Run() } } + class TestArrayElementTypeOperations + { + public static void Run() + { + Console.WriteLine("Testing array element type optimizations"); + + // We consider valuetype elements of arrays constructed... + { + Array arr = new NeverAllocated1[1]; + ThrowIfNotPresent(typeof(TestArrayElementTypeOperations), nameof(Marker1)); + + // The reason they're considered constructed is runtime magic here + // Make sure that works too. + object o = arr.GetValue(0); + if (!o.ToString().Contains(nameof(Marker1))) + throw new Exception(); + } + + // ...but not nullable... + { + Array arr = new Nullable[1]; + arr.GetValue(0); + ThrowIfPresent(typeof(TestArrayElementTypeOperations), nameof(Marker2)); + } + + + // ...or reference type element types + { + Array arr = new NeverAllocated3[1]; + arr.GetValue(0); + ThrowIfPresent(typeof(TestArrayElementTypeOperations), nameof(Marker3)); + } + } + + class Marker1 { } + struct NeverAllocated1 + { + public override string ToString() => typeof(Marker1).ToString(); + } + + class Marker2 { } + struct NeverAllocated2 + { + public override string ToString() => typeof(Marker2).ToString(); + } + + class Marker3 { } + class NeverAllocated3 + { + public override string ToString() => typeof(Marker3).ToString(); + } + } + + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2070:UnrecognizedReflectionPattern", Justification = "That's the point")] private static bool IsTypePresent(Type testType, string typeName) => testType.GetNestedType(typeName, BindingFlags.NonPublic | BindingFlags.Public) != null; @@ -230,4 +285,12 @@ private static void ThrowIfPresent(Type testType, string typeName) throw new Exception(typeName); } } + + private static void ThrowIfNotPresent(Type testType, string typeName) + { + if (!IsTypePresent(testType, typeName)) + { + throw new Exception(typeName); + } + } } diff --git a/src/tests/nativeaot/SmokeTests/DynamicGenerics/rd.xml b/src/tests/nativeaot/SmokeTests/DynamicGenerics/rd.xml index 5583cf52b7e914..92d116b2a139f2 100644 --- a/src/tests/nativeaot/SmokeTests/DynamicGenerics/rd.xml +++ b/src/tests/nativeaot/SmokeTests/DynamicGenerics/rd.xml @@ -113,6 +113,27 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/nativeaot/SmokeTests/Preinitialization/Preinitialization.csproj b/src/tests/nativeaot/SmokeTests/Preinitialization/Preinitialization.csproj index f0f876b0bb4ad5..8f2a5aa349d583 100644 --- a/src/tests/nativeaot/SmokeTests/Preinitialization/Preinitialization.csproj +++ b/src/tests/nativeaot/SmokeTests/Preinitialization/Preinitialization.csproj @@ -5,6 +5,12 @@ 0 true true + + + false diff --git a/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs b/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs index ab559549cdfc84..78d1a6c0560c62 100644 --- a/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs +++ b/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs @@ -55,6 +55,10 @@ private static int Main() TestNotReflectedIsNotReflectable.Run(); TestGenericInstantiationsAreEquallyReflectable.Run(); #endif + TestAttributeInheritance2.Run(); + TestInvokeMethodMetadata.Run(); + TestVTableOfNullableUnderlyingTypes.Run(); + TestInterfaceLists.Run(); // // Mostly functionality tests @@ -1875,6 +1879,97 @@ public static void Run() } } + class TestAttributeInheritance2 + { + [AttributeUsage(AttributeTargets.All, Inherited = true)] + class AttAttribute : Attribute { } + + class Base + { + [Att] + public virtual void VirtualMethodWithAttribute() { } + } + + class Derived : Base + { + public override void VirtualMethodWithAttribute() { } + } + + public static void Run() + { + object[] attrs = typeof(Derived).GetMethod(nameof(Derived.VirtualMethodWithAttribute)).GetCustomAttributes(inherit: true); + if (attrs.Length != 1 || attrs[0].GetType().Name != nameof(AttAttribute)) + { + throw new Exception(); + } + } + } + + class TestInvokeMethodMetadata + { + delegate int WithDefaultParameter1(int value = 1234); + delegate DateTime WithDefaultParameter2(DateTime value); + + public static int Method(int value) => value; + + public static DateTime Method(DateTime value) => value; + + public static void Run() + { + // Check that we have metadata for the Invoke method to convert Type.Missing to the actual value. + WithDefaultParameter1 del1 = Method; + int val = (int)del1.DynamicInvoke(new object[] { Type.Missing }); + if (val != 1234) + throw new Exception(); + + // Check that we have metadata for the Invoke method to find a matching method + Delegate del2 = Delegate.CreateDelegate(typeof(WithDefaultParameter2), typeof(TestInvokeMethodMetadata), nameof(Method)); + if (del2.Method.ReturnType != typeof(DateTime)) + throw new Exception(); + } + } + + class TestVTableOfNullableUnderlyingTypes + { + struct NeverAllocated + { + public override string ToString() => "Never allocated"; + } + + static Type s_hidden = typeof(Nullable); + + public static void Run() + { + // Underlying type of a Nullable needs to be considered constructed. + // Trimming warning suppressions in the libraries depend on this invariant. + var instance = RuntimeHelpers.GetUninitializedObject(s_hidden); + if (instance.ToString() != "Never allocated") + throw new Exception(); + } + } + + class TestInterfaceLists + { + interface IGeneric { } + + class Class : IGeneric { } + + static Type s_hidden = typeof(Class); + + public static void Run() + { + // Can't drop an interface from the interface list if the interface is referenced. + // Trimming warning suppressions in the libraries depend on this invariant. + foreach (var intface in s_hidden.GetInterfaces()) + { + if (intface.HasSameMetadataDefinitionAs(typeof(IGeneric))) + return; + } + + throw new Exception(); + } + } + #region Helpers private static Type SecretGetType(string testName, string typeName) diff --git a/src/tests/nativeaot/SmokeTests/Reflection/Reflection.csproj b/src/tests/nativeaot/SmokeTests/Reflection/Reflection.csproj index c386cd514b05fc..8d424f6fc12131 100644 --- a/src/tests/nativeaot/SmokeTests/Reflection/Reflection.csproj +++ b/src/tests/nativeaot/SmokeTests/Reflection/Reflection.csproj @@ -4,7 +4,6 @@ BuildAndRun 0 true - $(DefineConstants);REFLECTION_FROM_USAGE true diff --git a/src/tests/nativeaot/SmokeTests/Reflection/Reflection_ReflectedOnly.csproj b/src/tests/nativeaot/SmokeTests/Reflection/Reflection_FromUsage.csproj similarity index 84% rename from src/tests/nativeaot/SmokeTests/Reflection/Reflection_ReflectedOnly.csproj rename to src/tests/nativeaot/SmokeTests/Reflection/Reflection_FromUsage.csproj index 166979bc9c3691..584e823c5e0d05 100644 --- a/src/tests/nativeaot/SmokeTests/Reflection/Reflection_ReflectedOnly.csproj +++ b/src/tests/nativeaot/SmokeTests/Reflection/Reflection_FromUsage.csproj @@ -4,6 +4,7 @@ BuildAndRun 0 true + $(DefineConstants);REFLECTION_FROM_USAGE true @@ -11,12 +12,10 @@ true + + false - - - - From 4c6b53b04a4e53f3cd6b19811c64ab608032265c Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Wed, 15 Jun 2022 23:36:10 +0200 Subject: [PATCH 142/337] Remove GSS_KRB5_CRED_NO_CI_FLAGS_X code (#70772) The support for building with GSS_KRB5_CRED_NO_CI_FLAGS_X was broken for quite some time. Attempts to reenable it failed due to bug in the krb5 GSSAPI implementation resulting in invalid memory accesses. --- .../Net/Security/NegotiateStreamPal.Unix.cs | 10 ------- src/native/libs/Common/pal_config.h.in | 1 - .../System.Net.Security.Native/pal_gssapi.c | 30 ------------------- src/native/libs/configure.cmake | 12 -------- 4 files changed, 53 deletions(-) diff --git a/src/libraries/Common/src/System/Net/Security/NegotiateStreamPal.Unix.cs b/src/libraries/Common/src/System/Net/Security/NegotiateStreamPal.Unix.cs index 448444543018e4..291795b418b384 100644 --- a/src/libraries/Common/src/System/Net/Security/NegotiateStreamPal.Unix.cs +++ b/src/libraries/Common/src/System/Net/Security/NegotiateStreamPal.Unix.cs @@ -376,16 +376,6 @@ internal static SecurityStatusPal InitializeSecurityContext( ref resultBlob, ref contextFlags); - // Confidentiality flag should not be set if not requested - if (status.ErrorCode == SecurityStatusPalErrorCode.CompleteNeeded) - { - ContextFlagsPal mask = ContextFlagsPal.Confidentiality; - if ((requestedContextFlags & mask) != (contextFlags & mask)) - { - throw new PlatformNotSupportedException(SR.net_nego_protection_level_not_supported); - } - } - return status; } diff --git a/src/native/libs/Common/pal_config.h.in b/src/native/libs/Common/pal_config.h.in index 2c1c8ff1922c79..3f5b8c3627edcd 100644 --- a/src/native/libs/Common/pal_config.h.in +++ b/src/native/libs/Common/pal_config.h.in @@ -104,7 +104,6 @@ #cmakedefine01 HAVE_TCP_FSM_H #cmakedefine01 HAVE_GSSFW_HEADERS #cmakedefine01 HAVE_GSS_SPNEGO_MECHANISM -#cmakedefine01 HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X #cmakedefine01 HAVE_HEIMDAL_HEADERS #cmakedefine01 HAVE_NSGETENVIRON #cmakedefine01 HAVE_GETAUXVAL diff --git a/src/native/libs/System.Net.Security.Native/pal_gssapi.c b/src/native/libs/System.Net.Security.Native/pal_gssapi.c index 6206fa0fa0ce42..6959ce9a56f520 100644 --- a/src/native/libs/System.Net.Security.Native/pal_gssapi.c +++ b/src/native/libs/System.Net.Security.Native/pal_gssapi.c @@ -80,13 +80,6 @@ static gss_OID_desc gss_mech_ntlm_OID_desc = {.length = STRING_LENGTH(gss_ntlm_o PER_FUNCTION_BLOCK(GSS_C_NT_USER_NAME) \ PER_FUNCTION_BLOCK(GSS_C_NT_HOSTBASED_SERVICE) -#if HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X - -#define FOR_ALL_GSS_FUNCTIONS FOR_ALL_GSS_FUNCTIONS \ - PER_FUNCTION_BLOCK(gss_set_cred_option) - -#endif //HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X - // define indirection pointers for all functions, like // static TYPEOF(gss_accept_sec_context)* gss_accept_sec_context_ptr; #define PER_FUNCTION_BLOCK(fn) \ @@ -116,11 +109,6 @@ static void* volatile s_gssLib = NULL; #define gss_unwrap(...) gss_unwrap_ptr(__VA_ARGS__) #define gss_wrap(...) gss_wrap_ptr(__VA_ARGS__) -#if HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X -#define gss_set_cred_option(...) gss_set_cred_option_ptr(__VA_ARGS__) -#endif //HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X - - #define GSS_C_NT_USER_NAME (*GSS_C_NT_USER_NAME_ptr) #define GSS_C_NT_HOSTBASED_SERVICE (*GSS_C_NT_HOSTBASED_SERVICE_ptr) #define gss_mech_krb5 (*gss_mech_krb5_ptr) @@ -181,15 +169,6 @@ static uint32_t AcquireCredSpNego(uint32_t* minorStatus, uint32_t majorStatus = gss_acquire_cred( minorStatus, desiredName, 0, &gss_mech_spnego_OID_set_desc, credUsage, outputCredHandle, NULL, NULL); - // call gss_set_cred_option with GSS_KRB5_CRED_NO_CI_FLAGS_X to support Kerberos Sign Only option from *nix client against a windows server -#if HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X - if (majorStatus == GSS_S_COMPLETE) - { - GssBuffer emptyBuffer = GSS_C_EMPTY_BUFFER; - majorStatus = gss_set_cred_option(minorStatus, outputCredHandle, GSS_KRB5_CRED_NO_CI_FLAGS_X, &emptyBuffer); - } -#endif - return majorStatus; } @@ -604,15 +583,6 @@ static uint32_t AcquireCredWithPassword(uint32_t* minorStatus, uint32_t majorStatus = gss_acquire_cred_with_password( minorStatus, desiredName, &passwordBuffer, 0, desiredMech, credUsage, outputCredHandle, NULL, NULL); - // call gss_set_cred_option with GSS_KRB5_CRED_NO_CI_FLAGS_X to support Kerberos Sign Only option from *nix client against a windows server -#if HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X - if (majorStatus == GSS_S_COMPLETE) - { - GssBuffer emptyBuffer = GSS_C_EMPTY_BUFFER; - majorStatus = gss_set_cred_option(minorStatus, outputCredHandle, GSS_KRB5_CRED_NO_CI_FLAGS_X, &emptyBuffer); - } -#endif - return majorStatus; } diff --git a/src/native/libs/configure.cmake b/src/native/libs/configure.cmake index 8567842366bc5a..4a8b7940ce5efd 100644 --- a/src/native/libs/configure.cmake +++ b/src/native/libs/configure.cmake @@ -1042,18 +1042,6 @@ else () HAVE_GSS_SPNEGO_MECHANISM) endif () -if (HAVE_GSSFW_HEADERS) - check_symbol_exists( - GSS_KRB5_CRED_NO_CI_FLAGS_X - "GSS/GSS.h" - HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X) -else () - check_symbol_exists( - GSS_KRB5_CRED_NO_CI_FLAGS_X - "gssapi/gssapi_krb5.h" - HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X) -endif () - check_symbol_exists(getauxval sys/auxv.h HAVE_GETAUXVAL) check_include_files(crt_externs.h HAVE_CRT_EXTERNS_H) From 1e97f7c578314b0cdbadb98b3ccbf33e1b4b0bfa Mon Sep 17 00:00:00 2001 From: Jeremy Barton Date: Wed, 15 Jun 2022 15:07:12 -0700 Subject: [PATCH 143/337] Make ConnectWithRevocation_StapledOcsp more resilient to being slow --- .../CertificateValidationRemoteServer.cs | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationRemoteServer.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationRemoteServer.cs index 5498ca7ce2367d..a6a40195fc785e 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationRemoteServer.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/CertificateValidationRemoteServer.cs @@ -5,6 +5,7 @@ using System.Net; using System.Net.Sockets; using System.Net.Test.Common; +using System.Reflection; using System.Runtime.InteropServices; using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates.Tests.Common; @@ -184,8 +185,36 @@ private async Task ConnectWithRevocation_WithCallback_Core( if (revocationMode == X509RevocationMode.Offline) { - // Give the OCSP response a better chance to finish. - await Task.Delay(200); + if (offlineContext.GetValueOrDefault(false)) + { + // Add a delay just to show we're not winning because of race conditions. + await Task.Delay(200); + } + else + { + if (!OperatingSystem.IsLinux()) + { + throw new InvalidOperationException( + "This test configuration uses reflection and is only defined for Linux."); + } + + FieldInfo pendingDownloadTaskField = typeof(SslStreamCertificateContext).GetField( + "_pendingDownload", + BindingFlags.Instance | BindingFlags.NonPublic); + + if (pendingDownloadTaskField is null) + { + throw new InvalidOperationException("Cannot find the pending download field."); + } + + Task download = (Task)pendingDownloadTaskField.GetValue(serverOpts.ServerCertificateContext); + + // If it's null, it should mean it has already finished. If not, it might not have. + if (download is not null) + { + await download; + } + } } } else From 4e844e6088a3c63f5c99f24a7ac5e309288c2591 Mon Sep 17 00:00:00 2001 From: Andy Gocke Date: Wed, 15 Jun 2022 15:21:53 -0700 Subject: [PATCH 144/337] Upgrade SDK to Preview 5 (#70117) Upgrade to released Preview 5 build --- global.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/global.json b/global.json index 1447baf49983bd..18394813d74825 100644 --- a/global.json +++ b/global.json @@ -1,11 +1,11 @@ { "sdk": { - "version": "7.0.100-preview.3.22179.4", + "version": "7.0.100-preview.5.22307.18", "allowPrerelease": true, "rollForward": "major" }, "tools": { - "dotnet": "7.0.100-preview.3.22179.4" + "dotnet": "7.0.100-preview.5.22307.18" }, "msbuild-sdks": { "Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.22310.1", From 2ce8130f4bf4b02393b95719edb0f9d5c6ee1776 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 15 Jun 2022 16:22:25 -0700 Subject: [PATCH 145/337] Find&replace FastInterlock* with Interlocked* (#70784) FastInterlock* operations were #defined as aliases to regular Interlock* operations. Deleted the FastInterlock* aliases and replaced usage with Interlocked* operations. --- src/coreclr/vm/appdomain.cpp | 8 +- src/coreclr/vm/appdomain.hpp | 6 +- src/coreclr/vm/arm/cgencpu.h | 2 +- src/coreclr/vm/array.cpp | 2 +- src/coreclr/vm/assembly.cpp | 6 +- src/coreclr/vm/ceeload.cpp | 28 ++--- src/coreclr/vm/ceeload.h | 4 +- src/coreclr/vm/ceemain.cpp | 2 +- src/coreclr/vm/class.cpp | 2 +- src/coreclr/vm/class.h | 2 +- src/coreclr/vm/clsload.cpp | 2 +- src/coreclr/vm/codeman.cpp | 10 +- src/coreclr/vm/codepitchingmanager.cpp | 2 +- src/coreclr/vm/codeversion.cpp | 2 +- src/coreclr/vm/comcache.cpp | 6 +- src/coreclr/vm/comcallablewrapper.cpp | 18 +-- src/coreclr/vm/comcallablewrapper.h | 10 +- src/coreclr/vm/comconnectionpoints.cpp | 8 +- src/coreclr/vm/comdelegate.cpp | 6 +- src/coreclr/vm/comsynchronizable.cpp | 2 +- src/coreclr/vm/comtoclrcall.cpp | 2 +- src/coreclr/vm/comutilnative.cpp | 28 ++--- src/coreclr/vm/corhost.cpp | 6 +- src/coreclr/vm/crst.cpp | 4 +- src/coreclr/vm/crst.h | 4 +- src/coreclr/vm/disassembler.cpp | 4 +- src/coreclr/vm/domainassembly.cpp | 4 +- src/coreclr/vm/dynamicmethod.cpp | 2 +- src/coreclr/vm/eehash.inl | 4 +- src/coreclr/vm/eepolicy.cpp | 2 +- src/coreclr/vm/encee.cpp | 2 +- src/coreclr/vm/eventreporter.cpp | 2 +- src/coreclr/vm/excep.cpp | 2 +- src/coreclr/vm/exceptionhandling.cpp | 8 +- src/coreclr/vm/finalizerthread.cpp | 2 +- src/coreclr/vm/gccover.cpp | 2 +- src/coreclr/vm/gchelpers.cpp | 2 +- src/coreclr/vm/genericdict.cpp | 4 +- src/coreclr/vm/hash.cpp | 6 +- src/coreclr/vm/hosting.cpp | 2 +- src/coreclr/vm/i386/excepx86.cpp | 4 +- src/coreclr/vm/i386/stublinkerx86.cpp | 2 +- src/coreclr/vm/ilstubresolver.cpp | 6 +- src/coreclr/vm/instmethhash.h | 4 +- .../vm/interoplibinterface_comwrappers.cpp | 2 +- src/coreclr/vm/interoplibinterface_objc.cpp | 6 +- src/coreclr/vm/jithelpers.cpp | 4 +- src/coreclr/vm/listlock.h | 4 +- src/coreclr/vm/loaderallocator.cpp | 12 +- src/coreclr/vm/method.cpp | 32 ++--- src/coreclr/vm/method.hpp | 2 +- src/coreclr/vm/methodtable.cpp | 6 +- src/coreclr/vm/methodtable.h | 10 +- src/coreclr/vm/mngstdinterfaces.h | 2 +- src/coreclr/vm/peassembly.cpp | 6 +- src/coreclr/vm/peassembly.inl | 4 +- src/coreclr/vm/peimage.cpp | 8 +- src/coreclr/vm/peimage.inl | 2 +- src/coreclr/vm/peimagelayout.inl | 4 +- src/coreclr/vm/proftoeeinterfaceimpl.cpp | 4 +- src/coreclr/vm/spinlock.cpp | 4 +- src/coreclr/vm/spinlock.h | 4 +- src/coreclr/vm/stublink.cpp | 4 +- src/coreclr/vm/syncblk.cpp | 10 +- src/coreclr/vm/syncblk.h | 22 ++-- src/coreclr/vm/syncclean.cpp | 8 +- src/coreclr/vm/synch.cpp | 10 +- src/coreclr/vm/threadpoolrequest.cpp | 10 +- src/coreclr/vm/threadpoolrequest.h | 4 +- src/coreclr/vm/threads.cpp | 114 +++++++++--------- src/coreclr/vm/threads.h | 64 +++++----- src/coreclr/vm/threadsuspend.cpp | 52 ++++---- src/coreclr/vm/typedesc.cpp | 6 +- src/coreclr/vm/typedesc.h | 2 +- src/coreclr/vm/typehash.h | 4 +- src/coreclr/vm/util.hpp | 35 ------ src/coreclr/vm/virtualcallstub.cpp | 14 +-- src/coreclr/vm/win32threadpool.cpp | 8 +- src/coreclr/vm/win32threadpool.h | 6 +- 79 files changed, 344 insertions(+), 381 deletions(-) diff --git a/src/coreclr/vm/appdomain.cpp b/src/coreclr/vm/appdomain.cpp index dd6541a1f74379..e8da7d08ac9acf 100644 --- a/src/coreclr/vm/appdomain.cpp +++ b/src/coreclr/vm/appdomain.cpp @@ -903,7 +903,7 @@ OBJECTREF AppDomain::GetMissingObject() // Retrieve the value static field and store it. OBJECTHANDLE hndMissing = CreateHandle(pValueFD->GetStaticOBJECTREF()); - if (FastInterlockCompareExchangePointer(&m_hndMissing, hndMissing, NULL) != NULL) + if (InterlockedCompareExchangeT(&m_hndMissing, hndMissing, NULL) != NULL) { // Exchanged failed. The m_hndMissing did not equal NULL and was returned. DestroyHandle(hndMissing); @@ -2390,7 +2390,7 @@ void FileLoadLock::SetError(Exception *ex) void FileLoadLock::AddRef() { LIMITED_METHOD_CONTRACT; - FastInterlockIncrement((LONG *) &m_dwRefCount); + InterlockedIncrement((LONG *) &m_dwRefCount); } UINT32 FileLoadLock::Release() @@ -2403,7 +2403,7 @@ UINT32 FileLoadLock::Release() } CONTRACTL_END; - LONG count = FastInterlockDecrement((LONG *) &m_dwRefCount); + LONG count = InterlockedDecrement((LONG *) &m_dwRefCount); if (count == 0) delete this; @@ -4034,7 +4034,7 @@ RCWRefCache *AppDomain::GetRCWRefCache() if (!m_pRCWRefCache) { NewHolder pRCWRefCache = new RCWRefCache(this); - if (FastInterlockCompareExchangePointer(&m_pRCWRefCache, (RCWRefCache *)pRCWRefCache, NULL) == NULL) + if (InterlockedCompareExchangeT(&m_pRCWRefCache, (RCWRefCache *)pRCWRefCache, NULL) == NULL) { pRCWRefCache.SuppressRelease(); } diff --git a/src/coreclr/vm/appdomain.hpp b/src/coreclr/vm/appdomain.hpp index de8264b59842df..212a5e9994100f 100644 --- a/src/coreclr/vm/appdomain.hpp +++ b/src/coreclr/vm/appdomain.hpp @@ -2001,14 +2001,14 @@ class AppDomain : public BaseDomain { LIMITED_METHOD_CONTRACT; _ASSERTE(m_dwIterHolders); - FastInterlockDecrement(&m_dwIterHolders); + InterlockedDecrement(&m_dwIterHolders); } void IteratorAcquire() { LIMITED_METHOD_CONTRACT; - FastInterlockIncrement(&m_dwIterHolders); + InterlockedIncrement(&m_dwIterHolders); } #endif @@ -2152,7 +2152,7 @@ class AppDomain : public BaseDomain STRESS_LOG1(LF_APPDOMAIN, LL_INFO100,"Updating AD stage, stage=%d\n",stage); Stage lastStage=m_Stage; while (lastStage !=stage) - lastStage = (Stage)FastInterlockCompareExchange((LONG*)&m_Stage,stage,lastStage); + lastStage = (Stage)InterlockedCompareExchange((LONG*)&m_Stage,stage,lastStage); }; // List of unloaded LoaderAllocators, protected by code:GetLoaderAllocatorReferencesLock (for now) diff --git a/src/coreclr/vm/arm/cgencpu.h b/src/coreclr/vm/arm/cgencpu.h index a9ba5ec08effc1..c207c5ba87814a 100644 --- a/src/coreclr/vm/arm/cgencpu.h +++ b/src/coreclr/vm/arm/cgencpu.h @@ -1064,7 +1064,7 @@ struct ThisPtrRetBufPrecode { CONTRACTL_END; ExecutableWriterHolder precodeWriterHolder(this, sizeof(ThisPtrRetBufPrecode)); - return FastInterlockCompareExchange((LONG*)&precodeWriterHolder.GetRW()->m_pTarget, (LONG)target, (LONG)expected) == (LONG)expected; + return InterlockedCompareExchange((LONG*)&precodeWriterHolder.GetRW()->m_pTarget, (LONG)target, (LONG)expected) == (LONG)expected; } #endif // !DACCESS_COMPILE }; diff --git a/src/coreclr/vm/array.cpp b/src/coreclr/vm/array.cpp index 402acdb7a53233..69617911e03590 100644 --- a/src/coreclr/vm/array.cpp +++ b/src/coreclr/vm/array.cpp @@ -1183,7 +1183,7 @@ class ArrayStubCache : public StubCacheBase if (s_pArrayStubCache == NULL) { ArrayStubCache * pArrayStubCache = new ArrayStubCache(SystemDomain::GetGlobalLoaderAllocator()->GetStubHeap()); - if (FastInterlockCompareExchangePointer(&s_pArrayStubCache, pArrayStubCache, NULL) != NULL) + if (InterlockedCompareExchangeT(&s_pArrayStubCache, pArrayStubCache, NULL) != NULL) delete pArrayStubCache; } diff --git a/src/coreclr/vm/assembly.cpp b/src/coreclr/vm/assembly.cpp index e72b6bfe575275..e0bf705f1e97e2 100644 --- a/src/coreclr/vm/assembly.cpp +++ b/src/coreclr/vm/assembly.cpp @@ -195,7 +195,7 @@ void Assembly::Init(AllocMemTracker *pamTracker, LoaderAllocator *pLoaderAllocat else m_pModule = Module::Create(this, mdFileNil, pPEAssembly, pamTracker); - FastInterlockIncrement((LONG*)&g_cAssemblies); + InterlockedIncrement((LONG*)&g_cAssemblies); PrepareModuleForAssembly(m_pModule, pamTracker); @@ -312,7 +312,7 @@ void Assembly::Terminate( BOOL signalProfiler ) m_pClassLoader = NULL; } - FastInterlockDecrement((LONG*)&g_cAssemblies); + InterlockedDecrement((LONG*)&g_cAssemblies); #ifdef PROFILING_SUPPORTED if (CORProfilerTrackAssemblyLoads()) @@ -1084,7 +1084,7 @@ void Assembly::PublishModuleIntoAssembly(Module *module) CONTRACTL_END GetModule()->EnsuredStoreFile(module->GetModuleRef(), module); - FastInterlockIncrement((LONG*)&m_pClassLoader->m_cUnhashedModules); + InterlockedIncrement((LONG*)&m_pClassLoader->m_cUnhashedModules); } diff --git a/src/coreclr/vm/ceeload.cpp b/src/coreclr/vm/ceeload.cpp index 4ffba8ab8a3c6c..f4a6eb2f920cfe 100644 --- a/src/coreclr/vm/ceeload.cpp +++ b/src/coreclr/vm/ceeload.cpp @@ -178,7 +178,7 @@ BOOL Module::SetTransientFlagInterlocked(DWORD dwFlag) DWORD dwTransientFlags = m_dwTransientFlags; if ((dwTransientFlags & dwFlag) != 0) return FALSE; - if ((DWORD)FastInterlockCompareExchange((LONG*)&m_dwTransientFlags, dwTransientFlags | dwFlag, dwTransientFlags) == dwTransientFlags) + if ((DWORD)InterlockedCompareExchange((LONG*)&m_dwTransientFlags, dwTransientFlags | dwFlag, dwTransientFlags) == dwTransientFlags) return TRUE; } } @@ -434,7 +434,7 @@ void Module::Initialize(AllocMemTracker *pamTracker, LPCWSTR szName) #ifdef FEATURE_COLLECTIBLE_TYPES if (GetAssembly()->IsCollectible()) { - FastInterlockOr(&m_dwPersistedFlags, COLLECTIBLE_MODULE); + InterlockedOr((LONG*)&m_dwPersistedFlags, COLLECTIBLE_MODULE); } #endif // FEATURE_COLLECTIBLE_TYPES @@ -962,7 +962,7 @@ MethodTable *Module::GetGlobalMethodTable() ClassLoader::FailIfUninstDefOrRef).AsMethodTable(); } - FastInterlockOr(&m_dwPersistedFlags, COMPUTED_GLOBAL_CLASS); + InterlockedOr((LONG*)&m_dwPersistedFlags, COMPUTED_GLOBAL_CLASS); RETURN pMT; } else @@ -1580,11 +1580,11 @@ BOOL Module::HasDefaultDllImportSearchPathsAttribute() attributeIsFound = GetDefaultDllImportSearchPathsAttributeValue(this, TokenFromRid(1, mdtAssembly),&m_DefaultDllImportSearchPathsAttributeValue); if(attributeIsFound) { - FastInterlockOr(&m_dwPersistedFlags, DEFAULT_DLL_IMPORT_SEARCH_PATHS_IS_CACHED | DEFAULT_DLL_IMPORT_SEARCH_PATHS_STATUS); + InterlockedOr((LONG*)&m_dwPersistedFlags, DEFAULT_DLL_IMPORT_SEARCH_PATHS_IS_CACHED | DEFAULT_DLL_IMPORT_SEARCH_PATHS_STATUS); } else { - FastInterlockOr(&m_dwPersistedFlags, DEFAULT_DLL_IMPORT_SEARCH_PATHS_IS_CACHED); + InterlockedOr((LONG*)&m_dwPersistedFlags, DEFAULT_DLL_IMPORT_SEARCH_PATHS_IS_CACHED); } return (m_dwPersistedFlags & DEFAULT_DLL_IMPORT_SEARCH_PATHS_STATUS) != 0 ; @@ -1644,7 +1644,7 @@ BOOL Module::IsRuntimeWrapExceptions() fRuntimeWrapExceptions = TRUE; } ErrExit: - FastInterlockOr(&m_dwPersistedFlags, COMPUTED_WRAP_EXCEPTIONS | + InterlockedOr((LONG*)&m_dwPersistedFlags, COMPUTED_WRAP_EXCEPTIONS | (fRuntimeWrapExceptions ? WRAP_EXCEPTIONS : 0)); } @@ -1681,7 +1681,7 @@ BOOL Module::IsRuntimeMarshallingEnabled() (const void**)&pVal, &cbVal); } - FastInterlockOr(&m_dwPersistedFlags, RUNTIME_MARSHALLING_ENABLED_IS_CACHED | + InterlockedOr((LONG*)&m_dwPersistedFlags, RUNTIME_MARSHALLING_ENABLED_IS_CACHED | (hr == S_OK ? 0 : RUNTIME_MARSHALLING_ENABLED)); return hr != S_OK; @@ -1712,7 +1712,7 @@ BOOL Module::IsPreV4Assembly() } } - FastInterlockOr(&m_dwPersistedFlags, COMPUTED_IS_PRE_V4_ASSEMBLY | + InterlockedOr((LONG*)&m_dwPersistedFlags, COMPUTED_IS_PRE_V4_ASSEMBLY | (fIsPreV4Assembly ? IS_PRE_V4_ASSEMBLY : 0)); } @@ -1731,7 +1731,7 @@ DWORD Module::AllocateDynamicEntry(MethodTable *pMT) } CONTRACTL_END; - DWORD newId = FastInterlockExchangeAdd((LONG*)&m_cDynamicEntries, 1); + DWORD newId = InterlockedExchangeAdd((LONG*)&m_cDynamicEntries, 1); if (newId >= VolatileLoad(&m_maxDynamicEntries)) { @@ -2123,7 +2123,7 @@ void Module::FreeClassTables() if (m_dwTransientFlags & CLASSES_FREED) return; - FastInterlockOr(&m_dwTransientFlags, CLASSES_FREED); + InterlockedOr((LONG*)&m_dwTransientFlags, CLASSES_FREED); #if _DEBUG DebugLogRidMapOccupancy(); @@ -2698,7 +2698,7 @@ ILStubCache* Module::GetILStubCache() { ILStubCache *pILStubCache = new ILStubCache(GetLoaderAllocator()->GetHighFrequencyHeap()); - if (FastInterlockCompareExchangePointer(&m_pILStubCache, pILStubCache, NULL) != NULL) + if (InterlockedCompareExchangeT(&m_pILStubCache, pILStubCache, NULL) != NULL) { // some thread swooped in and set the field delete pILStubCache; @@ -4398,7 +4398,7 @@ LoaderHeap *Module::GetThunkHeap() ThunkHeapStubManager::g_pManager->GetRangeList(), UnlockedLoaderHeap::HeapKind::Executable); - if (FastInterlockCompareExchangePointer(&m_pThunkHeap, pNewHeap, 0) != 0) + if (InterlockedCompareExchangeT(&m_pThunkHeap, pNewHeap, 0) != 0) { delete pNewHeap; } @@ -4732,7 +4732,7 @@ void SaveManagedCommandLine(LPCWSTR pwzAssemblyPath, int argc, LPCWSTR *argv) void Module::SetIsIJWFixedUp() { LIMITED_METHOD_CONTRACT; - FastInterlockOr(&m_dwTransientFlags, IS_IJW_FIXED_UP); + InterlockedOr((LONG*)&m_dwTransientFlags, IS_IJW_FIXED_UP); } #endif // !DACCESS_COMPILE @@ -4740,7 +4740,7 @@ void Module::SetIsIJWFixedUp() void Module::SetBeingUnloaded() { LIMITED_METHOD_CONTRACT; - FastInterlockOr((ULONG*)&m_dwTransientFlags, IS_BEING_UNLOADED); + InterlockedOr((LONG*)&m_dwTransientFlags, IS_BEING_UNLOADED); } // =========================================================================== diff --git a/src/coreclr/vm/ceeload.h b/src/coreclr/vm/ceeload.h index ff980ed5cfd178..c0ddc457096abe 100644 --- a/src/coreclr/vm/ceeload.h +++ b/src/coreclr/vm/ceeload.h @@ -891,7 +891,7 @@ class Module VOID SetIsTenured() { LIMITED_METHOD_CONTRACT; - FastInterlockOr(&m_dwTransientFlags, MODULE_IS_TENURED); + InterlockedOr((LONG*)&m_dwTransientFlags, MODULE_IS_TENURED); } #endif // !DACCESS_COMPILE @@ -909,7 +909,7 @@ class Module VOID SetIsReadyForTypeLoad() { LIMITED_METHOD_CONTRACT; - FastInterlockOr(&m_dwTransientFlags, MODULE_READY_FOR_TYPELOAD); + InterlockedOr((LONG*)&m_dwTransientFlags, MODULE_READY_FOR_TYPELOAD); } #endif diff --git a/src/coreclr/vm/ceemain.cpp b/src/coreclr/vm/ceemain.cpp index 36d63aa9e771dc..5d3e2a7f47a7fc 100644 --- a/src/coreclr/vm/ceemain.cpp +++ b/src/coreclr/vm/ceemain.cpp @@ -1528,7 +1528,7 @@ void STDMETHODCALLTYPE EEShutDown(BOOL fIsDllUnloading) if (!fIsDllUnloading) { - if (FastInterlockIncrement(&OnlyOne) != 0) + if (InterlockedIncrement(&OnlyOne) != 0) { // I'm in a regular shutdown -- but another thread got here first. // It's a race if I return from here -- I'll call ExitProcess next, and diff --git a/src/coreclr/vm/class.cpp b/src/coreclr/vm/class.cpp index 6a51768b103699..118dc8c6e846eb 100644 --- a/src/coreclr/vm/class.cpp +++ b/src/coreclr/vm/class.cpp @@ -2192,7 +2192,7 @@ void EEClass::GetBestFitMapping(MethodTable * pMT, BOOL *pfBestFitMapping, BOOL if (*pfBestFitMapping) flags |= VMFLAG_BESTFITMAPPING; if (*pfThrowOnUnmappableChar) flags |= VMFLAG_THROWONUNMAPPABLECHAR; - FastInterlockOr(&pClass->m_VMFlags, flags); + InterlockedOr((LONG*)&pClass->m_VMFlags, flags); } else { diff --git a/src/coreclr/vm/class.h b/src/coreclr/vm/class.h index 3093feae45bfdd..7b9f77bca449ca 100644 --- a/src/coreclr/vm/class.h +++ b/src/coreclr/vm/class.h @@ -1198,7 +1198,7 @@ class EEClass // DO NOT CREATE A NEW EEClass USING NEW! inline void SetHasNoGuid() { WRAPPER_NO_CONTRACT; - FastInterlockOr(&m_VMFlags, VMFLAG_NO_GUID); + InterlockedOr((LONG*)&m_VMFlags, VMFLAG_NO_GUID); } public: diff --git a/src/coreclr/vm/clsload.cpp b/src/coreclr/vm/clsload.cpp index 8667c8e905ce08..1e91485aeada97 100644 --- a/src/coreclr/vm/clsload.cpp +++ b/src/coreclr/vm/clsload.cpp @@ -894,7 +894,7 @@ void ClassLoader::LazyPopulateCaseInsensitiveHashTables() amTracker.SuppressRelease(); pModule->SetAvailableClassCaseInsHash(pNewClassCaseInsHash); - FastInterlockDecrement((LONG*)&m_cUnhashedModules); + InterlockedDecrement((LONG*)&m_cUnhashedModules); _ASSERT(m_cUnhashedModules >= 0); } diff --git a/src/coreclr/vm/codeman.cpp b/src/coreclr/vm/codeman.cpp index 1b7caaef542018..37502f21ef1d3b 100644 --- a/src/coreclr/vm/codeman.cpp +++ b/src/coreclr/vm/codeman.cpp @@ -654,7 +654,7 @@ ExecutionManager::ReaderLockHolder::ReaderLockHolder(HostCallPreference hostCall IncCantAllocCount(); - FastInterlockIncrement(&m_dwReaderCount); + InterlockedIncrement(&m_dwReaderCount); EE_LOCK_TAKEN(GetPtrForLockContract()); @@ -687,7 +687,7 @@ ExecutionManager::ReaderLockHolder::~ReaderLockHolder() } CONTRACTL_END; - FastInterlockDecrement(&m_dwReaderCount); + InterlockedDecrement(&m_dwReaderCount); DecCantAllocCount(); EE_LOCK_RELEASED(GetPtrForLockContract()); @@ -725,10 +725,10 @@ ExecutionManager::WriterLockHolder::WriterLockHolder() // or allow a profiler to walk its stack Thread::IncForbidSuspendThread(); - FastInterlockIncrement(&m_dwWriterLock); + InterlockedIncrement(&m_dwWriterLock); if (m_dwReaderCount == 0) break; - FastInterlockDecrement(&m_dwWriterLock); + InterlockedDecrement(&m_dwWriterLock); // Before we loop and retry, it's safe to suspend or hijack and inspect // this thread @@ -743,7 +743,7 @@ ExecutionManager::WriterLockHolder::~WriterLockHolder() { LIMITED_METHOD_CONTRACT; - FastInterlockDecrement(&m_dwWriterLock); + InterlockedDecrement(&m_dwWriterLock); // Writer lock released, so it's safe again for this thread to be // suspended or have its stack walked by a profiler diff --git a/src/coreclr/vm/codepitchingmanager.cpp b/src/coreclr/vm/codepitchingmanager.cpp index 6badd9746d44f5..45bac532a317c1 100644 --- a/src/coreclr/vm/codepitchingmanager.cpp +++ b/src/coreclr/vm/codepitchingmanager.cpp @@ -78,7 +78,7 @@ static void CreateRWLock(SimpleRWLock** lock) void *pLockSpace = SystemDomain::GetGlobalLoaderAllocator()->GetLowFrequencyHeap()->AllocMem(S_SIZE_T(sizeof(SimpleRWLock))); SimpleRWLock *pLock = new (pLockSpace) SimpleRWLock(COOPERATIVE_OR_PREEMPTIVE, LOCK_TYPE_DEFAULT); - if (FastInterlockCompareExchangePointer(lock, pLock, NULL) != NULL) + if (InterlockedCompareExchangeT(lock, pLock, NULL) != NULL) SystemDomain::GetGlobalLoaderAllocator()->GetLowFrequencyHeap()->BackoutMem(pLockSpace, sizeof(SimpleRWLock)); } } diff --git a/src/coreclr/vm/codeversion.cpp b/src/coreclr/vm/codeversion.cpp index ffb0b73157a67e..bd7fce5d9d7c4d 100644 --- a/src/coreclr/vm/codeversion.cpp +++ b/src/coreclr/vm/codeversion.cpp @@ -110,7 +110,7 @@ NativeCodeVersionId NativeCodeVersionNode::GetVersionId() const BOOL NativeCodeVersionNode::SetNativeCodeInterlocked(PCODE pCode, PCODE pExpected) { LIMITED_METHOD_CONTRACT; - return FastInterlockCompareExchangePointer(&m_pNativeCode, + return InterlockedCompareExchangeT(&m_pNativeCode, (TADDR&)pCode, (TADDR&)pExpected) == (TADDR&)pExpected; } #endif diff --git a/src/coreclr/vm/comcache.cpp b/src/coreclr/vm/comcache.cpp index 6454b439541044..c9afbbed923dd9 100644 --- a/src/coreclr/vm/comcache.cpp +++ b/src/coreclr/vm/comcache.cpp @@ -1100,7 +1100,7 @@ HRESULT IUnkEntry::MarshalIUnknownToStream() // Try to set the stream in the IUnkEntry. If another thread already set it, // then we need to release the stream we just set up. - if (FastInterlockCompareExchangePointer(&m_pStream, pStream, NULL) != NULL) + if (InterlockedCompareExchangeT(&m_pStream, pStream, NULL) != NULL) SafeReleaseStream(pStream); return hr; @@ -1248,7 +1248,7 @@ DWORD CtxEntry::AddRef() } CONTRACTL_END; - ULONG cbRef = FastInterlockIncrement((LONG*)&m_dwRefCount); + ULONG cbRef = InterlockedIncrement((LONG*)&m_dwRefCount); LOG((LF_INTEROP, LL_INFO100, "CtxEntry::Addref %8.8x with %d\n", this, cbRef)); return cbRef; } @@ -1269,7 +1269,7 @@ DWORD CtxEntry::Release() LPVOID pCtxCookie = m_pCtxCookie; - LONG cbRef = FastInterlockDecrement((LONG*)&m_dwRefCount); + LONG cbRef = InterlockedDecrement((LONG*)&m_dwRefCount); LOG((LF_INTEROP, LL_INFO100, "CtxEntry::Release %8.8x with %d\n", this, cbRef)); // If the ref count falls to 0, try and delete the ctx entry. diff --git a/src/coreclr/vm/comcallablewrapper.cpp b/src/coreclr/vm/comcallablewrapper.cpp index 37a763e7b26f0f..9b91cf1a9299df 100644 --- a/src/coreclr/vm/comcallablewrapper.cpp +++ b/src/coreclr/vm/comcallablewrapper.cpp @@ -991,7 +991,7 @@ BOOL SimpleComCallWrapper::CustomQIRespondsToIMarshal() { newFlags |= enum_CustomQIRespondsToIMarshal; } - FastInterlockOr((ULONG *)&m_flags, newFlags); + InterlockedOr((LONG*)&m_flags, newFlags); } return (m_flags & enum_CustomQIRespondsToIMarshal); @@ -1034,7 +1034,7 @@ void SimpleComCallWrapper::InitDispatchExInfo() pDispExInfo->SynchWithManagedView(); // Swap the lock into the class member in a thread safe manner. - if (NULL == FastInterlockCompareExchangePointer(&pAuxData->m_pDispatchExInfo, pDispExInfo.GetValue(), NULL)) + if (NULL == InterlockedCompareExchangeT(&pAuxData->m_pDispatchExInfo, pDispExInfo.GetValue(), NULL)) pDispExInfo.SuppressRelease(); // Set the vtable entry to ensure that the next QI call will return immediately. @@ -2083,7 +2083,7 @@ void ComCallWrapper::ClearHandle() WRAPPER_NO_CONTRACT; OBJECTHANDLE pThis = m_ppThis; - if (FastInterlockCompareExchangePointer(&m_ppThis, NULL, pThis) == pThis) + if (InterlockedCompareExchangeT(&m_ppThis, NULL, pThis) == pThis) { DestroyRefcountedHandle(pThis); } @@ -3068,7 +3068,7 @@ LONG ComCallWrapperCache::AddRef() } CONTRACTL_END; - LONG i = FastInterlockIncrement(&m_cbRef); + LONG i = InterlockedIncrement(&m_cbRef); LOG((LF_INTEROP, LL_INFO100, "ComCallWrapperCache::Addref %8.8x with %d in loader allocator [%d] %8.8x\n", this, i, GetLoaderAllocator()?GetLoaderAllocator()->GetCreationNumber() : 0, GetLoaderAllocator())); @@ -3089,7 +3089,7 @@ LONG ComCallWrapperCache::Release() } CONTRACTL_END; - LONG i = FastInterlockDecrement(&m_cbRef); + LONG i = InterlockedDecrement(&m_cbRef); _ASSERTE(i >= 0); LOG((LF_INTEROP, LL_INFO100, "ComCallWrapperCache::Release %8.8x with %d in loader allocator [%d] %8.8x\n", @@ -3790,7 +3790,7 @@ void ComMethodTable::LayOutBasicMethodTable() // // Set the layout complete flag. // - FastInterlockOr((DWORD *)&m_Flags, enum_LayoutComplete); + InterlockedOr((LONG*)&m_Flags, enum_LayoutComplete); LOG((LF_INTEROP, LL_INFO1000, "LayOutClassMethodTable: %s, this: %p [DONE]\n", m_pMT->GetDebugClassName(), this)); } @@ -3821,7 +3821,7 @@ DispatchInfo *ComMethodTable::GetDispatchInfo() ExecutableWriterHolder comMTWriterHolder(this, sizeof(ComMethodTable)); // Swap the lock into the class member in a thread safe manner. - if (NULL == FastInterlockCompareExchangePointer(&comMTWriterHolder.GetRW()->m_pDispatchInfo, pDispInfo.GetValue(), NULL)) + if (NULL == InterlockedCompareExchangeT(&comMTWriterHolder.GetRW()->m_pDispatchInfo, pDispInfo.GetValue(), NULL)) pDispInfo.SuppressRelease(); } @@ -4140,7 +4140,7 @@ BOOL ComCallWrapperTemplate::IsSafeTypeForMarshalling() if (isSafe) { - FastInterlockOr(&m_flags, enum_IsSafeTypeForMarshalling); + InterlockedOr((LONG*)&m_flags, enum_IsSafeTypeForMarshalling); } return isSafe; @@ -4212,7 +4212,7 @@ DefaultInterfaceType ComCallWrapperTemplate::GetDefaultInterface(MethodTable **p _ASSERTE(th.IsNull() || !th.IsTypeDesc()); m_pDefaultItf = th.AsMethodTable(); - FastInterlockOr(&m_flags, enum_DefaultInterfaceTypeComputed | (DWORD)defItfType); + InterlockedOr((LONG*)&m_flags, enum_DefaultInterfaceTypeComputed | (DWORD)defItfType); } *ppDefaultItf = m_pDefaultItf; diff --git a/src/coreclr/vm/comcallablewrapper.h b/src/coreclr/vm/comcallablewrapper.h index 048c39e3c655fb..d4b0ebfb277b8a 100644 --- a/src/coreclr/vm/comcallablewrapper.h +++ b/src/coreclr/vm/comcallablewrapper.h @@ -1249,14 +1249,14 @@ public : { WRAPPER_NO_CONTRACT; - FastInterlockOr((ULONG*)&m_flags, enum_IsAggregated); + InterlockedOr((LONG*)&m_flags, enum_IsAggregated); } void UnMarkAggregated() { WRAPPER_NO_CONTRACT; - FastInterlockAnd((ULONG*)&m_flags, ~enum_IsAggregated); + InterlockedAnd((LONG*)&m_flags, ~enum_IsAggregated); } BOOL IsHandleWeak() @@ -1270,14 +1270,14 @@ public : { WRAPPER_NO_CONTRACT; - FastInterlockOr((ULONG*)&m_flags, enum_IsHandleWeak); + InterlockedOr((LONG*)&m_flags, enum_IsHandleWeak); } VOID ResetHandleStrength() { WRAPPER_NO_CONTRACT; - FastInterlockAnd((ULONG*)&m_flags, ~enum_IsHandleWeak); + InterlockedAnd((LONG*)&m_flags, ~enum_IsHandleWeak); } // is the object extends from (aggregates) a COM component @@ -1297,7 +1297,7 @@ public : void MarkComActivated() { LIMITED_METHOD_CONTRACT; - FastInterlockOr((ULONG*)&m_flags, enum_IsComActivated); + InterlockedOr((LONG*)&m_flags, enum_IsComActivated); } // Determines if the type associated with the ComCallWrapper supports exceptions. diff --git a/src/coreclr/vm/comconnectionpoints.cpp b/src/coreclr/vm/comconnectionpoints.cpp index c02ef40abc7b5d..506e4a1d05cabc 100644 --- a/src/coreclr/vm/comconnectionpoints.cpp +++ b/src/coreclr/vm/comconnectionpoints.cpp @@ -822,7 +822,7 @@ ULONG __stdcall ConnectionPointEnum::AddRef() SetupForComCallHR(); - LONG i = FastInterlockIncrement((LONG*)&m_cbRefCount ); + LONG i = InterlockedIncrement((LONG*)&m_cbRefCount ); return i; } @@ -843,7 +843,7 @@ ULONG __stdcall ConnectionPointEnum::Release() BEGIN_EXTERNAL_ENTRYPOINT(&hr) { - cbRef = FastInterlockDecrement((LONG*)&m_cbRefCount ); + cbRef = InterlockedDecrement((LONG*)&m_cbRefCount ); _ASSERTE(cbRef >=0); if (cbRef == 0) delete this; @@ -1063,7 +1063,7 @@ ULONG __stdcall ConnectionEnum::AddRef() SetupForComCallHR(); - LONG i = FastInterlockIncrement((LONG*)&m_cbRefCount); + LONG i = InterlockedIncrement((LONG*)&m_cbRefCount); return i; } @@ -1079,7 +1079,7 @@ ULONG __stdcall ConnectionEnum::Release() SetupForComCallHR(); - LONG i = FastInterlockDecrement((LONG*)&m_cbRefCount); + LONG i = InterlockedDecrement((LONG*)&m_cbRefCount); _ASSERTE(i >=0); if (i == 0) delete this; diff --git a/src/coreclr/vm/comdelegate.cpp b/src/coreclr/vm/comdelegate.cpp index 53616e81c0f65a..235e79ad58efac 100644 --- a/src/coreclr/vm/comdelegate.cpp +++ b/src/coreclr/vm/comdelegate.cpp @@ -834,7 +834,7 @@ Stub* COMDelegate::SetupShuffleThunk(MethodTable * pDelMT, MethodDesc *pTargetMe if (!pTargetMeth->IsStatic() && pTargetMeth->HasRetBuffArg() && IsRetBuffPassedAsFirstArg()) { - if (FastInterlockCompareExchangePointer(&pClass->m_pInstRetBuffCallStub, pShuffleThunk, NULL ) != NULL) + if (InterlockedCompareExchangeT(&pClass->m_pInstRetBuffCallStub, pShuffleThunk, NULL ) != NULL) { ExecutableWriterHolder shuffleThunkWriterHolder(pShuffleThunk, sizeof(Stub)); shuffleThunkWriterHolder.GetRW()->DecRef(); @@ -843,7 +843,7 @@ Stub* COMDelegate::SetupShuffleThunk(MethodTable * pDelMT, MethodDesc *pTargetMe } else { - if (FastInterlockCompareExchangePointer(&pClass->m_pStaticCallStub, pShuffleThunk, NULL ) != NULL) + if (InterlockedCompareExchangeT(&pClass->m_pStaticCallStub, pShuffleThunk, NULL ) != NULL) { ExecutableWriterHolder shuffleThunkWriterHolder(pShuffleThunk, sizeof(Stub)); shuffleThunkWriterHolder.GetRW()->DecRef(); @@ -1273,7 +1273,7 @@ LPVOID COMDelegate::ConvertToCallback(OBJECTREF pDelegateObj) ExecutableWriterHolder uMThunkMarshInfoWriterHolder(pUMThunkMarshInfo, sizeof(UMThunkMarshInfo)); uMThunkMarshInfoWriterHolder.GetRW()->LoadTimeInit(pInvokeMeth); - if (FastInterlockCompareExchangePointer(&(pClass->m_pUMThunkMarshInfo), + if (InterlockedCompareExchangeT(&(pClass->m_pUMThunkMarshInfo), pUMThunkMarshInfo, NULL ) != NULL) { diff --git a/src/coreclr/vm/comsynchronizable.cpp b/src/coreclr/vm/comsynchronizable.cpp index 8c64ca22fbe773..e38debbebeb692 100644 --- a/src/coreclr/vm/comsynchronizable.cpp +++ b/src/coreclr/vm/comsynchronizable.cpp @@ -295,7 +295,7 @@ void ThreadNative::Start(Thread* pNewThread, int threadStackSize, int priority, pNewThread->SetThreadPriority(MapToNTPriority(priority)); pNewThread->ChooseThreadCPUGroupAffinity(); - FastInterlockOr((ULONG *) &pNewThread->m_State, Thread::TS_LegalToJoin); + pNewThread->SetThreadState(Thread::TS_LegalToJoin); DWORD ret = pNewThread->StartThread(); diff --git a/src/coreclr/vm/comtoclrcall.cpp b/src/coreclr/vm/comtoclrcall.cpp index d9c76f3ecb8d08..7eae976a068ed3 100644 --- a/src/coreclr/vm/comtoclrcall.cpp +++ b/src/coreclr/vm/comtoclrcall.cpp @@ -868,7 +868,7 @@ void ComCallMethodDesc::InitRuntimeNativeInfo(MethodDesc *pStubMD) comCallMDWriterHolder.GetRW()->m_dwSlotInfo = (wSourceSlotEDX | (wStubStackSlotCount << 16)); if (pwStubStackSlotOffsets != NULL) { - if (FastInterlockCompareExchangePointer(&comCallMDWriterHolder.GetRW()->m_pwStubStackSlotOffsets, pwStubStackSlotOffsets.GetValue(), NULL) == NULL) + if (InterlockedCompareExchangeT(&comCallMDWriterHolder.GetRW()->m_pwStubStackSlotOffsets, pwStubStackSlotOffsets.GetValue(), NULL) == NULL) { pwStubStackSlotOffsets.SuppressRelease(); } diff --git a/src/coreclr/vm/comutilnative.cpp b/src/coreclr/vm/comutilnative.cpp index 36852e1a965bbd..e8960757151e4a 100644 --- a/src/coreclr/vm/comutilnative.cpp +++ b/src/coreclr/vm/comutilnative.cpp @@ -987,7 +987,7 @@ FCIMPL1(INT64, GCInterface::GetTotalAllocatedBytes, CLR_BOOL precise) #else // As it could be noticed we read 64bit values that may be concurrently updated. // Such reads are not guaranteed to be atomic on 32bit so extra care should be taken. - uint64_t unused_bytes = FastInterlockCompareExchangeLong((LONG64*)& Thread::dead_threads_non_alloc_bytes, 0, 0); + uint64_t unused_bytes = InterlockedCompareExchange64((LONG64*)& Thread::dead_threads_non_alloc_bytes, 0, 0); #endif uint64_t allocated_bytes = GCHeapUtilities::GetGCHeap()->GetTotalAllocatedBytes() - unused_bytes; @@ -998,7 +998,7 @@ FCIMPL1(INT64, GCInterface::GetTotalAllocatedBytes, CLR_BOOL precise) uint64_t current_high = high_watermark; while (allocated_bytes > current_high) { - uint64_t orig = FastInterlockCompareExchangeLong((LONG64*)& high_watermark, allocated_bytes, current_high); + uint64_t orig = InterlockedCompareExchange64((LONG64*)& high_watermark, allocated_bytes, current_high); if (orig == current_high) return allocated_bytes; @@ -1402,7 +1402,7 @@ FCIMPL2(INT32,COMInterlocked::Exchange, INT32 *location, INT32 value) FCThrow(kNullReferenceException); } - return FastInterlockExchange((LONG *) location, value); + return InterlockedExchange((LONG *) location, value); } FCIMPLEND @@ -1414,7 +1414,7 @@ FCIMPL2_IV(INT64,COMInterlocked::Exchange64, INT64 *location, INT64 value) FCThrow(kNullReferenceException); } - return FastInterlockExchangeLong((INT64 *) location, value); + return InterlockedExchange64((INT64 *) location, value); } FCIMPLEND @@ -1426,7 +1426,7 @@ FCIMPL3(INT32, COMInterlocked::CompareExchange, INT32* location, INT32 value, IN FCThrow(kNullReferenceException); } - return FastInterlockCompareExchange((LONG*)location, value, comparand); + return InterlockedCompareExchange((LONG*)location, value, comparand); } FCIMPLEND @@ -1438,7 +1438,7 @@ FCIMPL3_IVV(INT64, COMInterlocked::CompareExchange64, INT64* location, INT64 val FCThrow(kNullReferenceException); } - return FastInterlockCompareExchangeLong((INT64*)location, value, comparand); + return InterlockedCompareExchange64((INT64*)location, value, comparand); } FCIMPLEND @@ -1450,7 +1450,7 @@ FCIMPL2_IV(float,COMInterlocked::ExchangeFloat, float *location, float value) FCThrow(kNullReferenceException); } - LONG ret = FastInterlockExchange((LONG *) location, *(LONG*)&value); + LONG ret = InterlockedExchange((LONG *) location, *(LONG*)&value); return *(float*)&ret; } FCIMPLEND @@ -1464,7 +1464,7 @@ FCIMPL2_IV(double,COMInterlocked::ExchangeDouble, double *location, double value } - INT64 ret = FastInterlockExchangeLong((INT64 *) location, *(INT64*)&value); + INT64 ret = InterlockedExchange64((INT64 *) location, *(INT64*)&value); return *(double*)&ret; } FCIMPLEND @@ -1477,7 +1477,7 @@ FCIMPL3_IVV(float,COMInterlocked::CompareExchangeFloat, float *location, float v FCThrow(kNullReferenceException); } - LONG ret = (LONG)FastInterlockCompareExchange((LONG*) location, *(LONG*)&value, *(LONG*)&comparand); + LONG ret = (LONG)InterlockedCompareExchange((LONG*) location, *(LONG*)&value, *(LONG*)&comparand); return *(float*)&ret; } FCIMPLEND @@ -1490,7 +1490,7 @@ FCIMPL3_IVV(double,COMInterlocked::CompareExchangeDouble, double *location, doub FCThrow(kNullReferenceException); } - INT64 ret = (INT64)FastInterlockCompareExchangeLong((INT64*) location, *(INT64*)&value, *(INT64*)&comparand); + INT64 ret = (INT64)InterlockedCompareExchange64((INT64*) location, *(INT64*)&value, *(INT64*)&comparand); return *(double*)&ret; } FCIMPLEND @@ -1503,7 +1503,7 @@ FCIMPL2(LPVOID,COMInterlocked::ExchangeObject, LPVOID*location, LPVOID value) FCThrow(kNullReferenceException); } - LPVOID ret = FastInterlockExchangePointer(location, value); + LPVOID ret = InterlockedExchangeT(location, value); #ifdef _DEBUG Thread::ObjectRefAssign((OBJECTREF *)location); #endif @@ -1521,7 +1521,7 @@ FCIMPL3(LPVOID,COMInterlocked::CompareExchangeObject, LPVOID *location, LPVOID v } // @todo: only set ref if is updated - LPVOID ret = FastInterlockCompareExchangePointer(location, value, comparand); + LPVOID ret = InterlockedCompareExchangeT(location, value, comparand); if (ret == comparand) { #ifdef _DEBUG Thread::ObjectRefAssign((OBJECTREF *)location); @@ -1540,7 +1540,7 @@ FCIMPL2(INT32,COMInterlocked::ExchangeAdd32, INT32 *location, INT32 value) FCThrow(kNullReferenceException); } - return FastInterlockExchangeAdd((LONG *) location, value); + return InterlockedExchangeAdd((LONG *) location, value); } FCIMPLEND @@ -1552,7 +1552,7 @@ FCIMPL2_IV(INT64,COMInterlocked::ExchangeAdd64, INT64 *location, INT64 value) FCThrow(kNullReferenceException); } - return FastInterlockExchangeAddLong((INT64 *) location, value); + return InterlockedExchangeAdd64((INT64 *) location, value); } FCIMPLEND diff --git a/src/coreclr/vm/corhost.cpp b/src/coreclr/vm/corhost.cpp index 68b26039c0543e..b0c57bf4b17064 100644 --- a/src/coreclr/vm/corhost.cpp +++ b/src/coreclr/vm/corhost.cpp @@ -90,7 +90,7 @@ STDMETHODIMP CorHost2::Start() else { // Increment the global (and dynamic) refCount... - FastInterlockIncrement(&m_RefCount); + InterlockedIncrement(&m_RefCount); // And set our flag that this host has invoked the Start... m_fStarted = TRUE; @@ -113,7 +113,7 @@ STDMETHODIMP CorHost2::Start() // So, if you want to do that, just make sure you are the first host to load the // specific version of CLR in memory AND start it. m_fFirstToLoadCLR = TRUE; - FastInterlockIncrement(&m_RefCount); + InterlockedIncrement(&m_RefCount); } } @@ -159,7 +159,7 @@ HRESULT CorHost2::Stop() break; } else - if (FastInterlockCompareExchange(&m_RefCount, refCount - 1, refCount) == refCount) + if (InterlockedCompareExchange(&m_RefCount, refCount - 1, refCount) == refCount) { // Indicate that we have got a Stop for a corresponding Start call from the // Host. Semantically, CoreCLR has stopped for them. diff --git a/src/coreclr/vm/crst.cpp b/src/coreclr/vm/crst.cpp index d617647f27233b..28136d8fdaad48 100644 --- a/src/coreclr/vm/crst.cpp +++ b/src/coreclr/vm/crst.cpp @@ -308,7 +308,7 @@ void CrstBase::Enter(INDEBUG(NoLevelCheckFlag noLevelCheckFlag/* = CRST_LEVEL_CH if (m_dwFlags & CRST_TAKEN_DURING_SHUTDOWN) { // increment the usage count of locks that can be taken during shutdown - FastInterlockIncrement(&g_ShutdownCrstUsageCount); + InterlockedIncrement(&g_ShutdownCrstUsageCount); } // If this is a debugger lock, bump up the "Can't-Stop" count. @@ -368,7 +368,7 @@ void CrstBase::Leave() { // decrement the usage count of locks that can be taken during shutdown _ASSERTE_MSG(g_ShutdownCrstUsageCount.Load() > 0, "Attempting to leave a lock that was never taken!"); - FastInterlockDecrement(&g_ShutdownCrstUsageCount); + InterlockedDecrement(&g_ShutdownCrstUsageCount); } } diff --git a/src/coreclr/vm/crst.h b/src/coreclr/vm/crst.h index a8f2065703d6e2..cdc5da78d9189f 100644 --- a/src/coreclr/vm/crst.h +++ b/src/coreclr/vm/crst.h @@ -240,11 +240,11 @@ friend class Crst; { LIMITED_METHOD_CONTRACT; if (bSet) - FastInterlockIncrement(&m_cannotLeave); + InterlockedIncrement(&m_cannotLeave); else { _ASSERTE(m_cannotLeave); - FastInterlockDecrement(&m_cannotLeave); + InterlockedDecrement(&m_cannotLeave); } }; //----------------------------------------------------------------- diff --git a/src/coreclr/vm/disassembler.cpp b/src/coreclr/vm/disassembler.cpp index 51c48a112655e9..52c8d6b04c844c 100644 --- a/src/coreclr/vm/disassembler.cpp +++ b/src/coreclr/vm/disassembler.cpp @@ -158,7 +158,7 @@ Disassembler::Disassembler() // Try to get an external disassembler that is already available for use before creating one ExternalDisassembler *externalDisassembler = - FastInterlockExchangePointer(&s_availableExternalDisassembler, static_cast(nullptr)); + InterlockedExchangeT(&s_availableExternalDisassembler, static_cast(nullptr)); if (externalDisassembler == nullptr) { #if USE_COREDISTOOLS_DISASSEMBLER @@ -186,7 +186,7 @@ Disassembler::~Disassembler() // Save the external disassembler for future use. We only save one instance, so delete a previously saved one. ExternalDisassembler *externalDisassemblerToDelete = - FastInterlockExchangePointer(&s_availableExternalDisassembler, m_externalDisassembler); + InterlockedExchangeT(&s_availableExternalDisassembler, m_externalDisassembler); if (externalDisassemblerToDelete == nullptr) { return; diff --git a/src/coreclr/vm/domainassembly.cpp b/src/coreclr/vm/domainassembly.cpp index 47c0fd53a74cb6..253ff2ee32a972 100644 --- a/src/coreclr/vm/domainassembly.cpp +++ b/src/coreclr/vm/domainassembly.cpp @@ -340,7 +340,7 @@ OBJECTREF DomainAssembly::GetExposedModuleObject() // Atomically create a handle LOADERHANDLE handle = pLoaderAllocator->AllocateHandle(NULL); - FastInterlockCompareExchangePointer(&m_hExposedModuleObject, handle, static_cast(NULL)); + InterlockedCompareExchangeT(&m_hExposedModuleObject, handle, static_cast(NULL)); } if (pLoaderAllocator->GetHandleValue(m_hExposedModuleObject) == NULL) @@ -650,7 +650,7 @@ OBJECTREF DomainAssembly::GetExposedAssemblyObject() LOADERHANDLE handle = pLoaderAllocator->AllocateHandle(NULL); - FastInterlockCompareExchangePointer(&m_hExposedAssemblyObject, handle, static_cast(NULL)); + InterlockedCompareExchangeT(&m_hExposedAssemblyObject, handle, static_cast(NULL)); } if (pLoaderAllocator->GetHandleValue(m_hExposedAssemblyObject) == NULL) diff --git a/src/coreclr/vm/dynamicmethod.cpp b/src/coreclr/vm/dynamicmethod.cpp index f6c3b5a52d62fb..badc16f75df418 100644 --- a/src/coreclr/vm/dynamicmethod.cpp +++ b/src/coreclr/vm/dynamicmethod.cpp @@ -88,7 +88,7 @@ void DynamicMethodTable::CreateDynamicMethodTable(DynamicMethodTable **ppLocatio if (*ppLocation) RETURN; - if (FastInterlockCompareExchangePointer(ppLocation, pDynMT, NULL) != NULL) + if (InterlockedCompareExchangeT(ppLocation, pDynMT, NULL) != NULL) { LOG((LF_BCL, LL_INFO100, "Level2 - Another thread got here first - deleting DynamicMethodTable {0x%p}...\n", pDynMT)); RETURN; diff --git a/src/coreclr/vm/eehash.inl b/src/coreclr/vm/eehash.inl index 477df0dc1ae4ac..9fc5406e7eb889 100644 --- a/src/coreclr/vm/eehash.inl +++ b/src/coreclr/vm/eehash.inl @@ -749,7 +749,7 @@ BOOL EEHashTableBase::GrowHashTable() // we are doing this, as there can be concurrent readers! Note that // it is OK if the concurrent reader misses out on a match, though - // they will have to acquire the lock on a miss & try again. - FastInterlockExchange( (LONG *) &m_bGrowing, 1); + InterlockedExchange( (LONG *) &m_bGrowing, 1); for (DWORD i = 0; i < m_pVolatileBucketTable->m_dwNumBuckets; i++) { EEHashEntry_t * pEntry = m_pVolatileBucketTable->m_pBuckets[i]; @@ -800,7 +800,7 @@ BOOL EEHashTableBase::GrowHashTable() // m_pVolatileBucketTable = pNewBucketTable; - FastInterlockExchange( (LONG *) &m_bGrowing, 0); + InterlockedExchange( (LONG *) &m_bGrowing, 0); return TRUE; } diff --git a/src/coreclr/vm/eepolicy.cpp b/src/coreclr/vm/eepolicy.cpp index a1c909128adda2..862c3186261800 100644 --- a/src/coreclr/vm/eepolicy.cpp +++ b/src/coreclr/vm/eepolicy.cpp @@ -41,7 +41,7 @@ void SafeExitProcess(UINT exitCode, ShutdownCompleteAction sca = SCA_ExitProcess // other DLLs call Release() on us in their detach [dangerous!], etc. GCX_PREEMP_NO_DTOR(); - FastInterlockExchange((LONG*)&g_fForbidEnterEE, TRUE); + InterlockedExchange((LONG*)&g_fForbidEnterEE, TRUE); // Note that for free and retail builds StressLog must also be enabled if (g_pConfig && g_pConfig->StressLog()) diff --git a/src/coreclr/vm/encee.cpp b/src/coreclr/vm/encee.cpp index 301101d7a1f510..e59a217dfe4420 100644 --- a/src/coreclr/vm/encee.cpp +++ b/src/coreclr/vm/encee.cpp @@ -1358,7 +1358,7 @@ PTR_CBYTE EnCSyncBlockInfo::ResolveOrAllocateField(OBJECTREF thisPointer, EnCFie // put at front of list so the list is in order of most recently added pEntry->m_pNext = m_pList; - if (FastInterlockCompareExchangePointer(&m_pList, pEntry, pEntry->m_pNext) == pEntry->m_pNext) + if (InterlockedCompareExchangeT(&m_pList, pEntry, pEntry->m_pNext) == pEntry->m_pNext) break; // There was a race and another thread modified the list here, so we need to try again diff --git a/src/coreclr/vm/eventreporter.cpp b/src/coreclr/vm/eventreporter.cpp index 74a14b9aa1c02a..56d6519d5ca221 100644 --- a/src/coreclr/vm/eventreporter.cpp +++ b/src/coreclr/vm/eventreporter.cpp @@ -478,7 +478,7 @@ BOOL ShouldLogInEventLog() } static LONG fOnce = 0; - if (fOnce == 1 || FastInterlockExchange(&fOnce, 1) == 1) + if (fOnce == 1 || InterlockedExchange(&fOnce, 1) == 1) { return FALSE; } diff --git a/src/coreclr/vm/excep.cpp b/src/coreclr/vm/excep.cpp index e375130a04d0be..23d5e3b8f6f71a 100644 --- a/src/coreclr/vm/excep.cpp +++ b/src/coreclr/vm/excep.cpp @@ -3807,7 +3807,7 @@ LONG WatsonLastChance( // EXCEPTION_CONTINUE_SEARCH, _CONTINUE_ else { BOOL fWatsonAlreadyLaunched = FALSE; - if (FastInterlockCompareExchange(&g_watsonAlreadyLaunched, 1, 0) != 0) + if (InterlockedCompareExchange(&g_watsonAlreadyLaunched, 1, 0) != 0) { fWatsonAlreadyLaunched = TRUE; } diff --git a/src/coreclr/vm/exceptionhandling.cpp b/src/coreclr/vm/exceptionhandling.cpp index e70a340b7f99b9..8a4d6ee16c6c59 100644 --- a/src/coreclr/vm/exceptionhandling.cpp +++ b/src/coreclr/vm/exceptionhandling.cpp @@ -905,7 +905,7 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord // We should be in cooperative mode if we are going to handle the SO. // We track SO state for the thread. EEPolicy::HandleStackOverflow(); - FastInterlockAnd (&pThread->m_fPreemptiveGCDisabled, 0); + InterlockedAnd((LONG*)&pThread->m_fPreemptiveGCDisabled, 0); return ExceptionContinueSearch; } } @@ -5485,7 +5485,7 @@ void TrackerAllocator::FreeTrackerMemory(ExceptionTracker* pTracker) // mark this entry as free EH_LOG((LL_INFO100, "TrackerAllocator: freeing tracker 0x%p, thread = 0x%p\n", pTracker, pTracker->m_pThread)); CONSISTENCY_CHECK(pTracker->IsValid()); - FastInterlockExchangePointer(&(pTracker->m_pThread), NULL); + InterlockedExchangeT(&(pTracker->m_pThread), NULL); } #ifndef TARGET_UNIX @@ -5900,7 +5900,7 @@ UMThunkUnwindFrameChainHandler(IN PEXCEPTION_RECORD pExceptionRecord if (fIsSO) { // We don't have stack to do full-version EnablePreemptiveGC. - FastInterlockAnd (&pThread->m_fPreemptiveGCDisabled, 0); + InterlockedAnd((LONG*)&pThread->m_fPreemptiveGCDisabled, 0); } else { @@ -5985,7 +5985,7 @@ CallDescrWorkerUnwindFrameChainHandler(IN PEXCEPTION_RECORD pExceptionReco CleanUpForSecondPass(pThread, true, (void*)MemoryStackFp, (void*)MemoryStackFp); } - FastInterlockAnd (&pThread->m_fPreemptiveGCDisabled, 0); + InterlockedAnd((LONG*)&pThread->m_fPreemptiveGCDisabled, 0); // We'll let the SO infrastructure handle this exception... at that point, we // know that we'll have enough stack to do it. return ExceptionContinueSearch; diff --git a/src/coreclr/vm/finalizerthread.cpp b/src/coreclr/vm/finalizerthread.cpp index e8370315e66651..3efb36f645d51f 100644 --- a/src/coreclr/vm/finalizerthread.cpp +++ b/src/coreclr/vm/finalizerthread.cpp @@ -473,7 +473,7 @@ void FinalizerThread::SignalFinalizationDone(BOOL fFinalizer) if (fFinalizer) { - FastInterlockAnd((DWORD*)&g_FinalizerWaiterStatus, ~FWS_WaitInterrupt); + InterlockedAnd((LONG*)&g_FinalizerWaiterStatus, ~FWS_WaitInterrupt); } hEventFinalizerDone->Set(); } diff --git a/src/coreclr/vm/gccover.cpp b/src/coreclr/vm/gccover.cpp index 591c61190cd2c5..3f473c5a34599f 100644 --- a/src/coreclr/vm/gccover.cpp +++ b/src/coreclr/vm/gccover.cpp @@ -1494,7 +1494,7 @@ void DoGcStress (PCONTEXT regs, NativeCodeVersion nativeCodeVersion) bool bShouldUpdateProlog = true; if (gcCover->doingEpilogChecks) { if (offset == 0) { - if ((gcCover->callerThread == 0) && (FastInterlockCompareExchangePointer(&gcCover->callerThread, pThread, 0) == 0)) { + if ((gcCover->callerThread == 0) && (InterlockedCompareExchangeT(&gcCover->callerThread, pThread, 0) == 0)) { gcCover->callerRegs = *regs; gcCover->gcCount = GCHeapUtilities::GetGCHeap()->GetGcCount(); bShouldUpdateProlog = false; diff --git a/src/coreclr/vm/gchelpers.cpp b/src/coreclr/vm/gchelpers.cpp index 03f930498cb185..0b3d6ca29d5239 100644 --- a/src/coreclr/vm/gchelpers.cpp +++ b/src/coreclr/vm/gchelpers.cpp @@ -86,7 +86,7 @@ class GlobalAllocLock { } CONTRACTL_END; DWORD spinCount = 0; - while(FastInterlockExchange(&m_lock, 0) != -1) + while(InterlockedExchange(&m_lock, 0) != -1) { GCX_PREEMP(); __SwitchToThread(0, spinCount++); diff --git a/src/coreclr/vm/genericdict.cpp b/src/coreclr/vm/genericdict.cpp index 56a40b0495972a..1862e967990567 100644 --- a/src/coreclr/vm/genericdict.cpp +++ b/src/coreclr/vm/genericdict.cpp @@ -530,7 +530,7 @@ Dictionary* Dictionary::GetMethodDictionaryWithSizeCheck(MethodDesc* pMD, ULONG *pNewDictionary->GetBackPointerSlot(numGenericArgs) = pDictionary; // Publish the new dictionary slots to the type. - FastInterlockExchangePointer(&pIMD->m_pPerInstInfo, pNewDictionary); + InterlockedExchangeT(&pIMD->m_pPerInstInfo, pNewDictionary); pDictionary = pNewDictionary; } @@ -590,7 +590,7 @@ Dictionary* Dictionary::GetTypeDictionaryWithSizeCheck(MethodTable* pMT, ULONG s // Publish the new dictionary slots to the type. ULONG dictionaryIndex = pMT->GetNumDicts() - 1; Dictionary** pPerInstInfo = pMT->GetPerInstInfo(); - FastInterlockExchangePointer(pPerInstInfo + dictionaryIndex, pNewDictionary); + InterlockedExchangeT(pPerInstInfo + dictionaryIndex, pNewDictionary); pDictionary = pNewDictionary; } diff --git a/src/coreclr/vm/hash.cpp b/src/coreclr/vm/hash.cpp index 676a8789523931..87d4913b89aa0e 100644 --- a/src/coreclr/vm/hash.cpp +++ b/src/coreclr/vm/hash.cpp @@ -441,13 +441,13 @@ void HashMap::ProfileLookup(UPTR ntry, UPTR retValue) #ifndef DACCESS_COMPILE #ifdef HASHTABLE_PROFILE if (ntry < HASHTABLE_LOOKUP_PROBES_DATA - 2) - FastInterlockIncrement(&m_rgLookupProbes[ntry]); + InterlockedIncrement(&m_rgLookupProbes[ntry]); else - FastInterlockIncrement(&m_rgLookupProbes[HASHTABLE_LOOKUP_PROBES_DATA - 2]); + InterlockedIncrement(&m_rgLookupProbes[HASHTABLE_LOOKUP_PROBES_DATA - 2]); if (retValue == NULL) { // failure probes - FastInterlockIncrement(&m_rgLookupProbes[HASHTABLE_LOOKUP_PROBES_DATA - 1]); + InterlockedIncrement(&m_rgLookupProbes[HASHTABLE_LOOKUP_PROBES_DATA - 1]); // the following code is usually executed // only for special case of lookup done before insert // check hash.h SyncHash::InsertValue diff --git a/src/coreclr/vm/hosting.cpp b/src/coreclr/vm/hosting.cpp index 3379d2385bea0d..56ae004c0f10c3 100644 --- a/src/coreclr/vm/hosting.cpp +++ b/src/coreclr/vm/hosting.cpp @@ -207,7 +207,7 @@ BOOL ClrVirtualProtect(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect, PDWO BYTE* pEndOfUEFSectionBoundary = pAddressOfFollowingSection - 1; // Set the end of UEF section boundary - FastInterlockExchangePointer(s_pEndOfUEFSectionBoundary.GetPointer(), pEndOfUEFSectionBoundary); + InterlockedExchangeT(s_pEndOfUEFSectionBoundary.GetPointer(), pEndOfUEFSectionBoundary); } else { diff --git a/src/coreclr/vm/i386/excepx86.cpp b/src/coreclr/vm/i386/excepx86.cpp index fa928f22c4999f..731829d3c012c3 100644 --- a/src/coreclr/vm/i386/excepx86.cpp +++ b/src/coreclr/vm/i386/excepx86.cpp @@ -1656,7 +1656,7 @@ EXCEPTION_HANDLER_IMPL(COMPlusFrameHandler) // Switch to preemp mode since we are returning back to the OS. // We will do the quick switch since we are short of stack - FastInterlockAnd (&pThread->m_fPreemptiveGCDisabled, 0); + InterlockedAnd((LONG*)&pThread->m_fPreemptiveGCDisabled, 0); return ExceptionContinueSearch; } @@ -1708,7 +1708,7 @@ EXCEPTION_HANDLER_IMPL(COMPlusFrameHandler) // Switch to preemp mode since we are returning back to the OS. // We will do the quick switch since we are short of stack - FastInterlockAnd(&pThread->m_fPreemptiveGCDisabled, 0); + InterlockedAnd((LONG*)&pThread->m_fPreemptiveGCDisabled, 0); return ExceptionContinueSearch; } diff --git a/src/coreclr/vm/i386/stublinkerx86.cpp b/src/coreclr/vm/i386/stublinkerx86.cpp index 5126d2cc32685c..93f77dc7deee53 100644 --- a/src/coreclr/vm/i386/stublinkerx86.cpp +++ b/src/coreclr/vm/i386/stublinkerx86.cpp @@ -5019,7 +5019,7 @@ BOOL ThisPtrRetBufPrecode::SetTargetInterlocked(TADDR target, TADDR expected) _ASSERTE(IS_ALIGNED(&m_rel32, sizeof(INT32))); ExecutableWriterHolder rel32WriterHolder(&m_rel32, sizeof(INT32)); - FastInterlockExchange((LONG*)rel32WriterHolder.GetRW(), (LONG)newRel32); + InterlockedExchange((LONG*)rel32WriterHolder.GetRW(), (LONG)newRel32); return TRUE; } diff --git a/src/coreclr/vm/ilstubresolver.cpp b/src/coreclr/vm/ilstubresolver.cpp index 2721afdf2bf30a..1ae8614e342df1 100644 --- a/src/coreclr/vm/ilstubresolver.cpp +++ b/src/coreclr/vm/ilstubresolver.cpp @@ -311,7 +311,7 @@ ILStubResolver::AllocGeneratedIL( #ifdef _DEBUG LPVOID pPrevCompileTimeState = #endif // _DEBUG - FastInterlockExchangePointer(&m_pCompileTimeState, pNewCompileTimeState.GetValue()); + InterlockedExchangeT(&m_pCompileTimeState, pNewCompileTimeState.GetValue()); CONSISTENCY_CHECK(ILNotYetGenerated == (UINT_PTR)pPrevCompileTimeState); pNewLocalSig.SuppressRelease(); @@ -338,7 +338,7 @@ ILStubResolver::AllocGeneratedIL( #ifdef _DEBUG LPVOID pPrevCompileTimeState = #endif // _DEBUG - FastInterlockExchangePointer(&m_pCompileTimeState, (CompileTimeState*)pNewCompileTimeState); + InterlockedExchangeT(&m_pCompileTimeState, (CompileTimeState*)pNewCompileTimeState); CONSISTENCY_CHECK(ILNotYetGenerated == (UINT_PTR)pPrevCompileTimeState); pNewLocalSig.SuppressRelease(); @@ -458,7 +458,7 @@ ILStubResolver::ClearCompileTimeState(CompileTimeStatePtrSpecialValues newState) delete m_pCompileTimeState; - FastInterlockExchangePointer(&m_pCompileTimeState, dac_cast((TADDR)newState)); + InterlockedExchangeT(&m_pCompileTimeState, dac_cast((TADDR)newState)); } // ILStubResolver::ClearCompileTimeState //--------------------------------------------------------------------------------------- diff --git a/src/coreclr/vm/instmethhash.h b/src/coreclr/vm/instmethhash.h index 3b44c3781470bf..153bbe4740846b 100644 --- a/src/coreclr/vm/instmethhash.h +++ b/src/coreclr/vm/instmethhash.h @@ -81,8 +81,8 @@ class InstMethodHashTable : public DacEnumerableHashTable= 0 && msgSendFunction < ARRAY_SIZE(s_msgSendOverrides)); - success = FastInterlockCompareExchangePointer(&s_msgSendOverrides[msgSendFunction], fptr, NULL) == NULL; + success = InterlockedCompareExchangeT(&s_msgSendOverrides[msgSendFunction], fptr, NULL) == NULL; // Set P/Invoke override callback if we haven't already - if (success && FALSE == FastInterlockCompareExchange((LONG*)&s_msgSendOverridden, TRUE, FALSE)) + if (success && FALSE == InterlockedCompareExchange((LONG*)&s_msgSendOverridden, TRUE, FALSE)) PInvokeOverride::SetPInvokeOverride(&MessageSendPInvokeOverride, PInvokeOverride::Source::ObjectiveCInterop); END_QCALL; diff --git a/src/coreclr/vm/jithelpers.cpp b/src/coreclr/vm/jithelpers.cpp index 5dfb7de70ba29e..e1802b64792b67 100644 --- a/src/coreclr/vm/jithelpers.cpp +++ b/src/coreclr/vm/jithelpers.cpp @@ -3146,7 +3146,7 @@ CORINFO_GENERIC_HANDLE JIT_GenericHandleWorker(MethodDesc * pMD, MethodTable * p if (pMTDictionary != pDeclaringMTDictionary) { TypeHandle** pPerInstInfo = (TypeHandle**)pMT->GetPerInstInfo(); - FastInterlockExchangePointer(pPerInstInfo + dictionaryIndex, (TypeHandle*)pDeclaringMTDictionary); + InterlockedExchangeT(pPerInstInfo + dictionaryIndex, (TypeHandle*)pDeclaringMTDictionary); } } @@ -4753,7 +4753,7 @@ HCIMPL0(VOID, JIT_StressGC) BYTE* retInstrs = ((BYTE*) *__ms->pRetAddr()) - 4; _ASSERTE(retInstrs[-1] == 0xE8); // it is a call instruction // Wack it to point to the JITStressGCNop instead - FastInterlockExchange((LONG*) retInstrs), (LONG) JIT_StressGC_NOP); + InterlockedExchange((LONG*) retInstrs), (LONG) JIT_StressGC_NOP); #endif // _X86 HELPER_METHOD_FRAME_END(); diff --git a/src/coreclr/vm/listlock.h b/src/coreclr/vm/listlock.h index ec92028133b48b..8ad1fe4c967a5b 100644 --- a/src/coreclr/vm/listlock.h +++ b/src/coreclr/vm/listlock.h @@ -153,7 +153,7 @@ class ListLockEntryBase } CONTRACTL_END; - FastInterlockIncrement((LONG*)&m_dwRefCount); + InterlockedIncrement((LONG*)&m_dwRefCount); } void Release() @@ -169,7 +169,7 @@ class ListLockEntryBase ListLockHolder lock(m_pList); - if (FastInterlockDecrement((LONG*)&m_dwRefCount) == 0) + if (InterlockedDecrement((LONG*)&m_dwRefCount) == 0) { // Remove from list m_pList->Unlink(this); diff --git a/src/coreclr/vm/loaderallocator.cpp b/src/coreclr/vm/loaderallocator.cpp index aba0a96586178f..43311f87c97eb5 100644 --- a/src/coreclr/vm/loaderallocator.cpp +++ b/src/coreclr/vm/loaderallocator.cpp @@ -115,7 +115,7 @@ void LoaderAllocator::AddReference() CONTRACTL_END; _ASSERTE((m_cReferences > (UINT32)0) && (m_cReferences != (UINT32)-1)); - FastInterlockIncrement((LONG *)&m_cReferences); + InterlockedIncrement((LONG *)&m_cReferences); } #endif //!DACCESS_COMPILE @@ -146,7 +146,7 @@ BOOL LoaderAllocator::AddReferenceIfAlive() return FALSE; } - UINT32 cOriginalReferences = FastInterlockCompareExchange( + UINT32 cOriginalReferences = InterlockedCompareExchange( (LONG *)&m_cReferences, cReferencesLocalSnapshot + 1, cReferencesLocalSnapshot); @@ -181,7 +181,7 @@ BOOL LoaderAllocator::Release() #ifndef DACCESS_COMPILE _ASSERTE((m_cReferences > (UINT32)0) && (m_cReferences != (UINT32)-1)); - LONG cNewReferences = FastInterlockDecrement((LONG *)&m_cReferences); + LONG cNewReferences = InterlockedDecrement((LONG *)&m_cReferences); return (cNewReferences == 0); #else //DACCESS_COMPILE @@ -1512,7 +1512,7 @@ DispatchToken LoaderAllocator::GetDispatchToken( SimpleWriteLockHolder lock(pFatTokenSetLock); NewHolder pFatTokenSet = new FatTokenSet; - if (FastInterlockCompareExchangePointer( + if (InterlockedCompareExchangeT( &m_pFatTokenSetLock, pFatTokenSetLock.GetValue(), NULL) != NULL) { // Someone beat us to it lock.Release(); @@ -2058,7 +2058,7 @@ UMEntryThunkCache *LoaderAllocator::GetUMEntryThunkCache() { UMEntryThunkCache *pUMEntryThunkCache = new UMEntryThunkCache(GetAppDomain()); - if (FastInterlockCompareExchangePointer(&m_pUMEntryThunkCache, pUMEntryThunkCache, NULL) != NULL) + if (InterlockedCompareExchangeT(&m_pUMEntryThunkCache, pUMEntryThunkCache, NULL) != NULL) { // some thread swooped in and set the field delete pUMEntryThunkCache; @@ -2170,7 +2170,7 @@ PTR_OnStackReplacementManager LoaderAllocator::GetOnStackReplacementManager() { OnStackReplacementManager * newManager = new OnStackReplacementManager(this); - if (FastInterlockCompareExchangePointer(&m_onStackReplacementManager, newManager, NULL) != NULL) + if (InterlockedCompareExchangeT(&m_onStackReplacementManager, newManager, NULL) != NULL) { // some thread swooped in and set the field delete newManager; diff --git a/src/coreclr/vm/method.cpp b/src/coreclr/vm/method.cpp index 8b7f075c1b50b7..aab5409c8f2606 100644 --- a/src/coreclr/vm/method.cpp +++ b/src/coreclr/vm/method.cpp @@ -844,7 +844,7 @@ WORD MethodDesc::InterlockedUpdateFlags(WORD wMask, BOOL fSet) // is a word and we only have interlock operations over dwords. So we round down the flags field address to the nearest aligned // dword (along with the intended bitfield mask). Note that we make the assumption that the flags word is aligned itself, so we // only have two possibilites: the field already lies on a dword boundary or it's precisely one word out. - DWORD* pdwFlags = (DWORD*)((ULONG_PTR)&m_wFlags - (offsetof(MethodDesc, m_wFlags) & 0x3)); + LONG* pdwFlags = (LONG*)((ULONG_PTR)&m_wFlags - (offsetof(MethodDesc, m_wFlags) & 0x3)); #ifdef _PREFAST_ #pragma warning(push) @@ -864,9 +864,9 @@ WORD MethodDesc::InterlockedUpdateFlags(WORD wMask, BOOL fSet) #endif if (fSet) - FastInterlockOr(pdwFlags, dwMask); + InterlockedOr(pdwFlags, dwMask); else - FastInterlockAnd(pdwFlags, ~dwMask); + InterlockedAnd(pdwFlags, ~dwMask); return wOldState; } @@ -882,7 +882,7 @@ WORD MethodDesc::InterlockedUpdateFlags3(WORD wMask, BOOL fSet) // is a word and we only have interlock operations over dwords. So we round down the flags field address to the nearest aligned // dword (along with the intended bitfield mask). Note that we make the assumption that the flags word is aligned itself, so we // only have two possibilites: the field already lies on a dword boundary or it's precisely one word out. - DWORD* pdwFlags = (DWORD*)((ULONG_PTR)&m_wFlags3AndTokenRemainder - (offsetof(MethodDesc, m_wFlags3AndTokenRemainder) & 0x3)); + LONG* pdwFlags = (LONG*)((ULONG_PTR)&m_wFlags3AndTokenRemainder - (offsetof(MethodDesc, m_wFlags3AndTokenRemainder) & 0x3)); #ifdef _PREFAST_ #pragma warning(push) @@ -902,9 +902,9 @@ WORD MethodDesc::InterlockedUpdateFlags3(WORD wMask, BOOL fSet) #endif if (fSet) - FastInterlockOr(pdwFlags, dwMask); + InterlockedOr(pdwFlags, dwMask); else - FastInterlockAnd(pdwFlags, ~dwMask); + InterlockedAnd(pdwFlags, ~dwMask); return wOldState; } @@ -2957,19 +2957,19 @@ void MethodDesc::InterlockedUpdateFlags2(BYTE bMask, BOOL fSet) { WRAPPER_NO_CONTRACT; - ULONG* pLong = (ULONG*)(&m_bFlags2 - 3); + LONG* pLong = (LONG*)(&m_bFlags2 - 3); static_assert_no_msg(offsetof(MethodDesc, m_bFlags2) % sizeof(LONG) == 3); #if BIGENDIAN if (fSet) - FastInterlockOr(pLong, (ULONG)bMask); + InterlockedOr(pLong, (ULONG)bMask); else - FastInterlockAnd(pLong, ~(ULONG)bMask); + InterlockedAnd(pLong, ~(ULONG)bMask); #else // !BIGENDIAN if (fSet) - FastInterlockOr(pLong, (ULONG)bMask << (3 * 8)); + InterlockedOr(pLong, (LONG)bMask << (3 * 8)); else - FastInterlockAnd(pLong, ~((ULONG)bMask << (3 * 8))); + InterlockedAnd(pLong, ~((LONG)bMask << (3 * 8))); #endif // !BIGENDIAN } @@ -3005,7 +3005,7 @@ Precode* MethodDesc::GetOrCreatePrecode() AllocMemTracker amt; Precode* pPrecode = Precode::Allocate(requiredType, this, GetLoaderAllocator(), &amt); - if (FastInterlockCompareExchangePointer(pSlot, pPrecode->GetEntryPoint(), tempEntry) == tempEntry) + if (InterlockedCompareExchangeT(pSlot, pPrecode->GetEntryPoint(), tempEntry) == tempEntry) amt.SuppressRelease(); } @@ -3296,7 +3296,7 @@ BOOL MethodDesc::SetNativeCodeInterlocked(PCODE addr, PCODE pExpected /*=NULL*/) expected = *pSlot; - return FastInterlockCompareExchangePointer(reinterpret_cast(pSlot), + return InterlockedCompareExchangeT(reinterpret_cast(pSlot), (TADDR&)addr, (TADDR&)expected) == (TADDR&)expected; } @@ -3333,7 +3333,7 @@ BOOL MethodDesc::SetStableEntryPointInterlocked(PCODE addr) PCODE pExpected = GetTemporaryEntryPoint(); PTR_PCODE pSlot = GetAddrOfSlot(); - BOOL fResult = FastInterlockCompareExchangePointer(pSlot, addr, pExpected) == pExpected; + BOOL fResult = InterlockedCompareExchangeT(pSlot, addr, pExpected) == pExpected; InterlockedUpdateFlags2(enum_flag2_HasStableEntryPoint, TRUE); @@ -3419,7 +3419,7 @@ void NDirectMethodDesc::InterlockedSetNDirectFlags(WORD wFlags) ((WORD*)&dwMask)[0] |= wFlags; // Now, slam all 32 bits atomically. - FastInterlockOr((DWORD*)pFlags, dwMask); + InterlockedOr((LONG*)pFlags, dwMask); } @@ -4020,7 +4020,7 @@ void ComPlusCallMethodDesc::InitRetThunk() LPVOID pRetThunk = ComPlusCall::GetRetThunk(numStackBytes); - FastInterlockCompareExchangePointer(&m_pComPlusCallInfo->m_pRetThunk, pRetThunk, NULL); + InterlockedCompareExchangeT(&m_pComPlusCallInfo->m_pRetThunk, pRetThunk, NULL); #endif // TARGET_X86 } #endif //!DACCESS_COMPILE diff --git a/src/coreclr/vm/method.hpp b/src/coreclr/vm/method.hpp index bc58090dd587d7..04f655c3c8316a 100644 --- a/src/coreclr/vm/method.hpp +++ b/src/coreclr/vm/method.hpp @@ -3239,7 +3239,7 @@ class ComPlusCallMethodDesc : public MethodDesc { LIMITED_METHOD_CONTRACT; - FastInterlockOr(reinterpret_cast(&m_pComPlusCallInfo->m_flags), newFlags); + InterlockedOr((LONG*)&m_pComPlusCallInfo->m_flags, newFlags); } #ifdef TARGET_X86 diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index 013b201f653d9b..b8a234966e341f 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -552,7 +552,7 @@ void MethodTable::SetIsRestored() PRECONDITION(!IsFullyLoaded()); - FastInterlockAnd(&GetWriteableDataForWrite()->m_dwFlags, ~MethodTableWriteableData::enum_flag_Unrestored); + InterlockedAnd((LONG*)&GetWriteableDataForWrite()->m_dwFlags, ~MethodTableWriteableData::enum_flag_Unrestored); #ifndef DACCESS_COMPILE if (ETW_PROVIDER_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER)) @@ -3952,7 +3952,7 @@ void CallFinalizerOnThreadObject(Object *obj) refThis->ClearInternal(); } - FastInterlockOr ((ULONG *)&thread->m_State, Thread::TS_Finalized); + thread->SetThreadState(Thread::TS_Finalized); Thread::SetCleanupNeededForFinalizedThread(); } } @@ -4099,7 +4099,7 @@ OBJECTREF MethodTable::GetManagedClassObject() // Only the winner can set m_ExposedClassObject from NULL. LOADERHANDLE exposedClassObjectHandle = pLoaderAllocator->AllocateHandle(refClass); - if (FastInterlockCompareExchangePointer(&GetWriteableDataForWrite()->m_hExposedClassObject, exposedClassObjectHandle, static_cast(NULL))) + if (InterlockedCompareExchangeT(&GetWriteableDataForWrite()->m_hExposedClassObject, exposedClassObjectHandle, static_cast(NULL))) { pLoaderAllocator->FreeHandle(exposedClassObjectHandle); } diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index 4b1d4cbd6e6979..92d35b1273651f 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -886,7 +886,7 @@ class MethodTable PRECONDITION(!HasApproxParent()); PRECONDITION(IsRestored_NoLogging()); - FastInterlockAnd(&GetWriteableDataForWrite()->m_dwFlags, ~MethodTableWriteableData::enum_flag_IsNotFullyLoaded); + InterlockedAnd((LONG*)&GetWriteableDataForWrite()->m_dwFlags, ~MethodTableWriteableData::enum_flag_IsNotFullyLoaded); } // Equivalent to GetLoadLevel() == CLASS_LOADED @@ -911,7 +911,7 @@ class MethodTable if (canCompare) { // Set checked and canCompare flags in one interlocked operation. - FastInterlockOr(&GetWriteableDataForWrite_NoLogging()->m_dwFlags, + InterlockedOr((LONG*)&GetWriteableDataForWrite_NoLogging()->m_dwFlags, MethodTableWriteableData::enum_flag_HasCheckedCanCompareBitsOrUseFastGetHashCode | MethodTableWriteableData::enum_flag_CanCompareBitsOrUseFastGetHashCode); } else @@ -929,7 +929,7 @@ class MethodTable inline void SetHasCheckedCanCompareBitsOrUseFastGetHashCode() { WRAPPER_NO_CONTRACT; - FastInterlockOr(&GetWriteableDataForWrite_NoLogging()->m_dwFlags, MethodTableWriteableData::enum_flag_HasCheckedCanCompareBitsOrUseFastGetHashCode); + InterlockedOr((LONG*)&GetWriteableDataForWrite_NoLogging()->m_dwFlags, MethodTableWriteableData::enum_flag_HasCheckedCanCompareBitsOrUseFastGetHashCode); } inline void SetIsDependenciesLoaded() @@ -945,7 +945,7 @@ class MethodTable PRECONDITION(!HasApproxParent()); PRECONDITION(IsRestored_NoLogging()); - FastInterlockOr(&GetWriteableDataForWrite()->m_dwFlags, MethodTableWriteableData::enum_flag_DependenciesLoaded); + InterlockedOr((LONG*)&GetWriteableDataForWrite()->m_dwFlags, MethodTableWriteableData::enum_flag_DependenciesLoaded); } inline ClassLoadLevel GetLoadLevel() @@ -1747,7 +1747,7 @@ class MethodTable inline void SetHasExactParent() { WRAPPER_NO_CONTRACT; - FastInterlockAnd(&(GetWriteableDataForWrite()->m_dwFlags), ~MethodTableWriteableData::enum_flag_HasApproxParent); + InterlockedAnd((LONG*)&GetWriteableDataForWrite()->m_dwFlags, ~MethodTableWriteableData::enum_flag_HasApproxParent); } diff --git a/src/coreclr/vm/mngstdinterfaces.h b/src/coreclr/vm/mngstdinterfaces.h index ba058946aad433..8c2d251dd1b758 100644 --- a/src/coreclr/vm/mngstdinterfaces.h +++ b/src/coreclr/vm/mngstdinterfaces.h @@ -60,7 +60,7 @@ class MngStdInterfaceMap if (m_pMngStdItfMap == NULL) { MngStdInterfaceMap *tmp = new MngStdInterfaceMap; - if (FastInterlockCompareExchangePointer(&m_pMngStdItfMap, tmp, NULL) != NULL) { + if (InterlockedCompareExchangeT(&m_pMngStdItfMap, tmp, NULL) != NULL) { tmp->m_TypeNameToNativeIIDMap.ClearHashTable(); delete tmp; } diff --git a/src/coreclr/vm/peassembly.cpp b/src/coreclr/vm/peassembly.cpp index 95ceb1564a19b1..4b1719f032a147 100644 --- a/src/coreclr/vm/peassembly.cpp +++ b/src/coreclr/vm/peassembly.cpp @@ -307,7 +307,7 @@ void PEAssembly::OpenImporter() (void **)&pIMDImport)); // Atomically swap it into the field (release it if we lose the race) - if (FastInterlockCompareExchangePointer(&m_pImporter, pIMDImport, NULL) != NULL) + if (InterlockedCompareExchangeT(&m_pImporter, pIMDImport, NULL) != NULL) pIMDImport->Release(); } @@ -362,7 +362,7 @@ void PEAssembly::ConvertMDInternalToReadWrite() // Swap the pointers in a thread safe manner. If the contents of *ppImport // equals pOld then no other thread got here first, and the old contents are // replaced with pNew. The old contents are returned. - if (FastInterlockCompareExchangePointer(&m_pMDImport, pNew, pOld) == pOld) + if (InterlockedCompareExchangeT(&m_pMDImport, pNew, pOld) == pOld) { //if the debugger queries, it will now see that we have RW metadata m_MDImportIsRW_Debugger_Use_Only = TRUE; @@ -428,7 +428,7 @@ void PEAssembly::OpenEmitter() (void **)&pIMDEmit)); // Atomically swap it into the field (release it if we lose the race) - if (FastInterlockCompareExchangePointer(&m_pEmitter, pIMDEmit, NULL) != NULL) + if (InterlockedCompareExchangeT(&m_pEmitter, pIMDEmit, NULL) != NULL) pIMDEmit->Release(); } diff --git a/src/coreclr/vm/peassembly.inl b/src/coreclr/vm/peassembly.inl index 20e0d477ec9919..1dcc64e1a7fac2 100644 --- a/src/coreclr/vm/peassembly.inl +++ b/src/coreclr/vm/peassembly.inl @@ -56,7 +56,7 @@ inline ULONG PEAssembly::AddRef() } CONTRACTL_END; - return FastInterlockIncrement(&m_refCount); + return InterlockedIncrement(&m_refCount); } inline ULONG PEAssembly::Release() @@ -70,7 +70,7 @@ inline ULONG PEAssembly::Release() } CONTRACT_END; - LONG result = FastInterlockDecrement(&m_refCount); + LONG result = InterlockedDecrement(&m_refCount); _ASSERTE(result >= 0); if (result == 0) delete this; diff --git a/src/coreclr/vm/peimage.cpp b/src/coreclr/vm/peimage.cpp index b9bb8ff068b1f0..b456a1a8f8fa60 100644 --- a/src/coreclr/vm/peimage.cpp +++ b/src/coreclr/vm/peimage.cpp @@ -144,7 +144,7 @@ ULONG PEImage::Release() CrstHolder holder(&s_hashLock); // Decrement and check the refcount - if we hit 0, remove it from the hash and delete it. - result=FastInterlockDecrement(&m_refCount); + result=InterlockedDecrement(&m_refCount); if (result == 0 ) { LOG((LF_LOADER, LL_INFO100, "PEImage: Closing Image %S\n", (LPCWSTR) m_path)); @@ -348,7 +348,7 @@ void PEImage::OpenNativeMDImport() IID_IMDInternalImport, (void **) &m_pNewImport)); - if(FastInterlockCompareExchangePointer(&m_pNativeMDImport, m_pNewImport, NULL)) + if(InterlockedCompareExchangeT(&m_pNativeMDImport, m_pNewImport, NULL)) m_pNewImport->Release(); } _ASSERTE(m_pNativeMDImport); @@ -390,7 +390,7 @@ void PEImage::OpenMDImport() IID_IMDInternalImport, (void **) &m_pNewImport)); - if(FastInterlockCompareExchangePointer(&m_pMDImport, m_pNewImport, NULL)) + if(InterlockedCompareExchangeT(&m_pMDImport, m_pNewImport, NULL)) { m_pNewImport->Release(); } @@ -507,7 +507,7 @@ LoaderHeap *PEImage::IJWFixupData::GetThunkHeap() ThunkHeapStubManager::g_pManager->GetRangeList(), UnlockedLoaderHeap::HeapKind::Executable); - if (FastInterlockCompareExchangePointer((PVOID*)&m_DllThunkHeap, (VOID*)pNewHeap, (VOID*)0) != 0) + if (InterlockedCompareExchangeT((PVOID*)&m_DllThunkHeap, (VOID*)pNewHeap, (VOID*)0) != 0) { delete pNewHeap; } diff --git a/src/coreclr/vm/peimage.inl b/src/coreclr/vm/peimage.inl index 19668be89f97ce..3fec6c1086e518 100644 --- a/src/coreclr/vm/peimage.inl +++ b/src/coreclr/vm/peimage.inl @@ -22,7 +22,7 @@ inline ULONG PEImage::AddRef() } CONTRACT_END; - RETURN (static_cast(FastInterlockIncrement(&m_refCount))); + RETURN (static_cast(InterlockedIncrement(&m_refCount))); } inline const SString &PEImage::GetPath() diff --git a/src/coreclr/vm/peimagelayout.inl b/src/coreclr/vm/peimagelayout.inl index 8c02d9cc6b764e..038b17be1eb271 100644 --- a/src/coreclr/vm/peimagelayout.inl +++ b/src/coreclr/vm/peimagelayout.inl @@ -19,7 +19,7 @@ inline void PEImageLayout::AddRef() } CONTRACT_END; - FastInterlockIncrement(&m_refCount); + InterlockedIncrement(&m_refCount); RETURN; } @@ -41,7 +41,7 @@ inline ULONG PEImageLayout::Release() return m_refCount; #endif - ULONG result=FastInterlockDecrement(&m_refCount); + ULONG result=InterlockedDecrement(&m_refCount); if (result == 0 ) { delete this; diff --git a/src/coreclr/vm/proftoeeinterfaceimpl.cpp b/src/coreclr/vm/proftoeeinterfaceimpl.cpp index 4c827783d51b4a..4b32d145a716ab 100644 --- a/src/coreclr/vm/proftoeeinterfaceimpl.cpp +++ b/src/coreclr/vm/proftoeeinterfaceimpl.cpp @@ -918,8 +918,8 @@ void __stdcall UpdateGenerationBounds() GC_NOTRIGGER; MODE_ANY; // can be called even on GC threads #ifdef PROFILING_SUPPORTED - PRECONDITION(FastInterlockIncrement(&s_generationTableWriterCount) == 1); - POSTCONDITION(FastInterlockDecrement(&s_generationTableWriterCount) == 0); + PRECONDITION(InterlockedIncrement(&s_generationTableWriterCount) == 1); + POSTCONDITION(InterlockedDecrement(&s_generationTableWriterCount) == 0); #endif // PROFILING_SUPPORTED } CONTRACT_END; diff --git a/src/coreclr/vm/spinlock.cpp b/src/coreclr/vm/spinlock.cpp index 70ad06459777f9..a9a9b1d07ecfad 100644 --- a/src/coreclr/vm/spinlock.cpp +++ b/src/coreclr/vm/spinlock.cpp @@ -56,7 +56,7 @@ void SpinLock::Init(LOCK_TYPE type, bool RequireCoopGC) while (TRUE) { - LONG curValue = FastInterlockCompareExchange((LONG*)&m_Initialized, BeingInitialized, UnInitialized); + LONG curValue = InterlockedCompareExchange((LONG*)&m_Initialized, BeingInitialized, UnInitialized); if (curValue == Initialized) { return; @@ -163,7 +163,7 @@ BOOL SpinLock::GetLockNoWait() CONTRACTL_END; { - if (VolatileLoad(&m_lock) == 0 && FastInterlockExchange (&m_lock, 1) == 0) + if (VolatileLoad(&m_lock) == 0 && InterlockedExchange (&m_lock, 1) == 0) { EE_LOCK_TAKEN(this); return 1; diff --git a/src/coreclr/vm/spinlock.h b/src/coreclr/vm/spinlock.h index adef3d4a59bcf5..e902f8d2d02672 100644 --- a/src/coreclr/vm/spinlock.h +++ b/src/coreclr/vm/spinlock.h @@ -84,13 +84,13 @@ class DangerousNonHostedSpinLock FORCEINLINE void Acquire() { WRAPPER_NO_CONTRACT; - YIELD_WHILE(FastInterlockExchange(&m_value, 1) == 1); + YIELD_WHILE(InterlockedExchange(&m_value, 1) == 1); } FORCEINLINE BOOL TryAcquire() { WRAPPER_NO_CONTRACT; - return (FastInterlockExchange(&m_value, 1) == 0); + return (InterlockedExchange(&m_value, 1) == 0); } FORCEINLINE void Release() diff --git a/src/coreclr/vm/stublink.cpp b/src/coreclr/vm/stublink.cpp index 13407c7f28fbc5..d31953572d8c9e 100644 --- a/src/coreclr/vm/stublink.cpp +++ b/src/coreclr/vm/stublink.cpp @@ -1918,7 +1918,7 @@ VOID Stub::IncRef() CONTRACTL_END; _ASSERTE(m_signature == kUsedStub); - FastInterlockIncrement((LONG*)&m_refcount); + InterlockedIncrement((LONG*)&m_refcount); } //------------------------------------------------------------------- @@ -1934,7 +1934,7 @@ BOOL Stub::DecRef() CONTRACTL_END; _ASSERTE(m_signature == kUsedStub); - int count = FastInterlockDecrement((LONG*)&m_refcount); + int count = InterlockedDecrement((LONG*)&m_refcount); if (count <= 0) { DeleteStub(); return TRUE; diff --git a/src/coreclr/vm/syncblk.cpp b/src/coreclr/vm/syncblk.cpp index 9dfdfafc050f5d..4665c62e23a1a0 100644 --- a/src/coreclr/vm/syncblk.cpp +++ b/src/coreclr/vm/syncblk.cpp @@ -879,7 +879,7 @@ void SyncBlockCache::Grow() // note: we do not care if another thread does not see the new size // however we really do not want it to see the new size without seeing the new array //@TODO do we still leak here if two threads come here at the same time ? - FastInterlockExchangePointer(&SyncTableEntry::GetSyncTableEntryByRef(), newSyncTable.GetValue()); + InterlockedExchangeT(&SyncTableEntry::GetSyncTableEntryByRef(), newSyncTable.GetValue()); m_FreeSyncTableIndex++; @@ -1904,7 +1904,7 @@ DEBUG_NOINLINE void ObjHeader::EnterSpinLock() { // try to take the lock LONG newValue = curValue | BIT_SBLK_SPIN_LOCK; - LONG result = FastInterlockCompareExchange((LONG*)&m_SyncBlockValue, newValue, curValue); + LONG result = InterlockedCompareExchange((LONG*)&m_SyncBlockValue, newValue, curValue); if (result == curValue) break; } @@ -1952,7 +1952,7 @@ DEBUG_NOINLINE void ObjHeader::EnterSpinLock() { // try to take the lock LONG newValue = curValue | BIT_SBLK_SPIN_LOCK; - LONG result = FastInterlockCompareExchange((LONG*)&m_SyncBlockValue, newValue, curValue); + LONG result = InterlockedCompareExchange((LONG*)&m_SyncBlockValue, newValue, curValue); if (result == curValue) break; } @@ -1972,7 +1972,7 @@ DEBUG_NOINLINE void ObjHeader::ReleaseSpinLock() INCONTRACT(Thread* pThread = GetThreadNULLOk()); INCONTRACT(if (pThread != NULL) pThread->EndNoTriggerGC()); - FastInterlockAnd(&m_SyncBlockValue, ~BIT_SBLK_SPIN_LOCK); + InterlockedAnd((LONG*)&m_SyncBlockValue, ~BIT_SBLK_SPIN_LOCK); } #endif //!DACCESS_COMPILE @@ -2918,7 +2918,7 @@ bool SyncBlock::SetInteropInfo(InteropSyncBlockInfo* pInteropInfo) m_dwAppDomainIndex == GetAppDomain()->GetIndex()); m_dwAppDomainIndex = GetAppDomain()->GetIndex(); */ - return (FastInterlockCompareExchangePointer(&m_pInteropInfo, + return (InterlockedCompareExchangeT(&m_pInteropInfo, pInteropInfo, NULL) == NULL); } diff --git a/src/coreclr/vm/syncblk.h b/src/coreclr/vm/syncblk.h index e137532a090632..8e83a29cbd4f6f 100644 --- a/src/coreclr/vm/syncblk.h +++ b/src/coreclr/vm/syncblk.h @@ -567,7 +567,7 @@ class AwareLock void IncrementTransientPrecious() { LIMITED_METHOD_CONTRACT; - FastInterlockIncrement(&m_TransientPrecious); + InterlockedIncrement(&m_TransientPrecious); _ASSERTE(m_TransientPrecious > 0); } @@ -575,7 +575,7 @@ class AwareLock { LIMITED_METHOD_CONTRACT; _ASSERTE(m_TransientPrecious > 0); - FastInterlockDecrement(&m_TransientPrecious); + InterlockedDecrement(&m_TransientPrecious); } DWORD GetSyncBlockIndex(); @@ -738,7 +738,7 @@ class InteropSyncBlockInfo bool SetUMEntryThunk(void* pUMEntryThunk) { WRAPPER_NO_CONTRACT; - return (FastInterlockCompareExchangePointer(&m_pUMEntryThunk, + return (InterlockedCompareExchangeT(&m_pUMEntryThunk, pUMEntryThunk, NULL) == NULL); } @@ -801,7 +801,7 @@ class InteropSyncBlockInfo if (m_managedObjectComWrapperMap == NULL) { NewHolder map = new ManagedObjectComWrapperByIdMap(); - if (FastInterlockCompareExchangePointer((ManagedObjectComWrapperByIdMap**)&m_managedObjectComWrapperMap, (ManagedObjectComWrapperByIdMap *)map, NULL) == NULL) + if (InterlockedCompareExchangeT((ManagedObjectComWrapperByIdMap**)&m_managedObjectComWrapperMap, (ManagedObjectComWrapperByIdMap *)map, NULL) == NULL) { map.SuppressRelease(); } @@ -880,7 +880,7 @@ class InteropSyncBlockInfo { LIMITED_METHOD_CONTRACT; - return (FastInterlockCompareExchangePointer( + return (InterlockedCompareExchangeT( &m_externalComObjectContext, eoc, curr) == curr); @@ -1117,7 +1117,7 @@ class SyncBlock DWORD SetHashCode(DWORD hashCode) { WRAPPER_NO_CONTRACT; - DWORD result = FastInterlockCompareExchange((LONG*)&m_dwHashCode, hashCode, 0); + DWORD result = InterlockedCompareExchange((LONG*)&m_dwHashCode, hashCode, 0); if (result == 0) { // the sync block now holds a hash code, which we can't afford to lose. @@ -1473,7 +1473,7 @@ class ObjHeader // note that indx could be carrying the BIT_SBLK_IS_HASH_OR_SYNCBLKINDEX bit that we need to preserve newValue = (indx | (oldValue & ~(BIT_SBLK_IS_HASH_OR_SYNCBLKINDEX | BIT_SBLK_IS_HASHCODE | MASK_SYNCBLOCKINDEX))); - if (FastInterlockCompareExchange((LONG*)&m_SyncBlockValue, + if (InterlockedCompareExchange((LONG*)&m_SyncBlockValue, newValue, oldValue) == oldValue) @@ -1489,7 +1489,7 @@ class ObjHeader LIMITED_METHOD_CONTRACT; _ASSERTE(m_SyncBlockValue & BIT_SBLK_SPIN_LOCK); - FastInterlockAnd(&m_SyncBlockValue, ~(BIT_SBLK_IS_HASH_OR_SYNCBLKINDEX | BIT_SBLK_IS_HASHCODE | MASK_SYNCBLOCKINDEX)); + InterlockedAnd((LONG*)&m_SyncBlockValue, ~(BIT_SBLK_IS_HASH_OR_SYNCBLKINDEX | BIT_SBLK_IS_HASHCODE | MASK_SYNCBLOCKINDEX)); } // Used only GC @@ -1509,14 +1509,14 @@ class ObjHeader LIMITED_METHOD_CONTRACT; _ASSERTE((bit & MASK_SYNCBLOCKINDEX) == 0); - FastInterlockOr(&m_SyncBlockValue, bit); + InterlockedOr((LONG*)&m_SyncBlockValue, bit); } void ClrBit(DWORD bit) { LIMITED_METHOD_CONTRACT; _ASSERTE((bit & MASK_SYNCBLOCKINDEX) == 0); - FastInterlockAnd(&m_SyncBlockValue, ~bit); + InterlockedAnd((LONG*)&m_SyncBlockValue, ~bit); } //GC accesses this bit when all threads are stopped. void SetGCBit() @@ -1554,7 +1554,7 @@ class ObjHeader LIMITED_METHOD_CONTRACT; _ASSERTE((oldBits & BIT_SBLK_SPIN_LOCK) == 0); - DWORD result = FastInterlockCompareExchange((LONG*)&m_SyncBlockValue, newBits, oldBits); + DWORD result = InterlockedCompareExchange((LONG*)&m_SyncBlockValue, newBits, oldBits); return result; } diff --git a/src/coreclr/vm/syncclean.cpp b/src/coreclr/vm/syncclean.cpp index 4ffb3d2f109cb0..142417ce1d12c3 100644 --- a/src/coreclr/vm/syncclean.cpp +++ b/src/coreclr/vm/syncclean.cpp @@ -38,7 +38,7 @@ void SyncClean::AddHashMap (Bucket *bucket) pTempBucket = (Bucket *)m_HashMap; NextObsolete (bucket) = pTempBucket; } - while (FastInterlockCompareExchangePointer(m_HashMap.GetPointer(), bucket, pTempBucket) != pTempBucket); + while (InterlockedCompareExchangeT(m_HashMap.GetPointer(), bucket, pTempBucket) != pTempBucket); } void SyncClean::AddEEHashTable (EEHashEntry** entry) @@ -58,7 +58,7 @@ void SyncClean::AddEEHashTable (EEHashEntry** entry) pTempHashEntry = (EEHashEntry**)m_EEHashTable; entry[-1] = (EEHashEntry *)pTempHashEntry; } - while (FastInterlockCompareExchangePointer(m_EEHashTable.GetPointer(), entry, pTempHashEntry) != pTempHashEntry); + while (InterlockedCompareExchangeT(m_EEHashTable.GetPointer(), entry, pTempHashEntry) != pTempHashEntry); } void SyncClean::CleanUp () @@ -71,7 +71,7 @@ void SyncClean::CleanUp () (GCHeapUtilities::IsGCInProgress() && GetThreadNULLOk() == ThreadSuspend::GetSuspensionThread())); if (m_HashMap) { - Bucket * pTempBucket = FastInterlockExchangePointer(m_HashMap.GetPointer(), NULL); + Bucket * pTempBucket = InterlockedExchangeT(m_HashMap.GetPointer(), NULL); while (pTempBucket) { @@ -83,7 +83,7 @@ void SyncClean::CleanUp () if (m_EEHashTable) { - EEHashEntry ** pTempHashEntry = FastInterlockExchangePointer(m_EEHashTable.GetPointer(), NULL); + EEHashEntry ** pTempHashEntry = InterlockedExchangeT(m_EEHashTable.GetPointer(), NULL); while (pTempHashEntry) { EEHashEntry **pNextHashEntry = (EEHashEntry **)pTempHashEntry[-1]; diff --git a/src/coreclr/vm/synch.cpp b/src/coreclr/vm/synch.cpp index 2f9acbe476b061..7152d00ee0cc2f 100644 --- a/src/coreclr/vm/synch.cpp +++ b/src/coreclr/vm/synch.cpp @@ -124,14 +124,14 @@ void CLREventBase::CreateMonitorEvent(SIZE_T Cookie) CONTRACTL_END; // thread-safe SetAutoEvent - FastInterlockOr(&m_dwFlags, CLREVENT_FLAGS_AUTO_EVENT); + InterlockedOr((LONG*)&m_dwFlags, CLREVENT_FLAGS_AUTO_EVENT); { HANDLE h = WszCreateEvent(NULL,FALSE,FALSE,NULL); if (h == NULL) { ThrowOutOfMemory(); } - if (FastInterlockCompareExchangePointer(&m_handle, + if (InterlockedCompareExchangeT(&m_handle, h, INVALID_HANDLE_VALUE) != INVALID_HANDLE_VALUE) { @@ -141,7 +141,7 @@ void CLREventBase::CreateMonitorEvent(SIZE_T Cookie) } // thread-safe SetInDeadlockDetection - FastInterlockOr(&m_dwFlags, CLREVENT_FLAGS_IN_DEADLOCK_DETECTION); + InterlockedOr((LONG*)&m_dwFlags, CLREVENT_FLAGS_IN_DEADLOCK_DETECTION); for (;;) { @@ -154,7 +154,7 @@ void CLREventBase::CreateMonitorEvent(SIZE_T Cookie) } LONG newFlags = oldFlags | CLREVENT_FLAGS_MONITOREVENT_ALLOCATED; - if (FastInterlockCompareExchange((LONG*)&m_dwFlags, newFlags, oldFlags) != oldFlags) + if (InterlockedCompareExchange((LONG*)&m_dwFlags, newFlags, oldFlags) != oldFlags) { // We lost the race continue; @@ -196,7 +196,7 @@ void CLREventBase::SetMonitorEvent() } LONG newFlags = oldFlags | CLREVENT_FLAGS_MONITOREVENT_SIGNALLED; - if (FastInterlockCompareExchange((LONG*)&m_dwFlags, newFlags, oldFlags) != oldFlags) + if (InterlockedCompareExchange((LONG*)&m_dwFlags, newFlags, oldFlags) != oldFlags) { // We lost the race continue; diff --git a/src/coreclr/vm/threadpoolrequest.cpp b/src/coreclr/vm/threadpoolrequest.cpp index ff3fc9c93cf924..6e1caf5187650c 100644 --- a/src/coreclr/vm/threadpoolrequest.cpp +++ b/src/coreclr/vm/threadpoolrequest.cpp @@ -325,7 +325,7 @@ void UnManagedPerAppDomainTPCount::SetAppDomainRequestsActive() LONG count = VolatileLoad(&m_outstandingThreadRequestCount); while (count < (LONG)ThreadpoolMgr::NumberOfProcessors) { - LONG prevCount = FastInterlockCompareExchange(&m_outstandingThreadRequestCount, count+1, count); + LONG prevCount = InterlockedCompareExchange(&m_outstandingThreadRequestCount, count+1, count); if (prevCount == count) { ThreadpoolMgr::MaybeAddWorkingWorker(); @@ -346,7 +346,7 @@ bool FORCEINLINE UnManagedPerAppDomainTPCount::TakeActiveRequest() while (count > 0) { - LONG prevCount = FastInterlockCompareExchange(&m_outstandingThreadRequestCount, count-1, count); + LONG prevCount = InterlockedCompareExchange(&m_outstandingThreadRequestCount, count-1, count); if (prevCount == count) return true; count = prevCount; @@ -568,7 +568,7 @@ void ManagedPerAppDomainTPCount::SetAppDomainRequestsActive() LONG count = VolatileLoad(&m_numRequestsPending); while (true) { - LONG prev = FastInterlockCompareExchange(&m_numRequestsPending, count+1, count); + LONG prev = InterlockedCompareExchange(&m_numRequestsPending, count+1, count); if (prev == count) { ThreadpoolMgr::MaybeAddWorkingWorker(); @@ -593,7 +593,7 @@ void ManagedPerAppDomainTPCount::ClearAppDomainRequestsActive() LONG count = VolatileLoad(&m_numRequestsPending); while (count > 0) { - LONG prev = FastInterlockCompareExchange(&m_numRequestsPending, 0, count); + LONG prev = InterlockedCompareExchange(&m_numRequestsPending, 0, count); if (prev == count) break; count = prev; @@ -608,7 +608,7 @@ bool ManagedPerAppDomainTPCount::TakeActiveRequest() LONG count = VolatileLoad(&m_numRequestsPending); while (count > 0) { - LONG prev = FastInterlockCompareExchange(&m_numRequestsPending, count-1, count); + LONG prev = InterlockedCompareExchange(&m_numRequestsPending, count-1, count); if (prev == count) return true; count = prev; diff --git a/src/coreclr/vm/threadpoolrequest.h b/src/coreclr/vm/threadpoolrequest.h index 1f7b335b5fb797..f3cd4c49ccac60 100644 --- a/src/coreclr/vm/threadpoolrequest.h +++ b/src/coreclr/vm/threadpoolrequest.h @@ -136,7 +136,7 @@ class ManagedPerAppDomainTPCount : public IPerAppDomainTPCount { TPIndex m_index; struct DECLSPEC_ALIGN(MAX_CACHE_LINE_SIZE) { BYTE m_padding1[MAX_CACHE_LINE_SIZE - sizeof(LONG)]; - // Only use with VolatileLoad+VolatileStore+FastInterlockCompareExchange + // Only use with VolatileLoad+VolatileStore+InterlockedCompareExchange LONG m_numRequestsPending; BYTE m_padding2[MAX_CACHE_LINE_SIZE]; }; @@ -214,7 +214,7 @@ class UnManagedPerAppDomainTPCount : public IPerAppDomainTPCount { ULONG m_NumRequests; struct DECLSPEC_ALIGN(MAX_CACHE_LINE_SIZE) { BYTE m_padding1[MAX_CACHE_LINE_SIZE - sizeof(LONG)]; - // Only use with VolatileLoad+VolatileStore+FastInterlockCompareExchange + // Only use with VolatileLoad+VolatileStore+InterlockedCompareExchange LONG m_outstandingThreadRequestCount; BYTE m_padding2[MAX_CACHE_LINE_SIZE]; }; diff --git a/src/coreclr/vm/threads.cpp b/src/coreclr/vm/threads.cpp index 48a2a3b046a73f..b02c24dffca703 100644 --- a/src/coreclr/vm/threads.cpp +++ b/src/coreclr/vm/threads.cpp @@ -612,7 +612,7 @@ static void DeleteThread(Thread* pThread) pThread->RevokeApartmentSpy(); #endif // FEATURE_COMINTEROP - FastInterlockOr((ULONG *)&pThread->m_State, Thread::TS_Dead); + pThread->SetThreadState(Thread::TS_Dead); // ~Thread() calls SafeSetThrowables which has a conditional contract // which says that if you call it with a NULL throwable then it is @@ -695,17 +695,17 @@ Thread* SetupThread() { if (IsThreadPoolWorkerSpecialThread()) { - FastInterlockOr((ULONG *) &pThread->m_State, Thread::TS_TPWorkerThread); + pThread->SetThreadState(Thread::TS_TPWorkerThread); pThread->SetBackground(TRUE); } else if (IsThreadPoolIOCompletionSpecialThread()) { - FastInterlockOr ((ULONG *) &pThread->m_State, Thread::TS_CompletionPortThread); + pThread->SetThreadState(Thread::TS_CompletionPortThread); pThread->SetBackground(TRUE); } else if (IsTimerSpecialThread() || IsWaitSpecialThread()) { - FastInterlockOr((ULONG *) &pThread->m_State, Thread::TS_TPWorkerThread); + pThread->SetThreadState(Thread::TS_TPWorkerThread); pThread->SetBackground(TRUE); } @@ -727,8 +727,8 @@ Thread* SetupThread() pThread->PrepareApartmentAndContext(); // reset any unstarted bits on the thread object - FastInterlockAnd((ULONG *) &pThread->m_State, ~Thread::TS_Unstarted); - FastInterlockOr((ULONG *) &pThread->m_State, Thread::TS_LegalToJoin); + pThread->ResetThreadState(Thread::TS_Unstarted); + pThread->SetThreadState(Thread::TS_LegalToJoin); ThreadStore::AddThread(pThread); @@ -745,7 +745,7 @@ Thread* SetupThread() threadHolder.SuppressRelease(); - FastInterlockOr((ULONG *) &pThread->m_State, Thread::TS_FullyInitialized); + pThread->SetThreadState(Thread::TS_FullyInitialized); #ifdef DEBUGGING_SUPPORTED // @@ -788,15 +788,15 @@ Thread* SetupThread() if (IsThreadPoolWorkerSpecialThread()) { - FastInterlockOr((ULONG *) &pThread->m_State, Thread::TS_TPWorkerThread); + pThread->SetThreadState(Thread::TS_TPWorkerThread); } else if (IsThreadPoolIOCompletionSpecialThread()) { - FastInterlockOr ((ULONG *) &pThread->m_State, Thread::TS_CompletionPortThread); + pThread->SetThreadState(Thread::TS_CompletionPortThread); } else if (IsTimerSpecialThread() || IsWaitSpecialThread()) { - FastInterlockOr((ULONG *) &pThread->m_State, Thread::TS_TPWorkerThread); + pThread->SetThreadState(Thread::TS_TPWorkerThread); } #ifdef FEATURE_EVENT_TRACE @@ -878,8 +878,7 @@ Thread* SetupUnstartedThread(SetupUnstartedThreadFlags flags) pThread->SetThreadStateNC(Thread::TSNC_TSLTakenForStartup); } - FastInterlockOr((ULONG *) &pThread->m_State, - (Thread::TS_Unstarted | Thread::TS_WeOwn)); + pThread->SetThreadState((Thread::ThreadState)(Thread::TS_Unstarted | Thread::TS_WeOwn)); ThreadStore::AddThread(pThread); @@ -989,7 +988,7 @@ HRESULT Thread::DetachThread(BOOL fDLLThreadDetach) _ASSERTE (this == GetThread()); - FastInterlockIncrement(&Thread::m_DetachCount); + InterlockedIncrement(&Thread::m_DetachCount); if (IsAbortRequested()) { // Reset trapping count. @@ -998,7 +997,7 @@ HRESULT Thread::DetachThread(BOOL fDLLThreadDetach) if (!IsBackground()) { - FastInterlockIncrement(&Thread::m_ActiveDetachCount); + InterlockedIncrement(&Thread::m_ActiveDetachCount); ThreadStore::CheckForEEShutdown(); } @@ -1021,7 +1020,7 @@ HRESULT Thread::DetachThread(BOOL fDLLThreadDetach) SetThread(NULL); SetAppDomain(NULL); - FastInterlockOr((ULONG*)&m_State, (int) (Thread::TS_Detached | Thread::TS_ReportDead)); + SetThreadState((Thread::ThreadState)(Thread::TS_Detached | Thread::TS_ReportDead)); // Do not touch Thread object any more. It may be destroyed. // These detached threads will be cleaned up by finalizer thread. But if the process uses @@ -1898,7 +1897,7 @@ BOOL Thread::HasStarted() if (res == FALSE) goto FAILURE; - FastInterlockOr((ULONG *) &m_State, TS_FullyInitialized); + SetThreadState(TS_FullyInitialized); #ifdef DEBUGGING_SUPPORTED // @@ -1969,7 +1968,7 @@ BOOL Thread::HasStarted() CleanupCOMState(); } #endif - FastInterlockDecrement(&ThreadStore::s_pThreadStore->m_PendingThreadCount); + InterlockedDecrement(&ThreadStore::s_pThreadStore->m_PendingThreadCount); // One of the components of OtherThreadsComplete() has changed, so check whether // we should now exit the EE. ThreadStore::CheckForEEShutdown(); @@ -2376,7 +2375,7 @@ BOOL Thread::CreateNewOSThread(SIZE_T sizeToCommitOrReserve, LPTHREAD_START_ROUT m_OSThreadId = ourId; - FastInterlockIncrement(&ThreadStore::s_pThreadStore->m_PendingThreadCount); + InterlockedIncrement(&ThreadStore::s_pThreadStore->m_PendingThreadCount); #ifdef _DEBUG m_Creator.SetToCurrentThread(); @@ -2423,7 +2422,7 @@ int Thread::IncExternalCount() Thread *pCurThread = GetThreadNULLOk(); _ASSERTE(m_ExternalRefCount > 0); - int retVal = FastInterlockIncrement((LONG*)&m_ExternalRefCount); + int retVal = InterlockedIncrement((LONG*)&m_ExternalRefCount); // If we have an exposed object and the refcount is greater than one // we must make sure to keep a strong handle to the exposed object // so that we keep it alive even if nobody has a reference to it. @@ -2493,7 +2492,7 @@ int Thread::DecExternalCount(BOOL holdingLock) ThreadStore::s_pThreadStore->m_Crst.GetEnterCount() > 0 || IsAtProcessExit()); - retVal = FastInterlockDecrement((LONG*)&m_ExternalRefCount); + retVal = InterlockedDecrement((LONG*)&m_ExternalRefCount); if (retVal == 0) { @@ -2785,7 +2784,7 @@ void Thread::CoUninitialize() if (IsCoInitialized()) { BaseCoUninitialize(); - FastInterlockAnd((ULONG *)&m_State, ~TS_CoInitialized); + ResetThreadState(TS_CoInitialized); } #ifdef FEATURE_COMINTEROP @@ -2827,10 +2826,10 @@ void Thread::CleanupDetachedThreads() // Unmark that the thread is detached while we have the // thread store lock. This will ensure that no other // thread will race in here and try to delete it, too. - FastInterlockAnd((ULONG*)&(thread->m_State), ~TS_Detached); - FastInterlockDecrement(&m_DetachCount); + thread->ResetThreadState(TS_Detached); + InterlockedDecrement(&m_DetachCount); if (!thread->IsBackground()) - FastInterlockDecrement(&m_ActiveDetachCount); + InterlockedDecrement(&m_ActiveDetachCount); // If the debugger is attached, then we need to unlock the // thread store before calling OnThreadTerminate. That @@ -3016,7 +3015,7 @@ void Thread::OnThreadTerminate(BOOL holdingLock) GCX_COOP(); // GetTotalAllocatedBytes reads dead_threads_non_alloc_bytes, but will suspend EE, being in COOP mode we cannot race with that // however, there could be other threads terminating and doing the same Add. - FastInterlockExchangeAddLong((LONG64*)&dead_threads_non_alloc_bytes, m_alloc_context.alloc_limit - m_alloc_context.alloc_ptr); + InterlockedExchangeAdd64((LONG64*)&dead_threads_non_alloc_bytes, m_alloc_context.alloc_limit - m_alloc_context.alloc_ptr); GCHeapUtilities::GetGCHeap()->FixAllocContext(&m_alloc_context, NULL, NULL); m_alloc_context.init(); } @@ -3079,7 +3078,7 @@ void Thread::OnThreadTerminate(BOOL holdingLock) m_alloc_context.init(); } - FastInterlockOr((ULONG *) &m_State, TS_Dead); + SetThreadState(TS_Dead); ThreadStore::s_pThreadStore->m_DeadThreadCount++; ThreadStore::s_pThreadStore->IncrementDeadThreadCountForGCTrigger(); @@ -3091,7 +3090,7 @@ void Thread::OnThreadTerminate(BOOL holdingLock) ThreadStore::s_pThreadStore->m_BackgroundThreadCount--; } - FastInterlockAnd((ULONG *) &m_State, ~(TS_Unstarted | TS_Background)); + ResetThreadState((Thread::ThreadState)(TS_Unstarted | TS_Background)); // // If this thread was told to trip for debugging between the @@ -3397,7 +3396,7 @@ void Thread::DoAppropriateWaitWorkerAlertableHelper(WaitMode mode) // a thread that's not in the interruptible state, we just record that fact. So // we have to set TS_Interruptible before we test to see whether someone wants to // interrupt us or else we have a race condition that causes us to skip the APC. - FastInterlockOr((ULONG *) &m_State, TS_Interruptible); + SetThreadState(TS_Interruptible); if (HasThreadStateNC(TSNC_InRestoringSyncBlock)) { @@ -3411,7 +3410,7 @@ void Thread::DoAppropriateWaitWorkerAlertableHelper(WaitMode mode) // Safe to clear the interrupted state, no APC could have fired since we // reset m_UserInterrupt (which inhibits our APC callback from doing // anything). - FastInterlockAnd((ULONG *) &m_State, ~TS_Interrupted); + ResetThreadState(TS_Interrupted); } } @@ -4184,7 +4183,7 @@ void WINAPI Thread::UserInterruptAPC(ULONG_PTR data) { // Set bit to indicate this routine was called (as opposed to other // generic APCs). - FastInterlockOr((ULONG *) &pCurThread->m_State, TS_Interrupted); + pCurThread->SetThreadState(TS_Interrupted); } } } @@ -4198,7 +4197,7 @@ void Thread::UserInterrupt(ThreadInterruptMode mode) } CONTRACTL_END; - FastInterlockOr((DWORD*)&m_UserInterrupt, mode); + InterlockedOr(&m_UserInterrupt, mode); if (HasValidThreadHandle() && HasThreadState (TS_Interruptible)) @@ -4231,7 +4230,7 @@ void Thread::UserSleep(INT32 time) // a thread that's not in the interruptible state, we just record that fact. So // we have to set TS_Interruptible before we test to see whether someone wants to // interrupt us or else we have a race condition that causes us to skip the APC. - FastInterlockOr((ULONG *) &m_State, TS_Interruptible); + SetThreadState(TS_Interruptible); // If someone has interrupted us, we should not enter the wait. if (IsUserInterrupted()) @@ -4241,7 +4240,7 @@ void Thread::UserSleep(INT32 time) ThreadStateHolder tsh(TRUE, TS_Interruptible | TS_Interrupted); - FastInterlockAnd((ULONG *) &m_State, ~TS_Interrupted); + ResetThreadState(TS_Interrupted); DWORD dwTime = (DWORD)time; retry: @@ -4324,7 +4323,7 @@ OBJECTREF Thread::GetExposedObject() // Increase the external ref count. We can't call IncExternalCount because we // already hold the thread lock and IncExternalCount won't be able to take it. - ULONG retVal = FastInterlockIncrement ((LONG*)&m_ExternalRefCount); + ULONG retVal = InterlockedIncrement ((LONG*)&m_ExternalRefCount); // Check to see if we need to store a strong pointer to the object. if (retVal > 1) @@ -4663,7 +4662,7 @@ void Thread::SetBackground(BOOL isBack) { if (!IsBackground()) { - FastInterlockOr((ULONG *) &m_State, TS_Background); + SetThreadState(TS_Background); // unstarted threads don't contribute to the background count if (!IsUnstarted()) @@ -4683,7 +4682,7 @@ void Thread::SetBackground(BOOL isBack) { if (IsBackground()) { - FastInterlockAnd((ULONG *) &m_State, ~TS_Background); + ResetThreadState(TS_Background); // unstarted threads don't contribute to the background count if (!IsUnstarted()) @@ -4785,7 +4784,7 @@ void Thread::PrepareApartmentAndContext() // a different apartment state than the requested one. If we didn't clear // the requested apartment state, then we could end up with both TS_InSTA and // TS_InMTA set at the same time. - FastInterlockAnd ((ULONG *) &m_State, ~TS_InSTA & ~TS_InMTA); + ResetThreadState((Thread::ThreadState)(TS_InSTA | TS_InMTA)); // Attempt to set the requested apartment state. SetApartment(aState); @@ -4882,7 +4881,7 @@ Thread::ApartmentState Thread::GetApartmentRare(Thread::ApartmentState as) // made MTA (if it hasn't been CoInitializeEx'd but CoInitialize // has already been called on some other thread in the process. if (as == AS_InSTA) - FastInterlockOr((ULONG *) &m_State, AS_InSTA); + SetThreadState(TS_InSTA); } } } @@ -4935,7 +4934,7 @@ Thread::ApartmentState Thread::GetFinalApartment() { // On shutdown, do not use cached value. Someone might have called // CoUninitialize. - FastInterlockAnd ((ULONG *) &m_State, ~TS_InSTA & ~TS_InMTA); + ResetThreadState((Thread::ThreadState)(TS_InSTA | TS_InMTA)); } as = GetApartment(); @@ -4962,8 +4961,7 @@ VOID Thread::ResetApartment() CONTRACTL_END; // reset the TS_InSTA bit and TS_InMTA bit - ThreadState t_State = (ThreadState)(~(TS_InSTA | TS_InMTA)); - FastInterlockAnd((ULONG *) &m_State, t_State); + ResetThreadState((Thread::ThreadState)(TS_InSTA | TS_InMTA)); } // Attempt to set current thread's apartment state. The actual apartment state @@ -5012,7 +5010,7 @@ Thread::ApartmentState Thread::SetApartment(ApartmentState state) ::CoUninitialize(); ThreadState uninitialized = static_cast(TS_InSTA | TS_InMTA | TS_CoInitialized); - FastInterlockAnd((ULONG *) &m_State, ~uninitialized); + ResetThreadState(uninitialized); } #ifdef FEATURE_COMINTEROP @@ -5062,7 +5060,7 @@ Thread::ApartmentState Thread::SetApartment(ApartmentState state) if (m_OSThreadId != ::GetCurrentThreadId()) #endif { - FastInterlockOr((ULONG *) &m_State, (state == AS_InSTA) ? TS_InSTA : TS_InMTA); + SetThreadState((state == AS_InSTA) ? TS_InSTA : TS_InMTA); return state; } @@ -5104,14 +5102,14 @@ Thread::ApartmentState Thread::SetApartment(ApartmentState state) } // We succeeded in setting the apartment state to the requested state. - FastInterlockOr((ULONG *) &m_State, t_State); + SetThreadState(t_State); } else if (hr == RPC_E_CHANGED_MODE) { // We didn't manage to enforce the requested apartment state, but at least // we can work out what the state is now. No need to actually do the CoInit -- // obviously someone else already took care of that. - FastInterlockOr((ULONG *) &m_State, ((state == AS_InSTA) ? TS_InMTA : TS_InSTA)); + SetThreadState((state == AS_InSTA) ? TS_InMTA : TS_InSTA); } else if (hr == E_OUTOFMEMORY) { @@ -5388,13 +5386,13 @@ BOOL ThreadStore::RemoveThread(Thread *target) if (target->IsBackground()) s_pThreadStore->m_BackgroundThreadCount--; - FastInterlockExchangeAddLong( + InterlockedExchangeAdd64( (LONGLONG *)&Thread::s_workerThreadPoolCompletionCountOverflow, target->m_workerThreadPoolCompletionCount); - FastInterlockExchangeAddLong( + InterlockedExchangeAdd64( (LONGLONG *)&Thread::s_ioThreadPoolCompletionCountOverflow, target->m_ioThreadPoolCompletionCount); - FastInterlockExchangeAddLong( + InterlockedExchangeAdd64( (LONGLONG *)&Thread::s_monitorLockContentionCountOverflow, target->m_monitorLockContentionCount); @@ -5459,12 +5457,12 @@ void ThreadStore::TransferStartedThread(Thread *thread) s_pThreadStore->m_BackgroundThreadCount++; _ASSERTE(s_pThreadStore->m_PendingThreadCount > 0); - FastInterlockDecrement(&s_pThreadStore->m_PendingThreadCount); + InterlockedDecrement(&s_pThreadStore->m_PendingThreadCount); // As soon as we erase this bit, the thread becomes eligible for suspension, // stopping, interruption, etc. - FastInterlockAnd((ULONG *) &thread->m_State, ~Thread::TS_Unstarted); - FastInterlockOr((ULONG *) &thread->m_State, Thread::TS_LegalToJoin); + thread->ResetThreadState(Thread::TS_Unstarted); + thread->SetThreadState(Thread::TS_LegalToJoin); // One of the components of OtherThreadsComplete() has changed, so check whether // we should now exit the EE. @@ -5486,7 +5484,7 @@ void ThreadStore::IncrementDeadThreadCountForGCTrigger() // Although all increments and decrements are usually done inside a lock, that is not sufficient to synchronize with a // background GC thread resetting this value, hence the interlocked operation. Ignore overflow; overflow would likely never // occur, the count is treated as unsigned, and nothing bad would happen if it were to overflow. - SIZE_T count = static_cast(FastInterlockIncrement(&m_DeadThreadCountForGCTrigger)); + SIZE_T count = static_cast(InterlockedIncrement(&m_DeadThreadCountForGCTrigger)); SIZE_T countThreshold = static_cast(s_DeadThreadCountThresholdForGCTrigger); if (count < countThreshold || countThreshold == 0) @@ -5532,7 +5530,7 @@ void ThreadStore::DecrementDeadThreadCountForGCTrigger() // Although all increments and decrements are usually done inside a lock, that is not sufficient to synchronize with a // background GC thread resetting this value, hence the interlocked operation. - if (FastInterlockDecrement(&m_DeadThreadCountForGCTrigger) < 0) + if (InterlockedDecrement(&m_DeadThreadCountForGCTrigger) < 0) { m_DeadThreadCountForGCTrigger = 0; } @@ -5546,7 +5544,7 @@ void ThreadStore::OnMaxGenerationGCStarted() // objects are still reachable due to references to the thread objects, they will not contribute to triggering a GC again. // Synchronize the store with increment/decrement operations occurring on different threads, and make the change visible to // other threads in order to prevent unnecessary GC triggers. - FastInterlockExchange(&m_DeadThreadCountForGCTrigger, 0); + InterlockedExchange(&m_DeadThreadCountForGCTrigger, 0); } bool ThreadStore::ShouldTriggerGCForDeadThreads() @@ -5789,7 +5787,7 @@ void ThreadStore::WaitForOtherThreads() { TSLockHolder.Release(); - FastInterlockOr((ULONG *) &pCurThread->m_State, Thread::TS_ReportDead); + pCurThread->SetThreadState(Thread::TS_ReportDead); DWORD ret = WAIT_OBJECT_0; while (CLREventWaitWithTry(&m_TerminationEvent, INFINITE, TRUE, &ret)) @@ -5928,7 +5926,7 @@ void Thread::HandleThreadInterrupt () if ((m_UserInterrupt & TI_Interrupt) != 0) { ResetThreadState ((ThreadState)(TS_Interrupted | TS_Interruptible)); - FastInterlockAnd ((DWORD*)&m_UserInterrupt, ~TI_Interrupt); + InterlockedAnd (&m_UserInterrupt, ~TI_Interrupt); COMPlusThrow(kThreadInterruptedException); } @@ -6015,7 +6013,7 @@ void UniqueStackSetupMap() CrstUniqueStack, CrstFlags(CRST_REENTRANCY | CRST_UNSAFE_ANYMODE)); - if (FastInterlockCompareExchangePointer(&g_pUniqueStackCrst, + if (InterlockedCompareExchangeT(&g_pUniqueStackCrst, Attempt, NULL) != NULL) { @@ -8271,7 +8269,7 @@ void dbgOnly_IdentifySpecialEEThread() { WRAPPER_NO_CONTRACT; - LONG ourCount = FastInterlockIncrement(&cnt_SpecialEEThreads); + LONG ourCount = InterlockedIncrement(&cnt_SpecialEEThreads); _ASSERTE(ourCount < (LONG) ARRAY_SIZE(SpecialEEThreads)); SpecialEEThreads[ourCount-1] = ::GetCurrentThreadId(); diff --git a/src/coreclr/vm/threads.h b/src/coreclr/vm/threads.h index 97232493d6f620..f4bf60ec167997 100644 --- a/src/coreclr/vm/threads.h +++ b/src/coreclr/vm/threads.h @@ -1068,13 +1068,13 @@ class Thread void SetThreadState(ThreadState ts) { LIMITED_METHOD_CONTRACT; - FastInterlockOr((DWORD*)&m_State, ts); + InterlockedOr((LONG*)&m_State, ts); } void ResetThreadState(ThreadState ts) { LIMITED_METHOD_CONTRACT; - FastInterlockAnd((DWORD*)&m_State, ~ts); + InterlockedAnd((LONG*)&m_State, ~ts); } BOOL HasThreadState(ThreadState ts) @@ -1138,13 +1138,13 @@ class Thread void SetSyncBlockCleanup() { LIMITED_METHOD_CONTRACT; - FastInterlockOr((ULONG *)&m_ThreadTasks, TT_CleanupSyncBlock); + InterlockedOr((LONG*)&m_ThreadTasks, TT_CleanupSyncBlock); } void ResetSyncBlockCleanup() { LIMITED_METHOD_CONTRACT; - FastInterlockAnd((ULONG *)&m_ThreadTasks, ~TT_CleanupSyncBlock); + InterlockedAnd((LONG*)&m_ThreadTasks, ~TT_CleanupSyncBlock); } #ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT @@ -1157,14 +1157,14 @@ class Thread void SetCoInitialized() { LIMITED_METHOD_CONTRACT; - FastInterlockOr((ULONG *)&m_State, TS_CoInitialized); - FastInterlockAnd((ULONG*)&m_ThreadTasks, ~TT_CallCoInitialize); + InterlockedOr((LONG*)&m_State, TS_CoInitialized); + InterlockedAnd((LONG*)&m_ThreadTasks, ~TT_CallCoInitialize); } void ResetCoInitialized() { LIMITED_METHOD_CONTRACT; - FastInterlockAnd((ULONG *)&m_State,~TS_CoInitialized); + ResetThreadState(TS_CoInitialized); } #ifdef FEATURE_COMINTEROP @@ -1190,13 +1190,13 @@ class Thread void SetRequiresCoInitialize() { LIMITED_METHOD_CONTRACT; - FastInterlockOr((ULONG *)&m_ThreadTasks, TT_CallCoInitialize); + InterlockedOr((LONG*)&m_ThreadTasks, TT_CallCoInitialize); } void ResetRequiresCoInitialize() { LIMITED_METHOD_CONTRACT; - FastInterlockAnd((ULONG *)&m_ThreadTasks,~TT_CallCoInitialize); + InterlockedAnd((LONG*)&m_ThreadTasks,~TT_CallCoInitialize); } void CleanupCOMState(); @@ -1265,7 +1265,7 @@ class Thread void SetExecutingOnAltStack() { LIMITED_METHOD_CONTRACT; - FastInterlockOr((ULONG *) &m_State, TS_ExecutingOnAltStack); + SetThreadState(TS_ExecutingOnAltStack); } DWORD IsBackground() @@ -2103,7 +2103,7 @@ class Thread #else // _DEBUG return #endif //_DEBUG - FastInterlockIncrement((LONG*)&m_ExternalRefCount); + InterlockedIncrement((LONG*)&m_ExternalRefCount); #ifdef _DEBUG // This should never be called on a thread being destroyed @@ -2121,7 +2121,7 @@ class Thread return #endif //_DEBUG - FastInterlockDecrement((LONG*)&m_ExternalRefCount); + InterlockedDecrement((LONG*)&m_ExternalRefCount); #ifdef _DEBUG // This should never cause the last reference on the thread to be released @@ -2321,7 +2321,7 @@ class Thread void SetIsThreadPoolThread() { LIMITED_METHOD_CONTRACT; - FastInterlockOr((ULONG *)&m_State, Thread::TS_TPWorkerThread); + SetThreadState(TS_TPWorkerThread); } // public suspend functions. System ones are internal, like for GC. User ones @@ -2356,14 +2356,14 @@ class Thread static void AcquireAbortControl(Thread *pThread) { LIMITED_METHOD_CONTRACT; - FastInterlockIncrement (&pThread->m_AbortController); + InterlockedIncrement (&pThread->m_AbortController); } static void ReleaseAbortControl(Thread *pThread) { LIMITED_METHOD_CONTRACT; _ASSERTE (pThread->m_AbortController > 0); - FastInterlockDecrement (&pThread->m_AbortController); + InterlockedDecrement (&pThread->m_AbortController); } typedef Holder AbortControlHolder; @@ -2444,7 +2444,7 @@ class Thread if (IsRudeAbort()) { m_fRudeAbortInitiated = TRUE; } - FastInterlockOr((ULONG *)&m_State, TS_AbortInitiated); + SetThreadState(TS_AbortInitiated); // The following should be factored better, but I'm looking for a minimal V1 change. ResetUserInterrupted(); } @@ -2452,7 +2452,7 @@ class Thread inline void ResetAbortInitiated() { LIMITED_METHOD_CONTRACT; - FastInterlockAnd((ULONG *)&m_State, ~TS_AbortInitiated); + ResetThreadState(TS_AbortInitiated); m_fRudeAbortInitiated = FALSE; } @@ -2822,13 +2822,13 @@ class Thread { WRAPPER_NO_CONTRACT; Thread *pThread = GetThread(); - FastInterlockIncrement((LONG*)&pThread->m_PreventAsync); + InterlockedIncrement((LONG*)&pThread->m_PreventAsync); } static void DecPreventAsync() { WRAPPER_NO_CONTRACT; Thread *pThread = GetThread(); - FastInterlockDecrement((LONG*)&pThread->m_PreventAsync); + InterlockedDecrement((LONG*)&pThread->m_PreventAsync); } bool IsAsyncPrevented() @@ -3100,7 +3100,7 @@ class Thread // ThreadState newState = (ThreadState)(oldState & ~(TS_DebugSuspendPending | TS_SyncSuspended)); - if (FastInterlockCompareExchange((LONG *)&m_State, newState, oldState) == (LONG)oldState) + if (InterlockedCompareExchange((LONG *)&m_State, newState, oldState) == (LONG)oldState) { break; } @@ -3124,7 +3124,7 @@ class Thread if (m_State & TS_Hijacked) { *m_ppvHJRetAddrPtr = m_pvHJRetAddr; - FastInterlockAnd((ULONG *) &m_State, ~TS_Hijacked); + ResetThreadState(TS_Hijacked); } #endif } @@ -3192,7 +3192,7 @@ class Thread void ResetUserInterrupted() { LIMITED_METHOD_CONTRACT; - FastInterlockExchange(&m_UserInterrupt, 0); + InterlockedExchange(&m_UserInterrupt, 0); } void HandleThreadInterrupt(); @@ -3264,7 +3264,7 @@ class Thread || m_OSThreadId == 0xbaadf00d || ::MatchThreadHandleToOsId(h, (DWORD)m_OSThreadId) ); #endif - FastInterlockExchangePointer(&m_ThreadHandle, h); + InterlockedExchangeT(&m_ThreadHandle, h); } // We maintain a correspondence between this object, the ThreadId and ThreadHandle @@ -4088,12 +4088,12 @@ class Thread if(HasPendingGCStressInstructionUpdate()) { - *ppbDestCode = FastInterlockExchangePointer(&m_pbDestCode, NULL); + *ppbDestCode = InterlockedExchangeT(&m_pbDestCode, NULL); if(*ppbDestCode != NULL) { result = true; - *ppbSrcCode = FastInterlockExchangePointer(&m_pbSrcCode, NULL); + *ppbSrcCode = InterlockedExchangeT(&m_pbSrcCode, NULL); CONSISTENCY_CHECK(*ppbSrcCode != NULL); } @@ -4141,7 +4141,7 @@ class Thread { LIMITED_METHOD_CONTRACT; _ASSERTE(!m_debuggerActivePatchSkipper.Load()); - FastInterlockExchangePointer(m_debuggerActivePatchSkipper.GetPointer(), patchSkipper); + InterlockedExchangeT(m_debuggerActivePatchSkipper.GetPointer(), patchSkipper); _ASSERTE(m_debuggerActivePatchSkipper.Load()); } @@ -4149,7 +4149,7 @@ class Thread { LIMITED_METHOD_CONTRACT; _ASSERTE(m_debuggerActivePatchSkipper.Load()); - FastInterlockExchangePointer(m_debuggerActivePatchSkipper.GetPointer(), NULL); + InterlockedExchangeT(m_debuggerActivePatchSkipper.GetPointer(), NULL); _ASSERTE(!m_debuggerActivePatchSkipper.Load()); } @@ -4968,9 +4968,9 @@ DWORD MsgWaitHelper(int numWaiters, HANDLE* phEvent, BOOL bWaitAll, DWORD millis inline void Thread::MarkForDebugSuspend(void) { WRAPPER_NO_CONTRACT; - if (!(m_State & TS_DebugSuspendPending)) + if (!HasThreadState(TS_DebugSuspendPending)) { - FastInterlockOr((ULONG *) &m_State, TS_DebugSuspendPending); + SetThreadState(TS_DebugSuspendPending); ThreadStore::TrapReturningThreads(TRUE); } } @@ -4981,7 +4981,7 @@ inline void Thread::MarkForDebugSuspend(void) inline void Thread::IncrementTraceCallCount() { WRAPPER_NO_CONTRACT; - FastInterlockIncrement(&m_TraceCallCount); + InterlockedIncrement(&m_TraceCallCount); ThreadStore::TrapReturningThreads(TRUE); } @@ -4989,7 +4989,7 @@ inline void Thread::DecrementTraceCallCount() { WRAPPER_NO_CONTRACT; ThreadStore::TrapReturningThreads(FALSE); - FastInterlockDecrement(&m_TraceCallCount); + InterlockedDecrement(&m_TraceCallCount); } // When we enter an Object.Wait() we are logically inside the synchronized @@ -6092,7 +6092,7 @@ class ThreadStateHolder if (m_fNeed) { Thread *pThread = GetThread(); - FastInterlockAnd((ULONG *) &pThread->m_State, ~m_state); + InterlockedAnd((LONG*)&pThread->m_State, ~m_state); } } private: diff --git a/src/coreclr/vm/threadsuspend.cpp b/src/coreclr/vm/threadsuspend.cpp index a9a1b46daad51a..d0725699893e82 100644 --- a/src/coreclr/vm/threadsuspend.cpp +++ b/src/coreclr/vm/threadsuspend.cpp @@ -1405,7 +1405,7 @@ Thread::UserAbort(EEPolicy::ThreadAbortTypes abortType, DWORD timeout) // to erect appropriate memory barriers. So the interlocked operation // below ensures that any future reads on this thread will happen after // any earlier writes on a different thread have taken effect. - FastInterlockOr((DWORD*)&m_State, 0); + InterlockedOr((LONG*)&m_State, 0); #else // DISABLE_THREADSUSPEND @@ -1673,7 +1673,7 @@ void Thread::LockAbortRequest(Thread* pThread) } YieldProcessorNormalized(); // indicate to the processor that we are spinning } - if (FastInterlockCompareExchange(&(pThread->m_AbortRequestLock),1,0) == 0) { + if (InterlockedCompareExchange(&(pThread->m_AbortRequestLock),1,0) == 0) { return; } __SwitchToThread(0, ++dwSwitchCount); @@ -1685,7 +1685,7 @@ void Thread::UnlockAbortRequest(Thread *pThread) LIMITED_METHOD_CONTRACT; _ASSERTE (pThread->m_AbortRequestLock == 1); - FastInterlockExchange(&pThread->m_AbortRequestLock, 0); + InterlockedExchange(&pThread->m_AbortRequestLock, 0); } void Thread::MarkThreadForAbort(EEPolicy::ThreadAbortTypes abortType) @@ -1735,7 +1735,7 @@ void Thread::SetAbortRequestBit() { break; } - if (FastInterlockCompareExchange((LONG*)&m_State, curValue|TS_AbortRequested, curValue) == curValue) + if (InterlockedCompareExchange((LONG*)&m_State, curValue|TS_AbortRequested, curValue) == curValue) { ThreadStore::TrapReturningThreads(TRUE); @@ -1765,7 +1765,7 @@ void Thread::RemoveAbortRequestBit() { break; } - if (FastInterlockCompareExchange((LONG*)&m_State, curValue&(~TS_AbortRequested), curValue) == curValue) + if (InterlockedCompareExchange((LONG*)&m_State, curValue&(~TS_AbortRequested), curValue) == curValue) { ThreadStore::TrapReturningThreads(FALSE); @@ -1796,7 +1796,7 @@ void Thread::UnmarkThreadForAbort() if (IsAbortRequested()) { RemoveAbortRequestBit(); - FastInterlockAnd((DWORD*)&m_State,~(TS_AbortInitiated)); + ResetThreadState(TS_AbortInitiated); m_fRudeAbortInitiated = FALSE; ResetUserInterrupted(); } @@ -2174,7 +2174,7 @@ void Thread::RareDisablePreemptiveGC() END_GCX_ASSERT_PREEMP; // disable preemptive gc. - FastInterlockOr(&m_fPreemptiveGCDisabled, 1); + InterlockedOr((LONG*)&m_fPreemptiveGCDisabled, 1); // The fact that we check whether 'this' is the GC thread may seem // strange. After all, we determined this before entering the method. @@ -2214,7 +2214,7 @@ void Thread::HandleThreadAbort () { ResetThreadState ((ThreadState)(TS_Interrupted | TS_Interruptible)); // We are going to abort. Abort satisfies Thread.Interrupt requirement. - FastInterlockExchange (&m_UserInterrupt, 0); + InterlockedExchange (&m_UserInterrupt, 0); // generate either a ThreadAbort exception STRESS_LOG1(LF_APPDOMAIN, LL_INFO100, "Thread::HandleThreadAbort throwing abort for %x\n", GetThreadId()); @@ -2258,7 +2258,7 @@ void Thread::PreWorkForThreadAbort() SetAbortInitiated(); // if an abort and interrupt happen at the same time (e.g. on a sleeping thread), // the abort is favored. But we do need to reset the interrupt bits. - FastInterlockAnd((ULONG *) &m_State, ~(TS_Interruptible | TS_Interrupted)); + ResetThreadState((ThreadState)(TS_Interruptible | TS_Interrupted)); ResetUserInterrupted(); } @@ -2435,7 +2435,7 @@ void ThreadStore::TrapReturningThreads(BOOL yes) ForbidSuspendThreadHolder suspend; DWORD dwSwitchCount = 0; - while (1 == FastInterlockExchange(&g_fTrapReturningThreadsLock, 1)) + while (1 == InterlockedExchange(&g_fTrapReturningThreadsLock, 1)) { // we can't forbid suspension while we are sleeping and don't hold the lock // this will trigger an assert on SQLCLR but is a general issue @@ -2448,11 +2448,11 @@ void ThreadStore::TrapReturningThreads(BOOL yes) { #ifdef _DEBUG CounterHolder trtHolder(&g_trtChgInFlight); - FastInterlockIncrement(&g_trtChgStamp); + InterlockedIncrement(&g_trtChgStamp); #endif GCHeapUtilities::GetGCHeap()->SetSuspensionPending(true); - FastInterlockIncrement ((LONG *)&g_TrapReturningThreads); + InterlockedIncrement ((LONG *)&g_TrapReturningThreads); _ASSERTE(g_TrapReturningThreads > 0); #ifdef _DEBUG @@ -2461,7 +2461,7 @@ void ThreadStore::TrapReturningThreads(BOOL yes) } else { - FastInterlockDecrement ((LONG *)&g_TrapReturningThreads); + InterlockedDecrement ((LONG *)&g_TrapReturningThreads); GCHeapUtilities::GetGCHeap()->SetSuspensionPending(false); _ASSERTE(g_TrapReturningThreads >= 0); } @@ -4181,7 +4181,7 @@ bool Thread::SysStartSuspendForDebug(AppDomain *pAppDomain) // we need to erect appropriate memory barriers. So the interlocked // operation below ensures that any future reads on this thread will // happen after any earlier writes on a different thread. - FastInterlockOr(&thread->m_fPreemptiveGCDisabled, 0); + InterlockedOr((LONG*)&thread->m_fPreemptiveGCDisabled, 0); } else { @@ -4217,7 +4217,7 @@ bool Thread::SysStartSuspendForDebug(AppDomain *pAppDomain) #endif // !DISABLE_THREADSUSPEND && FEATURE_HIJACK && !TARGET_UNIX // Remember that this thread will be running to a safe point - FastInterlockIncrement(&m_DebugWillSyncCount); + InterlockedIncrement(&m_DebugWillSyncCount); // When the thread reaches a safe place, it will wait // on the DebugSuspendEvent which clients can set when they @@ -4277,7 +4277,7 @@ bool Thread::SysStartSuspendForDebug(AppDomain *pAppDomain) thread->IsInForbidSuspendForDebuggerRegion()) { // Remember that this thread will be running to a safe point - FastInterlockIncrement(&m_DebugWillSyncCount); + InterlockedIncrement(&m_DebugWillSyncCount); thread->SetThreadState(TS_DebugWillSync); } @@ -4298,7 +4298,7 @@ bool Thread::SysStartSuspendForDebug(AppDomain *pAppDomain) // thread to sync. // - if (FastInterlockDecrement(&m_DebugWillSyncCount) < 0) + if (InterlockedDecrement(&m_DebugWillSyncCount) < 0) { LOG((LF_CORDB, LL_INFO1000, "SUSPEND: all threads sync before return.\n")); @@ -4362,7 +4362,7 @@ bool Thread::SysSweepThreadsForDebug(bool forceSync) // we need to erect appropriate memory barriers. So the interlocked // operation below ensures that any future reads on this thread will // happen after any earlier writes on a different thread. - FastInterlockOr(&thread->m_fPreemptiveGCDisabled, 0); + InterlockedOr((LONG*)&thread->m_fPreemptiveGCDisabled, 0); if (!thread->m_fPreemptiveGCDisabled) { if (thread->IsInForbidSuspendForDebuggerRegion()) @@ -4472,8 +4472,8 @@ bool Thread::SysSweepThreadsForDebug(bool forceSync) // The thread is synced. Remove the sync bits and dec the sync count. Label_MarkThreadAsSynced: - FastInterlockAnd((ULONG *) &thread->m_State, ~TS_DebugWillSync); - if (FastInterlockDecrement(&m_DebugWillSyncCount) < 0) + thread->ResetThreadState(TS_DebugWillSync); + if (InterlockedDecrement(&m_DebugWillSyncCount) < 0) { // If that was the last thread, then the CLR is synced. // We return while own the thread store lock. We return true now, which indicates this to the caller. @@ -4602,7 +4602,7 @@ BOOL Thread::WaitSuspendEventsHelper(void) while (oldState & TS_DebugSuspendPending) { ThreadState newState = (ThreadState)(oldState | TS_SyncSuspended); - if (FastInterlockCompareExchange((LONG *)&m_State, newState, oldState) == (LONG)oldState) + if (InterlockedCompareExchange((LONG *)&m_State, newState, oldState) == (LONG)oldState) { result = m_DebugSuspendEvent.Wait(INFINITE,FALSE); #if _DEBUG @@ -4656,7 +4656,7 @@ void Thread::WaitSuspendEvents(BOOL fDoWait) // ThreadState newState = (ThreadState)(oldState & ~(TS_DebugSuspendPending | TS_SyncSuspended)); - if (FastInterlockCompareExchange((LONG *)&m_State, newState, oldState) == (LONG)oldState) + if (InterlockedCompareExchange((LONG *)&m_State, newState, oldState) == (LONG)oldState) { // // We are done. @@ -4758,7 +4758,7 @@ void Thread::HijackThread(ReturnKind returnKind, ExecutionState *esb) // Bash the stack to return to one of our stubs *esb->m_ppvRetAddrPtr = pvHijackAddr; - FastInterlockOr((ULONG *) &m_State, TS_Hijacked); + SetThreadState(TS_Hijacked); } // If we are unhijacking another thread (not the current thread), then the caller is responsible for @@ -4786,7 +4786,7 @@ void Thread::UnhijackThread() STRESS_LOG2(LF_SYNC, LL_INFO100, "Unhijacking return address 0x%p for thread %p\n", m_pvHJRetAddr, this); // restore the return address and clear the flag *m_ppvHJRetAddrPtr = m_pvHJRetAddr; - FastInterlockAnd((ULONG *) &m_State, ~TS_Hijacked); + ResetThreadState(TS_Hijacked); // But don't touch m_pvHJRetAddr. We may need that to resume a thread that // is currently hijacked! @@ -5499,7 +5499,7 @@ void Thread::MarkForSuspension(ULONG bit) _ASSERTE((m_State & bit) == 0); - FastInterlockOr((ULONG *) &m_State, bit); + InterlockedOr((LONG*)&m_State, bit); ThreadStore::TrapReturningThreads(TRUE); } @@ -5520,7 +5520,7 @@ void Thread::UnmarkForSuspension(ULONG mask) // we decrement the global first to be able to satisfy the assert from DbgFindThread ThreadStore::TrapReturningThreads(FALSE); - FastInterlockAnd((ULONG *) &m_State, mask); + InterlockedAnd((LONG*)&m_State, mask); } //---------------------------------------------------------------------------- diff --git a/src/coreclr/vm/typedesc.cpp b/src/coreclr/vm/typedesc.cpp index 89c0e53e6ba88e..41abdebda71ae8 100644 --- a/src/coreclr/vm/typedesc.cpp +++ b/src/coreclr/vm/typedesc.cpp @@ -506,7 +506,7 @@ OBJECTREF ParamTypeDesc::GetManagedClassObject() // Only the winner can set m_hExposedClassObject from NULL. LOADERHANDLE hExposedClassObject = pLoaderAllocator->AllocateHandle(refClass); - if (FastInterlockCompareExchangePointer(&m_hExposedClassObject, hExposedClassObject, static_cast(NULL))) + if (InterlockedCompareExchangeT(&m_hExposedClassObject, hExposedClassObject, static_cast(NULL))) { pLoaderAllocator->FreeHandle(hExposedClassObject); } @@ -668,7 +668,7 @@ void TypeDesc::DoFullyLoad(Generics::RecursionGraph *pVisited, ClassLoadLevel le switch (level) { case CLASS_DEPENDENCIES_LOADED: - FastInterlockOr(&m_typeAndFlags, TypeDesc::enum_flag_DependenciesLoaded); + InterlockedOr((LONG*)&m_typeAndFlags, TypeDesc::enum_flag_DependenciesLoaded); break; case CLASS_LOADED: @@ -1624,7 +1624,7 @@ OBJECTREF TypeVarTypeDesc::GetManagedClassObject() // Only the winner can set m_hExposedClassObject from NULL. LOADERHANDLE hExposedClassObject = pLoaderAllocator->AllocateHandle(refClass); - if (FastInterlockCompareExchangePointer(&m_hExposedClassObject, hExposedClassObject, static_cast(NULL))) + if (InterlockedCompareExchangeT(&m_hExposedClassObject, hExposedClassObject, static_cast(NULL))) { pLoaderAllocator->FreeHandle(hExposedClassObject); } diff --git a/src/coreclr/vm/typedesc.h b/src/coreclr/vm/typedesc.h index 951cb8cc117004..19833eede708bb 100644 --- a/src/coreclr/vm/typedesc.h +++ b/src/coreclr/vm/typedesc.h @@ -145,7 +145,7 @@ class TypeDesc VOID SetIsFullyLoaded() { LIMITED_METHOD_CONTRACT; - FastInterlockAnd(&m_typeAndFlags, ~TypeDesc::enum_flag_IsNotFullyLoaded); + InterlockedAnd((LONG*)&m_typeAndFlags, ~TypeDesc::enum_flag_IsNotFullyLoaded); } ClassLoadLevel GetLoadLevel(); diff --git a/src/coreclr/vm/typehash.h b/src/coreclr/vm/typehash.h index b705bd2a7801ad..b706ee64a44932 100644 --- a/src/coreclr/vm/typehash.h +++ b/src/coreclr/vm/typehash.h @@ -73,8 +73,8 @@ class EETypeHashTable : public DacEnumerableHashTableused < counter_block::MAX_COUNTER_ENTRIES)) { - counter_index = FastInterlockIncrement((LONG*)&cur_block->used) - 1; + counter_index = InterlockedIncrement((LONG*)&cur_block->used) - 1; if (counter_index < counter_block::MAX_COUNTER_ENTRIES) { // Typical case we allocate the next free counter in the block @@ -3151,7 +3151,7 @@ BOOL Prober::GrabEntry(size_t entryValue) { LIMITED_METHOD_CONTRACT; - return FastInterlockCompareExchangePointer(&base[index], + return InterlockedCompareExchangeT(&base[index], entryValue, static_cast(CALL_STUB_EMPTY_ENTRY)) == CALL_STUB_EMPTY_ENTRY; } @@ -3165,7 +3165,7 @@ inline void FastTable::IncrementCount() // at the same time and one increment is lost, then the size will be inaccurate and // BucketTable::GetMoreSpace will never succeed, resulting in an infinite loop trying // to add a new entry. - FastInterlockIncrement((LONG *)&contents[CALL_STUB_COUNT_INDEX]); + InterlockedIncrement((LONG *)&contents[CALL_STUB_COUNT_INDEX]); } size_t FastTable::Add(size_t entry, Prober* probe) @@ -3251,7 +3251,7 @@ BOOL BucketTable::GetMoreSpace(const Prober* p) // replacing the entry, then we will just put the new bucket we just created in the // dead list instead of risking a race condition which would put a duplicate of the old // bucket in the dead list (and even possibly cause a cyclic list). - if (FastInterlockCompareExchangePointer(reinterpret_cast(&buckets[index]), newBucket, oldBucket) != oldBucket) + if (InterlockedCompareExchangeT(reinterpret_cast(&buckets[index]), newBucket, oldBucket) != oldBucket) oldBucket = newBucket; // Link the old onto the "to be reclaimed" list. @@ -3260,7 +3260,7 @@ BOOL BucketTable::GetMoreSpace(const Prober* p) do { list = VolatileLoad(&dead); oldBucket->contents[CALL_STUB_DEAD_LINK] = (size_t) list; - } while (FastInterlockCompareExchangePointer(&dead, oldBucket, list) != list); + } while (InterlockedCompareExchangeT(&dead, oldBucket, list) != list); #ifdef _DEBUG { @@ -3318,7 +3318,7 @@ void BucketTable::Reclaim() //We are assuming that we are assuming the actually having to do anything is rare //so that the interlocked overhead is acceptable. If this is not true, then //we need to examine exactly how and when we may be called during shutdown. - if (FastInterlockCompareExchangePointer(&dead, NULL, list) != list) + if (InterlockedCompareExchangeT(&dead, NULL, list) != list) return; #ifdef _DEBUG @@ -3393,7 +3393,7 @@ BOOL BucketTable::SetUpProber(size_t keyA, size_t keyB, Prober *prober) // Doing an interlocked exchange here ensures that if someone has raced and beaten us to // replacing the entry, then we will free the new bucket we just created. - bucket = FastInterlockCompareExchangePointer(&buckets[index], reinterpret_cast(newBucket), static_cast(CALL_STUB_EMPTY_ENTRY)); + bucket = InterlockedCompareExchangeT(&buckets[index], reinterpret_cast(newBucket), static_cast(CALL_STUB_EMPTY_ENTRY)); if (bucket == CALL_STUB_EMPTY_ENTRY) { // We successfully wrote newBucket into buckets[index], overwritting the CALL_STUB_EMPTY_ENTRY value diff --git a/src/coreclr/vm/win32threadpool.cpp b/src/coreclr/vm/win32threadpool.cpp index f4aa3cee7929f8..e87e80b2f2f833 100644 --- a/src/coreclr/vm/win32threadpool.cpp +++ b/src/coreclr/vm/win32threadpool.cpp @@ -1274,14 +1274,14 @@ void ThreadpoolMgr::EnsureGateThreadRunning() // Prevent the gate thread from exiting, if it hasn't already done so. If it has, we'll create it on the next iteration of // this loop. // - FastInterlockCompareExchange(&GateThreadStatus, GATE_THREAD_STATUS_REQUESTED, GATE_THREAD_STATUS_WAITING_FOR_REQUEST); + InterlockedCompareExchange(&GateThreadStatus, GATE_THREAD_STATUS_REQUESTED, GATE_THREAD_STATUS_WAITING_FOR_REQUEST); break; case GATE_THREAD_STATUS_NOT_RUNNING: // // We need to create a new gate thread // - if (FastInterlockCompareExchange(&GateThreadStatus, GATE_THREAD_STATUS_REQUESTED, GATE_THREAD_STATUS_NOT_RUNNING) == GATE_THREAD_STATUS_NOT_RUNNING) + if (InterlockedCompareExchange(&GateThreadStatus, GATE_THREAD_STATUS_REQUESTED, GATE_THREAD_STATUS_NOT_RUNNING) == GATE_THREAD_STATUS_NOT_RUNNING) { if (!CreateGateThread()) { @@ -1324,7 +1324,7 @@ bool ThreadpoolMgr::ShouldGateThreadKeepRunning() // // Switch to WAITING_FOR_REQUEST, and see if we had a request since the last check. // - LONG previousStatus = FastInterlockExchange(&GateThreadStatus, GATE_THREAD_STATUS_WAITING_FOR_REQUEST); + LONG previousStatus = InterlockedExchange(&GateThreadStatus, GATE_THREAD_STATUS_WAITING_FOR_REQUEST); if (previousStatus == GATE_THREAD_STATUS_WAITING_FOR_REQUEST) { @@ -1361,7 +1361,7 @@ bool ThreadpoolMgr::ShouldGateThreadKeepRunning() // It looks like we shouldn't be running. But another thread may now tell us to run. If so, they will set GateThreadStatus // back to GATE_THREAD_STATUS_REQUESTED. // - previousStatus = FastInterlockCompareExchange(&GateThreadStatus, GATE_THREAD_STATUS_NOT_RUNNING, GATE_THREAD_STATUS_WAITING_FOR_REQUEST); + previousStatus = InterlockedCompareExchange(&GateThreadStatus, GATE_THREAD_STATUS_NOT_RUNNING, GATE_THREAD_STATUS_WAITING_FOR_REQUEST); if (previousStatus == GATE_THREAD_STATUS_WAITING_FOR_REQUEST) return false; } diff --git a/src/coreclr/vm/win32threadpool.h b/src/coreclr/vm/win32threadpool.h index 88453a002df0ba..b08d7ca32e9c2f 100644 --- a/src/coreclr/vm/win32threadpool.h +++ b/src/coreclr/vm/win32threadpool.h @@ -147,7 +147,7 @@ class ThreadpoolMgr // VolatileLoad may result in torn read Counts result; #ifndef DACCESS_COMPILE - result.AsLongLong = FastInterlockCompareExchangeLong(&counts.AsLongLong, 0, 0); + result.AsLongLong = InterlockedCompareExchange64(&counts.AsLongLong, 0, 0); ValidateCounts(result); #else result.AsLongLong = 0; //prevents prefast warning for DAC builds @@ -180,7 +180,7 @@ class ThreadpoolMgr LIMITED_METHOD_CONTRACT; Counts result; #ifndef DACCESS_COMPILE - result.AsLongLong = FastInterlockCompareExchangeLong(&counts.AsLongLong, newCounts.AsLongLong, oldCounts.AsLongLong); + result.AsLongLong = InterlockedCompareExchange64(&counts.AsLongLong, newCounts.AsLongLong, oldCounts.AsLongLong); if (result == oldCounts) { // can only do validation on success; if we failed, it may have been due to a previous @@ -699,7 +699,7 @@ class ThreadpoolMgr DWORD dwSwitchCount = 0; - while(lock != 0 || FastInterlockExchange( &lock, 1 ) != 0) + while(lock != 0 || InterlockedExchange( &lock, 1 ) != 0) { YieldProcessorNormalized(); // indicate to the processor that we are spinning From 446e5ad932ba693d64225bd2939e977832a642e2 Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Wed, 15 Jun 2022 18:17:26 -0700 Subject: [PATCH 146/337] JIT: rework optCanonicalizeLoop (#70792) Rework loop canonicalization in anticipation of extending it to handle non-loop edges like those seen in #70802 (details in #70569). The code to fix up flow out of `h` was not needed and has been removed. We now assert upstream that no such fix up will be needed. --- src/coreclr/jit/optimizer.cpp | 110 +++++++++++++++++++++------------- 1 file changed, 69 insertions(+), 41 deletions(-) diff --git a/src/coreclr/jit/optimizer.cpp b/src/coreclr/jit/optimizer.cpp index 4cf5db0a250d05..de2459c862e9a3 100644 --- a/src/coreclr/jit/optimizer.cpp +++ b/src/coreclr/jit/optimizer.cpp @@ -2874,38 +2874,49 @@ bool Compiler::optIsLoopEntry(BasicBlock* block) const return false; } -// Canonicalize the loop nest rooted at parent loop 'loopInd'. -// Returns 'true' if the flow graph is modified. +//----------------------------------------------------------------------------- +// optCanonicalizeLoopNest: Canonicalize a loop nest +// +// Arguments: +// loopInd - index of outermost loop in the nest +// +// Returns: +// true if the flow graph was modified +// +// Notes: +// For loopInd and all contained loops, ensures each loop top's back edges +// do not come from nested loops. +// +// Will split top blocks and redirect edges if needed. +// bool Compiler::optCanonicalizeLoopNest(unsigned char loopInd) { - bool modified = false; - - // Is the top of the current loop in any nested loop? - if (optLoopTable[loopInd].lpTop->bbNatLoopNum != loopInd) - { - if (optCanonicalizeLoop(loopInd)) - { - modified = true; - } - } + bool modified = optCanonicalizeLoop(loopInd); for (unsigned char child = optLoopTable[loopInd].lpChild; // child != BasicBlock::NOT_IN_LOOP; // child = optLoopTable[child].lpSibling) { - if (optCanonicalizeLoopNest(child)) - { - modified = true; - } + modified |= optCanonicalizeLoopNest(child); } return modified; } +//----------------------------------------------------------------------------- +// optCanonicalizeLoop: ensure that each loop top's back edges do not come +// from nested loops. +// +// Arguments: +// loopInd - index of the loop to consider +// +// Returns: +// true if flow changes were made +// bool Compiler::optCanonicalizeLoop(unsigned char loopInd) { // Is the top uniquely part of the current loop? - BasicBlock* t = optLoopTable[loopInd].lpTop; + BasicBlock* const t = optLoopTable[loopInd].lpTop; if (t->bbNatLoopNum == loopInd) { @@ -2993,12 +3004,28 @@ bool Compiler::optCanonicalizeLoop(unsigned char loopInd) // outside of and disjoint with the "try" region of the back edge. However, to // simplify things, we disqualify this type of loop, so we should never see this here. - BasicBlock* h = optLoopTable[loopInd].lpHead; - BasicBlock* b = optLoopTable[loopInd].lpBottom; + BasicBlock* const h = optLoopTable[loopInd].lpHead; + BasicBlock* const b = optLoopTable[loopInd].lpBottom; // The loop must be entirely contained within a single handler region. assert(BasicBlock::sameHndRegion(t, b)); + // We expect h to be already "canonical" -- that is, it falls through to t + // and is not a degenerate BBJ_COND (both branches and falls through to t) + // or a side entry to the loop. + // + // Because of this, introducing a block before t automatically gives us + // the right flow out of h. + // + assert(h->bbNext == t); + assert(h->bbFallsThrough()); + assert((h->bbJumpKind == BBJ_NONE) || (h->bbJumpKind == BBJ_COND)); + if (h->bbJumpKind == BBJ_COND) + { + BasicBlock* const hj = h->bbJumpDest; + assert((hj->bbNum < t->bbNum) || (hj->bbNum > b->bbNum)); + } + // If the bottom block is in the same "try" region, then we extend the EH // region. Otherwise, we add the new block outside the "try" region. const bool extendRegion = BasicBlock::sameTryRegion(t, b); @@ -3016,9 +3043,12 @@ bool Compiler::optCanonicalizeLoop(unsigned char loopInd) // a call to fgUpdateChangedFlowGraph which will recompute the reachability sets anyway. // Redirect the "bottom" of the current loop to "newT". - BlockToBlockMap* blockMap = new (getAllocator(CMK_LoopOpt)) BlockToBlockMap(getAllocator(CMK_LoopOpt)); + BlockToBlockMap* const blockMap = new (getAllocator(CMK_LoopOpt)) BlockToBlockMap(getAllocator(CMK_LoopOpt)); blockMap->Set(t, newT); optRedirectBlock(b, blockMap); + JITDUMP("in optCanonicalizeLoop: redirecting bottom->top backedge " FMT_BB " -> " FMT_BB " to " FMT_BB " -> " FMT_BB + "\n", + b->bbNum, t->bbNum, b->bbNum, newT->bbNum); // Redirect non-loop preds of "t" to also go to "newT". Inner loops that also branch to "t" should continue // to do so. However, there maybe be other predecessors from outside the loop nest that need to be updated @@ -3039,9 +3069,14 @@ bool Compiler::optCanonicalizeLoop(unsigned char loopInd) // outside-in, so we shouldn't encounter the new blocks at the loop boundaries, or in the predecessor lists. if (t->bbNum <= topPredBlock->bbNum && topPredBlock->bbNum <= b->bbNum) { - JITDUMP("in optCanonicalizeLoop: 'top' predecessor " FMT_BB " is in the range of " FMT_LP " (" FMT_BB - ".." FMT_BB "); not redirecting its bottom edge\n", - topPredBlock->bbNum, loopInd, t->bbNum, b->bbNum); + // Note we've already redirected b->t above. + // + if (topPredBlock->bbNum != b->bbNum) + { + JITDUMP("in optCanonicalizeLoop: in-loop 'top' predecessor " FMT_BB " is in the range of " FMT_LP + " (" FMT_BB ".." FMT_BB "); not redirecting its bottom edge\n", + topPredBlock->bbNum, loopInd, t->bbNum, b->bbNum); + } continue; } @@ -3073,10 +3108,12 @@ bool Compiler::optCanonicalizeLoop(unsigned char loopInd) } } + assert(h->bbNext == newT); assert(newT->bbNext == t); - // If it had been a do-while loop (top == entry), update entry, as well. - BasicBlock* origE = optLoopTable[loopInd].lpEntry; + // If loopInd is a do-while loop (top == entry), update entry as well. + // + BasicBlock* const origE = optLoopTable[loopInd].lpEntry; if (optLoopTable[loopInd].lpTop == origE) { optLoopTable[loopInd].lpEntry = newT; @@ -3088,24 +3125,10 @@ bool Compiler::optCanonicalizeLoop(unsigned char loopInd) JITDUMP("in optCanonicalizeLoop: made new block " FMT_BB " [%p] the new unique top of loop %d.\n", newT->bbNum, dspPtr(newT), loopInd); - // Make sure the head block still goes to the entry... - if (h->bbJumpKind == BBJ_NONE && h->bbNext != optLoopTable[loopInd].lpEntry) - { - h->bbJumpKind = BBJ_ALWAYS; - h->bbJumpDest = optLoopTable[loopInd].lpEntry; - } - else if (h->bbJumpKind == BBJ_COND && h->bbNext == newT && newT != optLoopTable[loopInd].lpEntry) - { - BasicBlock* h2 = fgNewBBafter(BBJ_ALWAYS, h, /*extendRegion*/ true); - optLoopTable[loopInd].lpHead = h2; - h2->bbJumpDest = optLoopTable[loopInd].lpEntry; - h2->bbStmtList = nullptr; - fgInsertStmtAtEnd(h2, fgNewStmtFromTree(gtNewOperNode(GT_NOP, TYP_VOID, nullptr))); - } - // If any loops nested in "loopInd" have the same head and entry as "loopInd", - // it must be the case that they were do-while's (since "h" fell through to the entry). + // it must be the case that they were also do-while's (since "h" fell through to the entry). // The new node "newT" becomes the head of such loops. + // for (unsigned char childLoop = optLoopTable[loopInd].lpChild; // childLoop != BasicBlock::NOT_IN_LOOP; // childLoop = optLoopTable[childLoop].lpSibling) @@ -3114,6 +3137,11 @@ bool Compiler::optCanonicalizeLoop(unsigned char loopInd) newT->bbJumpKind == BBJ_NONE && newT->bbNext == origE) { optUpdateLoopHead(childLoop, h, newT); + + // Fix pred list here, so when we walk preds of child loop tops + // we see the right blocks. + // + fgReplacePred(optLoopTable[childLoop].lpTop, h, newT); } } return true; From 205b7fff5d6dccad113952b13955fa6a378fcaf5 Mon Sep 17 00:00:00 2001 From: Andrew Au Date: Wed, 15 Jun 2022 20:03:52 -0700 Subject: [PATCH 147/337] Avoid infinite loop in case of heap corruption (#70759) Co-authored-by: Juan Hoyos Co-authored-by: Noah Falk --- src/coreclr/debug/daccess/dacdbiimpl.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/coreclr/debug/daccess/dacdbiimpl.cpp b/src/coreclr/debug/daccess/dacdbiimpl.cpp index 6ae350448755d5..9fb920f18ed609 100644 --- a/src/coreclr/debug/daccess/dacdbiimpl.cpp +++ b/src/coreclr/debug/daccess/dacdbiimpl.cpp @@ -6450,7 +6450,7 @@ HRESULT DacHeapWalker::MoveToNextObject() bool DacHeapWalker::GetSize(TADDR tMT, size_t &size) { - // With heap corruption, it's entierly possible that the MethodTable + // With heap corruption, it's entirely possible that the MethodTable // we get is bad. This could cause exceptions, which we will catch // and return false. This causes the heapwalker to move to the next // segment. @@ -6478,6 +6478,12 @@ bool DacHeapWalker::GetSize(TADDR tMT, size_t &size) size = AlignLarge(size); else size = Align(size); + + // If size == 0, it means we have a heap corruption and + // we will stuck in an infinite loop, so better fail the call now. + ret &= (0 < size); + // Also guard for cases where the size reported is too large and exceeds the high allocation mark. + ret &= ((tMT + size) <= mHeaps[mCurrHeap].Segments[mCurrSeg].End); } EX_CATCH { From a7052ac7302d828673f229298f841e850818e220 Mon Sep 17 00:00:00 2001 From: Thays Grazia Date: Thu, 16 Jun 2022 00:15:03 -0300 Subject: [PATCH 148/337] [wasm][debugger] Remove workaround to get pauseOnExceptions setting (#70748) --- src/libraries/sendtohelix-wasm.targets | 1 + .../BrowserDebugProxy/DevToolsHelper.cs | 3 +- .../Firefox/FirefoxExecutionContext.cs | 2 +- .../debugger/BrowserDebugProxy/MonoProxy.cs | 87 ++++++------------- 4 files changed, 29 insertions(+), 64 deletions(-) diff --git a/src/libraries/sendtohelix-wasm.targets b/src/libraries/sendtohelix-wasm.targets index 168d97a6afc2be..cd01a18d1c9656 100644 --- a/src/libraries/sendtohelix-wasm.targets +++ b/src/libraries/sendtohelix-wasm.targets @@ -3,6 +3,7 @@ <_workItemTimeout Condition="'$(Scenario)' == 'BuildWasmApps' and '$(_workItemTimeout)' == ''">01:30:00 <_workItemTimeout Condition="'$(NeedsToBuildWasmAppsOnHelix)' == 'true'">01:00:00 <_workItemTimeout Condition="'$(Scenario)' == 'WasmDebuggerTests'">01:00:00 + <_workItemTimeout Condition="'$(Scenario)' == 'WasmDebuggerTests' and '$(BrowserHost)' == 'windows'">01:30:00 <_workItemTimeout Condition="'$(Scenario)' == 'WasmTestOnBrowser' and '$(BrowserHost)' == 'windows'">00:45:00 true diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs b/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs index 960157f8176c2b..5c888238b7f248 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs @@ -401,11 +401,12 @@ internal enum PauseOnExceptionsKind internal class ExecutionContext { - public ExecutionContext(MonoSDBHelper sdbAgent, int id, object auxData) + public ExecutionContext(MonoSDBHelper sdbAgent, int id, object auxData, PauseOnExceptionsKind pauseOnExceptions) { Id = id; AuxData = auxData; SdbAgent = sdbAgent; + PauseOnExceptions = pauseOnExceptions; } public string DebugId { get; set; } diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/Firefox/FirefoxExecutionContext.cs b/src/mono/wasm/debugger/BrowserDebugProxy/Firefox/FirefoxExecutionContext.cs index 8f8561bb2a59ed..253b7316779537 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/Firefox/FirefoxExecutionContext.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/Firefox/FirefoxExecutionContext.cs @@ -14,7 +14,7 @@ internal sealed class FirefoxExecutionContext : ExecutionContext public string? GlobalName { get; set; } public Result LastDebuggerAgentBufferReceived { get; set; } - public FirefoxExecutionContext(MonoSDBHelper sdbAgent, int id, string actorName) : base(sdbAgent, id, actorName) + public FirefoxExecutionContext(MonoSDBHelper sdbAgent, int id, string actorName) : base(sdbAgent, id, actorName, PauseOnExceptionsKind.Unset) { ActorName = actorName; } diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs index 4ddddec96cb8db..c83f07ddaaae48 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs @@ -21,14 +21,14 @@ internal class MonoProxy : DevToolsProxy private IList urlSymbolServerList; private HashSet sessions = new HashSet(); protected Dictionary contexts = new Dictionary(); - private const string sPauseOnUncaught = "pause_on_uncaught"; - private const string sPauseOnCaught = "pause_on_caught"; public static HttpClient HttpClient => new HttpClient(); // index of the runtime in a same JS page/process public int RuntimeId { get; private init; } public bool JustMyCode { get; private set; } + private PauseOnExceptionsKind _defaultPauseOnExceptions { get; set; } + protected readonly ProxyOptions _options; public MonoProxy(ILogger logger, IList urlSymbolServerList, int runtimeId = 0, string loggerId = "", ProxyOptions options = null) : base(logger, loggerId) @@ -36,6 +36,7 @@ public MonoProxy(ILogger logger, IList urlSymbolServerList, int runtimeI this.urlSymbolServerList = urlSymbolServerList ?? new List(); RuntimeId = runtimeId; _options = options; + _defaultPauseOnExceptions = PauseOnExceptionsKind.Unset; } internal ExecutionContext GetContext(SessionId sessionId) @@ -160,55 +161,18 @@ protected override async Task AcceptEvent(SessionId sessionId, JObject par bool? is_default = aux_data["isDefault"]?.Value(); if (is_default == true) { - await OnDefaultContext(sessionId, new ExecutionContext(new MonoSDBHelper (this, logger, sessionId), id, aux_data), token); + await OnDefaultContext(sessionId, new ExecutionContext(new MonoSDBHelper (this, logger, sessionId), id, aux_data, _defaultPauseOnExceptions), token); } } return true; } - case "Runtime.exceptionThrown": - { - // Don't process events from sessions we aren't tracking - if (!contexts.TryGetValue(sessionId, out ExecutionContext context)) - return false; - - if (!context.IsRuntimeReady) - { - string exceptionError = args?["exceptionDetails"]?["exception"]?["value"]?.Value(); - if (exceptionError == sPauseOnUncaught || exceptionError == sPauseOnCaught) - return true; - } - break; - } - case "Debugger.paused": { // Don't process events from sessions we aren't tracking - if (!contexts.TryGetValue(sessionId, out ExecutionContext context)) + if (!contexts.ContainsKey(sessionId)) return false; - if (!context.IsRuntimeReady) - { - string reason = args?["reason"]?.Value(); - if (reason == "exception") - { - string exceptionError = args?["data"]?["value"]?.Value(); - if (exceptionError == sPauseOnUncaught) - { - await SendResume(sessionId, token); - if (context.PauseOnExceptions == PauseOnExceptionsKind.Unset) - context.PauseOnExceptions = PauseOnExceptionsKind.Uncaught; - return true; - } - if (exceptionError == sPauseOnCaught) - { - await SendResume(sessionId, token); - context.PauseOnExceptions = PauseOnExceptionsKind.All; - return true; - } - } - } - //TODO figure out how to stich out more frames and, in particular what happens when real wasm is on the stack string top_func = args?["callFrames"]?[0]?["functionName"]?.Value(); switch (top_func) { @@ -291,6 +255,13 @@ protected async Task IsRuntimeAlreadyReadyAlready(SessionId sessionId, Can Result res = await SendMonoCommand(sessionId, MonoCommands.IsRuntimeReady(RuntimeId), token); return res.Value?["result"]?["value"]?.Value() ?? false; } + private static PauseOnExceptionsKind GetPauseOnExceptionsStatusFromString(string state) + { + PauseOnExceptionsKind pauseOnException; + if (Enum.TryParse(state, true, out pauseOnException)) + return pauseOnException; + return PauseOnExceptionsKind.Unset; + } protected override async Task AcceptCommand(MessageId id, JObject parms, CancellationToken token) { @@ -302,7 +273,16 @@ protected override async Task AcceptCommand(MessageId id, JObject parms, C await AttachToTarget(id, token); if (!contexts.TryGetValue(id, out ExecutionContext context)) + { + if (method == "Debugger.setPauseOnExceptions") + { + string state = args["state"].Value(); + var pauseOnException = GetPauseOnExceptionsStatusFromString(state); + if (pauseOnException != PauseOnExceptionsKind.Unset) + _defaultPauseOnExceptions = pauseOnException; + } return false; + } switch (method) { @@ -513,13 +493,9 @@ protected override async Task AcceptCommand(MessageId id, JObject parms, C case "Debugger.setPauseOnExceptions": { string state = args["state"].Value(); - context.PauseOnExceptions = state switch - { - "all" => PauseOnExceptionsKind.All, - "uncaught" => PauseOnExceptionsKind.Uncaught, - "none" => PauseOnExceptionsKind.None, - _ => PauseOnExceptionsKind.Unset - }; + var pauseOnException = GetPauseOnExceptionsStatusFromString(state); + if (pauseOnException != PauseOnExceptionsKind.Unset) + context.PauseOnExceptions = pauseOnException; if (context.IsRuntimeReady) await context.SdbAgent.EnableExceptions(context.PauseOnExceptions, token); @@ -1784,23 +1760,10 @@ private async Task AttachToTarget(SessionId sessionId, CancellationToken token) // see https://github.com/mono/mono/issues/19549 for background if (sessions.Add(sessionId)) { - string checkUncaughtExceptions = string.Empty; - string checkCaughtExceptions = string.Empty; - - //we only need this check if it's a non-vs debugging - if (sessionId == SessionId.Null) - { - if (!contexts.TryGetValue(sessionId, out ExecutionContext context) || context.PauseOnExceptions == PauseOnExceptionsKind.Unset) - { - checkUncaughtExceptions = $"throw \"{sPauseOnUncaught}\";"; - checkCaughtExceptions = $"try {{throw \"{sPauseOnCaught}\";}} catch {{}}"; - } - } - await SendMonoCommand(sessionId, new MonoCommands("globalThis.dotnetDebugger = true"), token); Result res = await SendCommand(sessionId, "Page.addScriptToEvaluateOnNewDocument", - JObject.FromObject(new { source = $"globalThis.dotnetDebugger = true; delete navigator.constructor.prototype.webdriver; {checkCaughtExceptions} {checkUncaughtExceptions}" }), + JObject.FromObject(new { source = $"globalThis.dotnetDebugger = true; delete navigator.constructor.prototype.webdriver;" }), token); if (sessionId != SessionId.Null && !res.IsOk) From 24bbfbfb925d1d71d6c2f52d521aab00c65446a9 Mon Sep 17 00:00:00 2001 From: Tlakaelel Axayakatl Ceja Date: Wed, 15 Jun 2022 20:26:52 -0700 Subject: [PATCH 149/337] Add SubstitutionParser that uses XPath Navigator into NativeAOT (#64671) --- .../Compiler/BodySubstitution.cs | 56 ++++++ .../Compiler/BodySubstitutionParser.cs | 172 ++++++++++++++++++ .../Compiler/FeatureSwitchManager.cs | 165 +---------------- .../Compiler/ProcessLinkerXmlBase.cs | 29 ++- .../ILCompiler.Compiler.csproj | 2 + 5 files changed, 258 insertions(+), 166 deletions(-) create mode 100644 src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/BodySubstitution.cs create mode 100644 src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/BodySubstitutionParser.cs diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/BodySubstitution.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/BodySubstitution.cs new file mode 100644 index 00000000000000..be138cefa7de1e --- /dev/null +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/BodySubstitution.cs @@ -0,0 +1,56 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using Internal.IL; +using Internal.IL.Stubs; +using Internal.TypeSystem; + +namespace ILCompiler +{ + internal sealed class BodySubstitution + { + private object _value; + + private readonly static object Throw = new object(); + + public readonly static BodySubstitution ThrowingBody = new BodySubstitution(Throw); + public readonly static BodySubstitution EmptyBody = new BodySubstitution(null); + + public object Value + { + get + { + Debug.Assert(_value != Throw); + return _value; + } + } + + private BodySubstitution(object value) => _value = value; + + public static BodySubstitution Create(object value) => new BodySubstitution(value); + public MethodIL EmitIL(MethodDesc method) + { + ILEmitter emit = new ILEmitter(); + ILCodeStream codestream = emit.NewCodeStream(); + + if (_value == Throw) + { + codestream.EmitCallThrowHelper(emit, method.Context.GetHelperEntryPoint("ThrowHelpers", "ThrowFeatureBodyRemoved")); + } + else if (_value == null) + { + Debug.Assert(method.Signature.ReturnType.IsVoid); + codestream.Emit(ILOpcode.ret); + } + else + { + Debug.Assert(_value is int); + codestream.EmitLdc((int)_value); + codestream.Emit(ILOpcode.ret); + } + + return emit.Link(method); + } + } +} diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/BodySubstitutionParser.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/BodySubstitutionParser.cs new file mode 100644 index 00000000000000..3aade53731c65e --- /dev/null +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/BodySubstitutionParser.cs @@ -0,0 +1,172 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Reflection.Metadata; +using Internal.TypeSystem; +using System.Xml.XPath; +using System.Globalization; +using System.Linq; + +namespace ILCompiler +{ + internal sealed class BodySubstitutionsParser : ProcessLinkerXmlBase + { + private readonly Dictionary _methodSubstitutions; + private readonly Dictionary _fieldSubstitutions; + + private BodySubstitutionsParser(TypeSystemContext context, Stream documentStream, ManifestResource resource, ModuleDesc resourceAssembly, string xmlDocumentLocation, IReadOnlyDictionary featureSwitchValues) + : base(context, documentStream, resource, resourceAssembly, xmlDocumentLocation, featureSwitchValues) + { + _methodSubstitutions = new Dictionary(); + _fieldSubstitutions = new Dictionary(); + } + + protected override void ProcessAssembly(ModuleDesc assembly, XPathNavigator nav, bool warnOnUnresolvedTypes) + { + ProcessTypes(assembly, nav, warnOnUnresolvedTypes); + } + + // protected override TypeDesc? ProcessExportedType(ExportedType exported, ModuleDesc assembly, XPathNavigator nav) => null; + + protected override bool ProcessTypePattern(string fullname, ModuleDesc assembly, XPathNavigator nav) => false; + + protected override void ProcessType(TypeDesc type, XPathNavigator nav) + { + Debug.Assert(ShouldProcessElement(nav)); + ProcessTypeChildren(type, nav); + } + + protected override void ProcessMethod(TypeDesc type, XPathNavigator methodNav, object customData) + { + string signature = GetSignature(methodNav); + if (string.IsNullOrEmpty(signature)) + return; + + MethodDesc method = FindMethod(type, signature); + if (method == null) + { + // LogWarning(methodNav, DiagnosticId.XmlCouldNotFindMethodOnType, signature, type.GetDisplayName()); + return; + } + + string action = GetAttribute(methodNav, "body"); + switch (action) + { + case "remove": + _methodSubstitutions.Add(method, BodySubstitution.ThrowingBody); + break; + case "stub": + BodySubstitution stubBody; + if (method.Signature.ReturnType.IsVoid) + stubBody = BodySubstitution.EmptyBody; + else + stubBody = BodySubstitution.Create(TryCreateSubstitution(method.Signature.ReturnType, GetAttribute(methodNav, "value"))); + + if (stubBody != null) + { + _methodSubstitutions[method] = stubBody; + } + else + { + // Context.LogWarning ($"Invalid value for '{method.GetDisplayName ()}' stub", 2010, _xmlDocumentLocation); + } + break; + default: + //Context.LogWarning($"Unknown body modification '{action}' for '{method.GetDisplayName()}'", 2011, _xmlDocumentLocation); + break; + } + } + + protected override void ProcessField(TypeDesc type, XPathNavigator fieldNav) + { + string name = GetAttribute(fieldNav, "name"); + if (string.IsNullOrEmpty(name)) + return; + + var field = type.GetFields().FirstOrDefault(f => f.Name == name); + if (field == null) + { + // LogWarning(fieldNav, DiagnosticId.XmlCouldNotFindFieldOnType, name, type.GetDisplayName()); + return; + } + + if (!field.IsStatic || field.IsLiteral) + { + // LogWarning(fieldNav, DiagnosticId.XmlSubstitutedFieldNeedsToBeStatic, field.GetDisplayName()); + return; + } + + string value = GetAttribute(fieldNav, "value"); + if (string.IsNullOrEmpty(value)) + { + //Context.LogWarning($"Missing 'value' attribute for field '{field.GetDisplayName()}'.", 2014, _xmlDocumentLocation); + return; + } + + object substitution = TryCreateSubstitution(field.FieldType, value); + if (substitution == null) + { + //Context.LogWarning($"Invalid value '{value}' for '{field.GetDisplayName()}'.", 2015, _xmlDocumentLocation); + return; + } + + if (String.Equals(GetAttribute(fieldNav, "initialize"), "true", StringComparison.InvariantCultureIgnoreCase)) + { + // We would need to also mess with the cctor of the type to set the field to this value: + // + // * Linker will remove all stsfld instructions referencing this field from the cctor + // * It will place an explicit stsfld in front of the last "ret" instruction in the cctor + // + // This approach... has issues. + throw new NotSupportedException(); + } + + _fieldSubstitutions[field] = substitution; + } + + static MethodDesc FindMethod(TypeDesc type, string signature) + { + foreach (MethodDesc meth in type.GetMethods()) + if (signature == GetMethodSignature(meth, includeGenericParameters: true)) + return meth; + return null; + } + + private object TryCreateSubstitution(TypeDesc type, string value) + { + switch (type.UnderlyingType.Category) + { + case TypeFlags.Int32: + if (string.IsNullOrEmpty(value)) + return 0; + else if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out int iresult)) + return iresult; + break; + + case TypeFlags.Boolean: + if (String.IsNullOrEmpty(value)) + return 0; + else if (bool.TryParse(value, out bool bvalue)) + return bvalue ? 1 : 0; + else + goto case TypeFlags.Int32; + + default: + throw new NotSupportedException(type.ToString()); + } + + return null; + } + + public static (Dictionary, Dictionary) GetSubstitutions(TypeSystemContext context, UnmanagedMemoryStream documentStream, ManifestResource resource, ModuleDesc resourceAssembly, string xmlDocumentLocation, IReadOnlyDictionary featureSwitchValues) + { + var rdr = new BodySubstitutionsParser(context, documentStream, resource, resourceAssembly, xmlDocumentLocation, featureSwitchValues); + rdr.ProcessXml(false); + return (rdr._methodSubstitutions, rdr._fieldSubstitutions); + } + } +} diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/FeatureSwitchManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/FeatureSwitchManager.cs index 20050db2c8cdab..2efa5cfeb9d1dc 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/FeatureSwitchManager.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/FeatureSwitchManager.cs @@ -8,7 +8,6 @@ using System.Reflection.Metadata; using System.Reflection.PortableExecutable; using System.Xml; - using Internal.IL; using Internal.IL.Stubs; using Internal.TypeSystem; @@ -740,172 +739,10 @@ public AssemblyFeatureInfo(EcmaModule module, IReadOnlyDictionary ms = new UnmanagedMemoryStream(reader.CurrentPointer, length); } - (BodySubstitutions, FieldSubstitutions) = SubstitutionsReader.GetSubstitutions(module.Context, XmlReader.Create(ms), module, featureSwitchValues); + (BodySubstitutions, FieldSubstitutions) = BodySubstitutionsParser.GetSubstitutions(module.Context, ms, resource, module, "name", featureSwitchValues); } } } } - - private class BodySubstitution - { - private object _value; - - private readonly static object Throw = new object(); - - public readonly static BodySubstitution ThrowingBody = new BodySubstitution(Throw); - public readonly static BodySubstitution EmptyBody = new BodySubstitution(null); - - public object Value - { - get - { - Debug.Assert(_value != Throw); - return _value; - } - } - - private BodySubstitution(object value) => _value = value; - - public static BodySubstitution Create(object value) => new BodySubstitution(value); - public MethodIL EmitIL(MethodDesc method) - { - ILEmitter emit = new ILEmitter(); - ILCodeStream codestream = emit.NewCodeStream(); - - if (_value == Throw) - { - codestream.EmitCallThrowHelper(emit, method.Context.GetHelperEntryPoint("ThrowHelpers", "ThrowFeatureBodyRemoved")); - } - else if (_value == null) - { - Debug.Assert(method.Signature.ReturnType.IsVoid); - codestream.Emit(ILOpcode.ret); - } - else - { - Debug.Assert(_value is int); - codestream.EmitLdc((int)_value); - codestream.Emit(ILOpcode.ret); - } - - return emit.Link(method); - } - } - - private class SubstitutionsReader : ProcessXmlBase - { - private readonly Dictionary _methodSubstitutions; - private readonly Dictionary _fieldSubstitutions; - - private SubstitutionsReader(TypeSystemContext context, XmlReader reader, ModuleDesc module, IReadOnlyDictionary featureSwitchValues) - : base(context, reader, module, featureSwitchValues) - { - _methodSubstitutions = new Dictionary(); - _fieldSubstitutions = new Dictionary(); - } - - protected override void ProcessMethod(MethodDesc method) - { - string action = GetAttribute("body"); - if (!String.IsNullOrEmpty(action)) - { - switch (action) - { - case "remove": - _methodSubstitutions.Add(method, BodySubstitution.ThrowingBody); - break; - case "stub": - BodySubstitution stubBody; - if (method.Signature.ReturnType.IsVoid) - stubBody = BodySubstitution.EmptyBody; - else - stubBody = BodySubstitution.Create(TryCreateSubstitution(method.Signature.ReturnType, GetAttribute("value"))); - - if (stubBody != null) - { - _methodSubstitutions[method] = stubBody; - } - else - { - // Context.LogWarning ($"Invalid value for '{method.GetDisplayName ()}' stub", 2010, _xmlDocumentLocation); - } - - break; - default: - //Context.LogWarning($"Unknown body modification '{action}' for '{method.GetDisplayName()}'", 2011, _xmlDocumentLocation); - break; - } - } - } - - protected override void ProcessField(FieldDesc field) - { - if (!field.IsStatic || field.IsLiteral) - { - // Context.LogWarning ($"Substituted field '{field.GetDisplayName ()}' needs to be static field.", 2013, _xmlDocumentLocation); - return; - } - - string value = GetAttribute("value"); - if (string.IsNullOrEmpty(value)) - { - //Context.LogWarning($"Missing 'value' attribute for field '{field.GetDisplayName()}'.", 2014, _xmlDocumentLocation); - return; - } - - object substitution = TryCreateSubstitution(field.FieldType, value); - if (substitution == null) - { - //Context.LogWarning($"Invalid value '{value}' for '{field.GetDisplayName()}'.", 2015, _xmlDocumentLocation); - return; - } - - if (String.Equals(GetAttribute("initialize"), "true", StringComparison.InvariantCultureIgnoreCase)) - { - // We would need to also mess with the cctor of the type to set the field to this value: - // - // * Linker will remove all stsfld instructions referencing this field from the cctor - // * It will place an explicit stsfld in front of the last "ret" instruction in the cctor - // - // This approach... has issues. - throw new NotSupportedException(); - } - - _fieldSubstitutions[field] = substitution; - } - - private object TryCreateSubstitution(TypeDesc type, string value) - { - switch (type.UnderlyingType.Category) - { - case TypeFlags.Int32: - if (string.IsNullOrEmpty(value)) - return 0; - else if (int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out int iresult)) - return iresult; - break; - - case TypeFlags.Boolean: - if (String.IsNullOrEmpty(value)) - return 0; - else if (bool.TryParse(value, out bool bvalue)) - return bvalue ? 1 : 0; - else - goto case TypeFlags.Int32; - - default: - throw new NotSupportedException(type.ToString()); - } - - return null; - } - - public static (Dictionary, Dictionary) GetSubstitutions(TypeSystemContext context, XmlReader reader, ModuleDesc module, IReadOnlyDictionary featureSwitchValues) - { - var rdr = new SubstitutionsReader(context, reader, module, featureSwitchValues); - rdr.ProcessXml(); - return (rdr._methodSubstitutions, rdr._fieldSubstitutions); - } - } } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ProcessLinkerXmlBase.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ProcessLinkerXmlBase.cs index e4c06223c6c40a..062c80897e95fd 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ProcessLinkerXmlBase.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ProcessLinkerXmlBase.cs @@ -50,7 +50,7 @@ public abstract class ProcessLinkerXmlBase private readonly IReadOnlyDictionary _featureSwitchValues; protected readonly TypeSystemContext _context; - protected ProcessLinkerXmlBase(TypeSystemContext context, UnmanagedMemoryStream documentStream, string xmlDocumentLocation, IReadOnlyDictionary featureSwitchValues) + protected ProcessLinkerXmlBase(TypeSystemContext context, Stream documentStream, string xmlDocumentLocation, IReadOnlyDictionary featureSwitchValues) { _context = context; using (documentStream) @@ -61,7 +61,7 @@ protected ProcessLinkerXmlBase(TypeSystemContext context, UnmanagedMemoryStream _featureSwitchValues = featureSwitchValues; } - protected ProcessLinkerXmlBase(TypeSystemContext context, UnmanagedMemoryStream documentStream, ManifestResource resource, ModuleDesc resourceAssembly, string xmlDocumentLocation, IReadOnlyDictionary featureSwitchValues) + protected ProcessLinkerXmlBase(TypeSystemContext context, Stream documentStream, ManifestResource resource, ModuleDesc resourceAssembly, string xmlDocumentLocation, IReadOnlyDictionary featureSwitchValues) : this(context, documentStream, xmlDocumentLocation, featureSwitchValues) { _owningModule = resourceAssembly ?? throw new ArgumentNullException(nameof(resourceAssembly)); @@ -489,6 +489,31 @@ protected static string GetAttribute(XPathNavigator nav, string attribute) return nav.GetAttribute(attribute, XmlNamespace); } + public static string GetMethodSignature(MethodDesc meth, bool includeGenericParameters) + { + StringBuilder sb = new StringBuilder(); + CecilTypeNameFormatter.Instance.AppendName(sb, meth.Signature.ReturnType); + sb.Append(' '); + sb.Append(meth.Name); + if (includeGenericParameters && meth.HasInstantiation) + { + sb.Append('`'); + sb.Append(meth.Instantiation.Length); + } + + sb.Append('('); + for (int i = 0; i < meth.Signature.Length; i++) + { + if (i > 0) + sb.Append(','); + + CecilTypeNameFormatter.Instance.AppendName(sb, meth.Signature[i]); + } + + sb.Append(')'); + return sb.ToString(); + } + #if false protected MessageOrigin GetMessageOriginForPosition(XPathNavigator position) { diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj b/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj index 92718ba7ce9303..12fadf2a915f37 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj @@ -300,6 +300,8 @@ + + From 3c33b4293107c607ae8669545114d6f9891432cb Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Thu, 16 Jun 2022 08:45:07 +0200 Subject: [PATCH 150/337] Add end-to-end test for NTLM/Negotiate authentication against fake server (#70630) * Add end-to-end test for NTLM/Negotiate authentication against fake server * Simplify the test since HttpClientHandler is always SocketsHttpHandler for the test environment * Fix test condition * Remove extra comment --- .../Net/Security}/FakeNegotiateServer.cs | 0 .../System/Net/Security}/FakeNtlmServer.cs | 0 .../FunctionalTests/NtAuthTests.FakeServer.cs | 140 ++++++++++++++++++ .../System.Net.Http.Functional.Tests.csproj | 12 ++ .../System.Net.Security.Unit.Tests.csproj | 6 +- 5 files changed, 156 insertions(+), 2 deletions(-) rename src/libraries/{System.Net.Security/tests/UnitTests/Fakes => Common/tests/System/Net/Security}/FakeNegotiateServer.cs (100%) rename src/libraries/{System.Net.Security/tests/UnitTests/Fakes => Common/tests/System/Net/Security}/FakeNtlmServer.cs (100%) create mode 100644 src/libraries/System.Net.Http/tests/FunctionalTests/NtAuthTests.FakeServer.cs diff --git a/src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeNegotiateServer.cs b/src/libraries/Common/tests/System/Net/Security/FakeNegotiateServer.cs similarity index 100% rename from src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeNegotiateServer.cs rename to src/libraries/Common/tests/System/Net/Security/FakeNegotiateServer.cs diff --git a/src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeNtlmServer.cs b/src/libraries/Common/tests/System/Net/Security/FakeNtlmServer.cs similarity index 100% rename from src/libraries/System.Net.Security/tests/UnitTests/Fakes/FakeNtlmServer.cs rename to src/libraries/Common/tests/System/Net/Security/FakeNtlmServer.cs diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/NtAuthTests.FakeServer.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/NtAuthTests.FakeServer.cs new file mode 100644 index 00000000000000..881555d67ffad9 --- /dev/null +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/NtAuthTests.FakeServer.cs @@ -0,0 +1,140 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Linq; +using System.Net.Security; +using System.Net.Test.Common; +using System.Security.Principal; +using System.Threading.Tasks; + +using Xunit; +using Xunit.Abstractions; + +namespace System.Net.Http.Functional.Tests +{ + public partial class NtAuthTests : IClassFixture + { + public static bool IsNtlmAvailable => + Capability.IsNtlmInstalled() || OperatingSystem.IsAndroid() || OperatingSystem.IsTvOS(); + + private static NetworkCredential s_testCredentialRight = new NetworkCredential("rightusername", "rightpassword"); + + internal static async Task HandleAuthenticationRequestWithFakeServer(LoopbackServer.Connection connection, bool useNtlm) + { + HttpRequestData request = await connection.ReadRequestDataAsync(); + FakeNtlmServer? fakeNtlmServer = null; + FakeNegotiateServer? fakeNegotiateServer = null; + string authHeader = null; + + foreach (HttpHeaderData header in request.Headers) + { + if (header.Name == "Authorization") + { + authHeader = header.Value; + break; + } + } + + if (string.IsNullOrEmpty(authHeader)) + { + // This is initial request, we reject with showing supported mechanisms. + if (useNtlm) + { + authHeader = "WWW-Authenticate: NTLM\r\n"; + } + else + { + authHeader = "WWW-Authenticate: Negotiate\r\n"; + } + + await connection.SendResponseAsync(HttpStatusCode.Unauthorized, authHeader).ConfigureAwait(false); + connection.CompleteRequestProcessing(); + + // Read next requests and fall-back to loop bellow to process it. + request = await connection.ReadRequestDataAsync(); + } + + bool isAuthenticated = false; + do + { + foreach (HttpHeaderData header in request.Headers) + { + if (header.Name == "Authorization") + { + authHeader = header.Value; + break; + } + } + + Assert.NotNull(authHeader); + var tokens = authHeader.Split(' ', 2, StringSplitOptions.TrimEntries); + // Should be type and base64 encoded blob + Assert.Equal(2, tokens.Length); + + if (fakeNtlmServer == null) + { + fakeNtlmServer = new FakeNtlmServer(s_testCredentialRight) { ForceNegotiateVersion = true }; + if (!useNtlm) + { + fakeNegotiateServer = new FakeNegotiateServer(fakeNtlmServer); + } + } + + byte[]? outBlob; + + if (fakeNegotiateServer != null) + { + outBlob = fakeNegotiateServer.GetOutgoingBlob(Convert.FromBase64String(tokens[1])); + isAuthenticated = fakeNegotiateServer.IsAuthenticated; + } + else + { + outBlob = fakeNtlmServer.GetOutgoingBlob(Convert.FromBase64String(tokens[1])); + isAuthenticated = fakeNtlmServer.IsAuthenticated; + } + + if (outBlob != null) + { + authHeader = $"WWW-Authenticate: {tokens[0]} {Convert.ToBase64String(outBlob)}\r\n"; + await connection.SendResponseAsync(isAuthenticated ? HttpStatusCode.OK : HttpStatusCode.Unauthorized, authHeader); + connection.CompleteRequestProcessing(); + + if (!isAuthenticated) + { + request = await connection.ReadRequestDataAsync(); + } + } + } + while (!isAuthenticated); + + await connection.SendResponseAsync(HttpStatusCode.OK); + } + + [ConditionalTheory(nameof(IsNtlmAvailable))] + [InlineData(true)] + [InlineData(false)] + public async Task DefaultHandler_FakeServer_Success(bool useNtlm) + { + await LoopbackServer.CreateClientAndServerAsync( + async uri => + { + HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, uri); + requestMessage.Version = new Version(1, 1); + + HttpMessageHandler handler = new HttpClientHandler() { Credentials = s_testCredentialRight }; + using (var client = new HttpClient(handler)) + { + HttpResponseMessage response = await client.SendAsync(requestMessage); + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + } + }, + async server => + { + await server.AcceptConnectionAsync(async connection => + { + await HandleAuthenticationRequestWithFakeServer(connection, useNtlm); + }).ConfigureAwait(false); + }); + } + } +} diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj b/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj index 59a84cb1826930..e5da76698df37e 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/System.Net.Http.Functional.Tests.csproj @@ -352,6 +352,7 @@ Link="Common\System\Net\Http\HttpClientHandlerTest.Decompression.cs" /> + + + + + + + + SelectedSitesTest.txt diff --git a/src/libraries/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj b/src/libraries/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj index 55df154298e536..3f61524d58c4c8 100644 --- a/src/libraries/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj +++ b/src/libraries/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj @@ -30,8 +30,10 @@ - - + + From 3fc61ebb562afc327a8fc6de5c82d76e86bf6f5d Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Thu, 16 Jun 2022 12:41:45 +0200 Subject: [PATCH 151/337] Enable ThreadAbort with CET enabled via the QueueUserAPC2 (#70803) This change makes ThreadAbort work when CET is enabled. Instead of thread redirection, it uses the new user mode APC mechanism to get a thread to a handler and then throws the ThreadAbortException from there if the thread was interrupted at a safe location. I have verified it works using mdbg tests and also by manual testing in the Visual Studio 2022 using a test app that creates an instance of classes with properties containing infinite loop, wait on a lock, wait on a handle, infinite loop inside of a lock and infinite loop in finally. For the testing, I've enabled this separately from the CET so that the missing support for CET in the debugger code doesn't cause troubles. So we could enable this without CET enabled too, but I'd prefer doing that separately. --- src/coreclr/vm/threads.h | 1 + src/coreclr/vm/threadsuspend.cpp | 567 ++++++++++++++++--------------- 2 files changed, 290 insertions(+), 278 deletions(-) diff --git a/src/coreclr/vm/threads.h b/src/coreclr/vm/threads.h index f4bf60ec167997..aab863910738c8 100644 --- a/src/coreclr/vm/threads.h +++ b/src/coreclr/vm/threads.h @@ -2215,6 +2215,7 @@ class Thread { SuspendForGC, SuspendForDebugger, + ThreadAbort, }; bool InjectActivation(ActivationReason reason); diff --git a/src/coreclr/vm/threadsuspend.cpp b/src/coreclr/vm/threadsuspend.cpp index d0725699893e82..305145572dd4d1 100644 --- a/src/coreclr/vm/threadsuspend.cpp +++ b/src/coreclr/vm/threadsuspend.cpp @@ -1227,398 +1227,400 @@ Thread::UserAbort(EEPolicy::ThreadAbortTypes abortType, DWORD timeout) _ASSERTE(this != pCurThread); // Aborting another thread. + if (!UseSpecialUserModeApc()) + { #ifdef _DEBUG - DWORD elapsed_time = 0; + DWORD elapsed_time = 0; #endif - // We do not want this thread to be alerted. - ThreadPreventAsyncHolder preventAsync(pCurThread != NULL); + // We do not want this thread to be alerted. + ThreadPreventAsyncHolder preventAsync(pCurThread != NULL); #ifdef _DEBUG - // If UserAbort times out, put up msgbox once. - BOOL fAlreadyAssert = FALSE; + // If UserAbort times out, put up msgbox once. + BOOL fAlreadyAssert = FALSE; #endif #if !defined(DISABLE_THREADSUSPEND) - DWORD dwSwitchCount = 0; + DWORD dwSwitchCount = 0; #endif // !defined(DISABLE_THREADSUSPEND) - while (true) - { - // Lock the thread store - LOG((LF_SYNC, INFO3, "UserAbort obtain lock\n")); - - ULONGLONG abortEndTime = GetAbortEndTime(); - if (abortEndTime != MAXULONGLONG) + while (true) { - ULONGLONG now_time = CLRGetTickCount64(); + // Lock the thread store + LOG((LF_SYNC, INFO3, "UserAbort obtain lock\n")); - if (now_time >= abortEndTime) + ULONGLONG abortEndTime = GetAbortEndTime(); + if (abortEndTime != MAXULONGLONG) { - // timeout, but no action on timeout. - // Debugger can call this function to abort func-eval with a timeout - return HRESULT_FROM_WIN32(ERROR_TIMEOUT); + ULONGLONG now_time = CLRGetTickCount64(); + + if (now_time >= abortEndTime) + { + // timeout, but no action on timeout. + // Debugger can call this function to abort func-eval with a timeout + return HRESULT_FROM_WIN32(ERROR_TIMEOUT); + } } - } - // Thread abort needs to walk stack to decide if thread abort can proceed. - // It is unsafe to crawl a stack of thread if the thread is OS-suspended which we do during - // thread abort. For example, Thread T1 aborts thread T2. T2 is suspended by T1. Inside SQL - // this means that no thread sharing the same scheduler with T2 can run. If T1 needs a lock which - // is owned by one thread on the scheduler, T1 will wait forever. - // Our solution is to move T2 to a safe point, resume it, and then do stack crawl. + // Thread abort needs to walk stack to decide if thread abort can proceed. + // It is unsafe to crawl a stack of thread if the thread is OS-suspended which we do during + // thread abort. For example, Thread T1 aborts thread T2. T2 is suspended by T1. Inside SQL + // this means that no thread sharing the same scheduler with T2 can run. If T1 needs a lock which + // is owned by one thread on the scheduler, T1 will wait forever. + // Our solution is to move T2 to a safe point, resume it, and then do stack crawl. - // We need to make sure that ThreadStoreLock is released after CheckForAbort. This makes sure - // that ThreadAbort does not race against GC. - class CheckForAbort - { - private: - Thread *m_pThread; - BOOL m_fHoldingThreadStoreLock; - BOOL m_NeedRelease; - public: - CheckForAbort(Thread *pThread, BOOL fHoldingThreadStoreLock) - : m_pThread(pThread), - m_fHoldingThreadStoreLock(fHoldingThreadStoreLock), - m_NeedRelease(TRUE) + // We need to make sure that ThreadStoreLock is released after CheckForAbort. This makes sure + // that ThreadAbort does not race against GC. + class CheckForAbort { - if (!fHoldingThreadStoreLock) + private: + Thread *m_pThread; + BOOL m_fHoldingThreadStoreLock; + BOOL m_NeedRelease; + public: + CheckForAbort(Thread *pThread, BOOL fHoldingThreadStoreLock) + : m_pThread(pThread), + m_fHoldingThreadStoreLock(fHoldingThreadStoreLock), + m_NeedRelease(TRUE) { - ThreadSuspend::LockThreadStore(ThreadSuspend::SUSPEND_OTHER); - } - ThreadStore::ResetStackCrawlEvent(); + if (!fHoldingThreadStoreLock) + { + ThreadSuspend::LockThreadStore(ThreadSuspend::SUSPEND_OTHER); + } + ThreadStore::ResetStackCrawlEvent(); - // The thread being aborted may clear the TS_AbortRequested bit and the matching increment - // of g_TrapReturningThreads behind our back. Increment g_TrapReturningThreads here - // to ensure that we stop for the stack crawl even if the TS_AbortRequested bit is cleared. - ThreadStore::TrapReturningThreads(TRUE); - } - void NeedStackCrawl() - { - m_pThread->SetThreadState(Thread::TS_StackCrawlNeeded); - } - ~CheckForAbort() - { - Release(); - } - void Release() - { - if (m_NeedRelease) + // The thread being aborted may clear the TS_AbortRequested bit and the matching increment + // of g_TrapReturningThreads behind our back. Increment g_TrapReturningThreads here + // to ensure that we stop for the stack crawl even if the TS_AbortRequested bit is cleared. + ThreadStore::TrapReturningThreads(TRUE); + } + void NeedStackCrawl() + { + m_pThread->SetThreadState(Thread::TS_StackCrawlNeeded); + } + ~CheckForAbort() { - m_NeedRelease = FALSE; - ThreadStore::TrapReturningThreads(FALSE); - ThreadStore::SetStackCrawlEvent(); - m_pThread->ResetThreadState(TS_StackCrawlNeeded); - if (!m_fHoldingThreadStoreLock) + Release(); + } + void Release() + { + if (m_NeedRelease) { - ThreadSuspend::UnlockThreadStore(); + m_NeedRelease = FALSE; + ThreadStore::TrapReturningThreads(FALSE); + ThreadStore::SetStackCrawlEvent(); + m_pThread->ResetThreadState(TS_StackCrawlNeeded); + if (!m_fHoldingThreadStoreLock) + { + ThreadSuspend::UnlockThreadStore(); + } } } - } - }; - CheckForAbort checkForAbort(this, fHoldingThreadStoreLock); + }; + CheckForAbort checkForAbort(this, fHoldingThreadStoreLock); - // We own TS lock. The state of the Thread can not be changed. - if (m_State & TS_Unstarted) - { - // This thread is not yet started. + // We own TS lock. The state of the Thread can not be changed. + if (m_State & TS_Unstarted) + { + // This thread is not yet started. #ifdef _DEBUG - m_dwAbortPoint = 2; + m_dwAbortPoint = 2; #endif - return S_OK; - } + return S_OK; + } - if (GetThreadHandle() == INVALID_HANDLE_VALUE && - (m_State & TS_Unstarted) == 0) - { - // The thread is going to die or is already dead. - UnmarkThreadForAbort(); + if (GetThreadHandle() == INVALID_HANDLE_VALUE && + (m_State & TS_Unstarted) == 0) + { + // The thread is going to die or is already dead. + UnmarkThreadForAbort(); #ifdef _DEBUG - m_dwAbortPoint = 3; + m_dwAbortPoint = 3; #endif - return S_OK; - } + return S_OK; + } - // What if someone else has this thread suspended already? It'll depend where the - // thread got suspended. - // - // User Suspend: - // We'll just set the abort bit and hope for the best on the resume. - // - // GC Suspend: - // If it's suspended in jitted code, we'll hijack the IP. - // Consider race w/ GC suspension - // If it's suspended but not in jitted code, we'll get suspended for GC, the GC - // will complete, and then we'll abort the target thread. - // + // What if someone else has this thread suspended already? It'll depend where the + // thread got suspended. + // + // User Suspend: + // We'll just set the abort bit and hope for the best on the resume. + // + // GC Suspend: + // If it's suspended in jitted code, we'll hijack the IP. + // Consider race w/ GC suspension + // If it's suspended but not in jitted code, we'll get suspended for GC, the GC + // will complete, and then we'll abort the target thread. + // - // It's possible that the thread has completed the abort already. - // - if (!(m_State & TS_AbortRequested)) - { + // It's possible that the thread has completed the abort already. + // + if (!(m_State & TS_AbortRequested)) + { #ifdef _DEBUG - m_dwAbortPoint = 4; + m_dwAbortPoint = 4; #endif - return S_OK; - } + return S_OK; + } - // If a thread is Dead or Detached, abort is a NOP. - // - if (m_State & (TS_Dead | TS_Detached | TS_TaskReset)) - { - UnmarkThreadForAbort(); + // If a thread is Dead or Detached, abort is a NOP. + // + if (m_State & (TS_Dead | TS_Detached | TS_TaskReset)) + { + UnmarkThreadForAbort(); #ifdef _DEBUG - m_dwAbortPoint = 5; + m_dwAbortPoint = 5; #endif - return S_OK; - } + return S_OK; + } - // It's possible that some stub notices the AbortRequested bit -- even though we - // haven't done any real magic yet. If the thread has already started it's abort, we're - // done. - // - // Two more cases can be folded in here as well. If the thread is unstarted, it'll - // abort when we start it. - // - // If the thread is user suspended (SyncSuspended) -- we're out of luck. Set the bit and - // hope for the best on resume. - // - if ((m_State & TS_AbortInitiated) && !IsRudeAbort()) - { + // It's possible that some stub notices the AbortRequested bit -- even though we + // haven't done any real magic yet. If the thread has already started it's abort, we're + // done. + // + // Two more cases can be folded in here as well. If the thread is unstarted, it'll + // abort when we start it. + // + // If the thread is user suspended (SyncSuspended) -- we're out of luck. Set the bit and + // hope for the best on resume. + // + if ((m_State & TS_AbortInitiated) && !IsRudeAbort()) + { #ifdef _DEBUG - m_dwAbortPoint = 6; + m_dwAbortPoint = 6; #endif - break; - } + break; + } - BOOL fOutOfRuntime = FALSE; - BOOL fNeedStackCrawl = FALSE; + BOOL fOutOfRuntime = FALSE; + BOOL fNeedStackCrawl = FALSE; #ifdef DISABLE_THREADSUSPEND - // On platforms that do not support safe thread suspension we have to - // rely on the GCPOLL mechanism; the mechanism is activated above by - // TrapReturningThreads. However when reading shared state we need - // to erect appropriate memory barriers. So the interlocked operation - // below ensures that any future reads on this thread will happen after - // any earlier writes on a different thread have taken effect. - InterlockedOr((LONG*)&m_State, 0); + // On platforms that do not support safe thread suspension we have to + // rely on the GCPOLL mechanism; the mechanism is activated above by + // TrapReturningThreads. However when reading shared state we need + // to erect appropriate memory barriers. So the interlocked operation + // below ensures that any future reads on this thread will happen after + // any earlier writes on a different thread have taken effect. + InterlockedOr((LONG*)&m_State, 0); #else // DISABLE_THREADSUSPEND - // Win32 suspend the thread, so it isn't moving under us. - SuspendThreadResult str = SuspendThread(); - switch (str) - { - case STR_Success: - break; + // Win32 suspend the thread, so it isn't moving under us. + SuspendThreadResult str = SuspendThread(); + switch (str) + { + case STR_Success: + break; - case STR_Failure: - case STR_UnstartedOrDead: - case STR_NoStressLog: - checkForAbort.Release(); - __SwitchToThread(0, ++dwSwitchCount); - continue; + case STR_Failure: + case STR_UnstartedOrDead: + case STR_NoStressLog: + checkForAbort.Release(); + __SwitchToThread(0, ++dwSwitchCount); + continue; - default: - UNREACHABLE(); - } + default: + UNREACHABLE(); + } - _ASSERTE(str == STR_Success); + _ASSERTE(str == STR_Success); #endif // DISABLE_THREADSUSPEND - // It's possible that the thread has completed the abort already. - // - if (!(m_State & TS_AbortRequested)) - { + // It's possible that the thread has completed the abort already. + // + if (!(m_State & TS_AbortRequested)) + { #ifndef DISABLE_THREADSUSPEND - ResumeThread(); + ResumeThread(); #endif #ifdef _DEBUG - m_dwAbortPoint = 63; + m_dwAbortPoint = 63; #endif - return S_OK; - } + return S_OK; + } - // Check whether some stub noticed the AbortRequested bit in-between our test above - // and us suspending the thread. - if ((m_State & TS_AbortInitiated) && !IsRudeAbort()) - { + // Check whether some stub noticed the AbortRequested bit in-between our test above + // and us suspending the thread. + if ((m_State & TS_AbortInitiated) && !IsRudeAbort()) + { #ifndef DISABLE_THREADSUSPEND - ResumeThread(); + ResumeThread(); #endif #ifdef _DEBUG - m_dwAbortPoint = 65; + m_dwAbortPoint = 65; #endif - break; - } + break; + } - // If Threads is stopped under a managed debugger, it will have both - // TS_DebugSuspendPending and TS_SyncSuspended, regardless of whether - // the thread is actually suspended or not. - if (m_State & TS_SyncSuspended) - { + // If Threads is stopped under a managed debugger, it will have both + // TS_DebugSuspendPending and TS_SyncSuspended, regardless of whether + // the thread is actually suspended or not. + if (m_State & TS_SyncSuspended) + { #ifndef DISABLE_THREADSUSPEND - ResumeThread(); + ResumeThread(); #endif - checkForAbort.Release(); + checkForAbort.Release(); #ifdef _DEBUG - m_dwAbortPoint = 7; + m_dwAbortPoint = 7; #endif - // - // If it's stopped by the debugger, we don't want to throw an exception. - // Debugger suspension is to have no effect of the runtime behaviour. - // - if (m_State & TS_DebugSuspendPending) - { - return S_OK; - } + // + // If it's stopped by the debugger, we don't want to throw an exception. + // Debugger suspension is to have no effect of the runtime behaviour. + // + if (m_State & TS_DebugSuspendPending) + { + return S_OK; + } - COMPlusThrow(kThreadStateException, IDS_EE_THREAD_ABORT_WHILE_SUSPEND); - } + COMPlusThrow(kThreadStateException, IDS_EE_THREAD_ABORT_WHILE_SUSPEND); + } - // If the thread has no managed code on it's call stack, abort is a NOP. We're about - // to touch the unmanaged thread's stack -- for this to be safe, we can't be - // Dead/Detached/Unstarted. - // - _ASSERTE(!(m_State & ( TS_Dead - | TS_Detached - | TS_Unstarted))); + // If the thread has no managed code on it's call stack, abort is a NOP. We're about + // to touch the unmanaged thread's stack -- for this to be safe, we can't be + // Dead/Detached/Unstarted. + // + _ASSERTE(!(m_State & ( TS_Dead + | TS_Detached + | TS_Unstarted))); #if defined(TARGET_X86) && !defined(FEATURE_EH_FUNCLETS) - // TODO WIN64: consider this if there is a way to detect of managed code on stack. - if ((m_pFrame == FRAME_TOP) - && (GetFirstCOMPlusSEHRecord(this) == EXCEPTION_CHAIN_END) - ) - { + // TODO WIN64: consider this if there is a way to detect of managed code on stack. + if ((m_pFrame == FRAME_TOP) + && (GetFirstCOMPlusSEHRecord(this) == EXCEPTION_CHAIN_END) + ) + { #ifndef DISABLE_THREADSUSPEND - ResumeThread(); + ResumeThread(); #endif #ifdef _DEBUG - m_dwAbortPoint = 8; + m_dwAbortPoint = 8; #endif - return S_OK; - } + return S_OK; + } #endif // TARGET_X86 - if (!m_fPreemptiveGCDisabled) - { - if ((m_pFrame != FRAME_TOP) && m_pFrame->IsTransitionToNativeFrame() + if (!m_fPreemptiveGCDisabled) + { + if ((m_pFrame != FRAME_TOP) && m_pFrame->IsTransitionToNativeFrame() #if defined(TARGET_X86) && !defined(FEATURE_EH_FUNCLETS) - && ((size_t) GetFirstCOMPlusSEHRecord(this) > ((size_t) m_pFrame) - 20) + && ((size_t) GetFirstCOMPlusSEHRecord(this) > ((size_t) m_pFrame) - 20) #endif // TARGET_X86 - ) - { - fOutOfRuntime = TRUE; + ) + { + fOutOfRuntime = TRUE; + } } - } - checkForAbort.NeedStackCrawl(); - if (!m_fPreemptiveGCDisabled) - { - fNeedStackCrawl = TRUE; - } + checkForAbort.NeedStackCrawl(); + if (!m_fPreemptiveGCDisabled) + { + fNeedStackCrawl = TRUE; + } #if defined(FEATURE_HIJACK) && !defined(TARGET_UNIX) - else - { - HandleJITCaseForAbort(); - } + else + { + HandleJITCaseForAbort(); + } #endif // FEATURE_HIJACK && !TARGET_UNIX #ifndef DISABLE_THREADSUSPEND - // The thread is not suspended now. - ResumeThread(); + // The thread is not suspended now. + ResumeThread(); #endif - if (!fNeedStackCrawl) - { - goto LPrepareRetry; - } + if (!fNeedStackCrawl) + { + goto LPrepareRetry; + } - if (!ReadyForAbort()) { - goto LPrepareRetry; - } + if (!ReadyForAbort()) { + goto LPrepareRetry; + } - // !!! Check for Exception in flight should happen before induced thread abort. - // !!! ReadyForAbort skips catch and filter clause. + // !!! Check for Exception in flight should happen before induced thread abort. + // !!! ReadyForAbort skips catch and filter clause. - // If an exception is currently being thrown, one of two things will happen. Either, we'll - // catch, and notice the abort request in our end-catch, or we'll not catch [in which case - // we're leaving managed code anyway. The top-most handler is responsible for resetting - // the bit. - // - if (HasException() && - // For rude abort, we will initiated abort - !IsRudeAbort()) - { + // If an exception is currently being thrown, one of two things will happen. Either, we'll + // catch, and notice the abort request in our end-catch, or we'll not catch [in which case + // we're leaving managed code anyway. The top-most handler is responsible for resetting + // the bit. + // + if (HasException() && + // For rude abort, we will initiated abort + !IsRudeAbort()) + { #ifdef _DEBUG - m_dwAbortPoint = 9; + m_dwAbortPoint = 9; #endif - break; - } + break; + } - // If the thread is in sleep, wait, or join interrupt it - // However, we do NOT want to interrupt if the thread is already processing an exception - if (m_State & TS_Interruptible) - { - UserInterrupt(TI_Abort); // if the user wakes up because of this, it will read the - // abort requested bit and initiate the abort + // If the thread is in sleep, wait, or join interrupt it + // However, we do NOT want to interrupt if the thread is already processing an exception + if (m_State & TS_Interruptible) + { + UserInterrupt(TI_Abort); // if the user wakes up because of this, it will read the + // abort requested bit and initiate the abort #ifdef _DEBUG - m_dwAbortPoint = 10; + m_dwAbortPoint = 10; #endif - goto LPrepareRetry; - } + goto LPrepareRetry; + } - if (fOutOfRuntime) - { - // If the thread is running outside the EE, and is behind a stub that's going - // to catch... + if (fOutOfRuntime) + { + // If the thread is running outside the EE, and is behind a stub that's going + // to catch... #ifdef _DEBUG - m_dwAbortPoint = 11; + m_dwAbortPoint = 11; #endif - break; - } + break; + } - // Ok. It's not in managed code, nor safely out behind a stub that's going to catch - // it on the way in. We have to poll. + // Ok. It's not in managed code, nor safely out behind a stub that's going to catch + // it on the way in. We have to poll. LPrepareRetry: - checkForAbort.Release(); + checkForAbort.Release(); - // Don't do a Sleep. It's possible that the thread we are trying to abort is - // stuck in unmanaged code trying to get into the apartment that we are supposed - // to be pumping! Instead, ping the current thread's handle. Obviously this - // will time out, but it will pump if we need it to. - if (pCurThread) - { - pCurThread->Join(ABORT_POLL_TIMEOUT, TRUE); - } - else - { - ClrSleepEx(ABORT_POLL_TIMEOUT, FALSE); - } + // Don't do a Sleep. It's possible that the thread we are trying to abort is + // stuck in unmanaged code trying to get into the apartment that we are supposed + // to be pumping! Instead, ping the current thread's handle. Obviously this + // will time out, but it will pump if we need it to. + if (pCurThread) + { + pCurThread->Join(ABORT_POLL_TIMEOUT, TRUE); + } + else + { + ClrSleepEx(ABORT_POLL_TIMEOUT, FALSE); + } #ifdef _DEBUG - elapsed_time += ABORT_POLL_TIMEOUT; - if (g_pConfig->GetGCStressLevel() == 0 && !fAlreadyAssert) - { - _ASSERTE(elapsed_time < ABORT_FAIL_TIMEOUT); - fAlreadyAssert = TRUE; - } + elapsed_time += ABORT_POLL_TIMEOUT; + if (g_pConfig->GetGCStressLevel() == 0 && !fAlreadyAssert) + { + _ASSERTE(elapsed_time < ABORT_FAIL_TIMEOUT); + fAlreadyAssert = TRUE; + } #endif - } // while (true) - + } // while (true) + } if ((GetAbortEndTime() != MAXULONGLONG) && IsAbortRequested()) { while (TRUE) @@ -1627,6 +1629,14 @@ Thread::UserAbort(EEPolicy::ThreadAbortTypes abortType, DWORD timeout) { return S_OK; } + +#ifdef FEATURE_THREAD_ACTIVATION + if (UseSpecialUserModeApc()) + { + InjectActivation(ActivationReason::ThreadAbort); + } +#endif // FEATURE_THREAD_ACTIVATION + ULONGLONG curTime = CLRGetTickCount64(); if (curTime >= GetAbortEndTime()) { @@ -5950,6 +5960,7 @@ void Thread::ApcActivationCallback(ULONG_PTR Parameter) { case ActivationReason::SuspendForGC: case ActivationReason::SuspendForDebugger: + case ActivationReason::ThreadAbort: HandleSuspensionForInterruptedThread(pContext); break; From c972517fe5589ec0c77d5e6ba92c952ca91e5aa1 Mon Sep 17 00:00:00 2001 From: Lakshan Fernando Date: Thu, 16 Jun 2022 07:51:40 -0700 Subject: [PATCH 152/337] Test additional NativeAOT Lib testing (#70212) * Test additional NativeAOT Lib testing * more libraries to un nativeaot rolling build * FB * FB2 * only write results file if specified in args * excluding failing tests * oops, missed pull before a forced push * excluding some recently added tests that fail * fix typo with end element * FB --- .../runtime-extra-platforms-other.yml | 29 +++ eng/pipelines/runtime.yml | 2 +- src/libraries/tests.proj | 177 ++++++++++++++++-- 3 files changed, 192 insertions(+), 16 deletions(-) diff --git a/eng/pipelines/runtime-extra-platforms-other.yml b/eng/pipelines/runtime-extra-platforms-other.yml index 9907d7ed9079ef..53acaa8c3ee186 100644 --- a/eng/pipelines/runtime-extra-platforms-other.yml +++ b/eng/pipelines/runtime-extra-platforms-other.yml @@ -72,6 +72,35 @@ jobs: eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), eq(variables['isRollingBuild'], true)) +# +# CoreCLR NativeAOT release build and additional libraries tests that are known to be passing +# Only when CoreCLR or library is changed +# +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml + buildConfig: Release + platforms: + - windows_x64 + - windows_arm64 + jobParameters: + testGroup: innerloop + isSingleFile: true + nameSuffix: NativeAOT_Libs_Passing + buildArgs: -s clr.alljits+clr.tools+clr.nativeaotlibs+clr.nativeaotruntime+libs+libs.tests -c $(_BuildConfig) /p:TestNativeAot=true /p:ArchiveTests=true + timeoutInMinutes: 180 + # extra steps, run tests + extraStepsTemplate: /eng/pipelines/libraries/helix.yml + extraStepsParameters: + creator: dotnet-bot + testRunNamePrefixSuffix: NativeAOT_$(_BuildConfig) + condition: >- + or( + eq(dependencies.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), + eq(dependencies.evaluate_paths.outputs['SetPathVars_coreclr.containsChange'], true), + eq(variables['isRollingBuild'], true)) + # Run net48 tests on win-x64 - template: /eng/pipelines/common/platform-matrix.yml parameters: diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index 0cf7e96a580768..301809c16cb373 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -260,7 +260,7 @@ jobs: testGroup: innerloop isSingleFile: true nameSuffix: NativeAOT - buildArgs: -s clr.alljits+clr.tools+clr.nativeaotlibs+clr.nativeaotruntime+libs+libs.tests -c $(_BuildConfig) /p:TestNativeAot=true /p:ArchiveTests=true + buildArgs: -s clr.alljits+clr.tools+clr.nativeaotlibs+clr.nativeaotruntime+libs+libs.tests -c $(_BuildConfig) /p:TestNativeAot=true /p:RunSmokeTestsOnly=true /p:ArchiveTests=true timeoutInMinutes: 180 # extra steps, run tests extraStepsTemplate: /eng/pipelines/libraries/helix.yml diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index 01cc7cd2ceb24b..f732de61da0739 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -395,20 +395,149 @@ - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -416,9 +545,27 @@ Include="@(HighAOTResourceRequiringProject)" /> + + + + + + + + + + + + + + + + + Include="@(SmokeTestProject)" /> From 3b04dc1c69935c3e59a137f48494021fd045050b Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Thu, 16 Jun 2022 07:57:24 -0700 Subject: [PATCH 153/337] Fix emitDispJumpList for Arm64 (#70542) * fix jitdump * Fix arm build * Another format --- src/coreclr/jit/emit.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index a8777adc3ed9cb..f68ce116bb8f48 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -3894,6 +3894,19 @@ void emitter::emitDispJumpList() unsigned int jmpCount = 0; for (instrDescJmp* jmp = emitJumpList; jmp != nullptr; jmp = jmp->idjNext) { +#if defined(TARGET_ARM64) + if ((jmp->idInsFmt() == IF_LARGEADR) || (jmp->idInsFmt() == IF_LARGELDC)) + { + printf("IG%02u IN%04x %3s[%u] -> %s\n", jmp->idjIG->igNum, jmp->idDebugOnlyInfo()->idNum, + codeGen->genInsDisplayName(jmp), jmp->idCodeSize(), getRegName(jmp->idReg1())); + } + else + { + printf("IG%02u IN%04x %3s[%u] -> IG%02u\n", jmp->idjIG->igNum, jmp->idDebugOnlyInfo()->idNum, + codeGen->genInsDisplayName(jmp), jmp->idCodeSize(), + ((insGroup*)emitCodeGetCookie(jmp->idAddr()->iiaBBlabel))->igNum); + } +#else printf("IG%02u IN%04x %3s[%u] -> IG%02u %s\n", jmp->idjIG->igNum, jmp->idDebugOnlyInfo()->idNum, codeGen->genInsDisplayName(jmp), jmp->idCodeSize(), ((insGroup*)emitCodeGetCookie(jmp->idAddr()->iiaBBlabel))->igNum, @@ -3903,6 +3916,7 @@ void emitter::emitDispJumpList() "" #endif ); +#endif jmpCount += 1; } printf(" total jump count: %u\n", jmpCount); From 8b3be893f0259d7b5c9a7ea66f9bdeecc9cafc13 Mon Sep 17 00:00:00 2001 From: Aman Khalid Date: Thu, 16 Jun 2022 08:09:08 -0700 Subject: [PATCH 154/337] Fix regression in runtime-jit-experimental (#70797) The newly-introduced `emitRemoveJumpToNextInst` optimization caused a regression when hot/cold-splitting, where jumps from the last hot instruction to the first cold instruction were erroneously removed. This is fixed by disabling the `isRemovableJmpCandidate` flag for branches between hot/cold sections. On an unrelated note, a JIT dump message has been added to indicate stress-splitting is occurring. --- src/coreclr/jit/codegenlinear.cpp | 33 +++++++++++++++++-------------- src/coreclr/jit/flowgraph.cpp | 1 + 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/coreclr/jit/codegenlinear.cpp b/src/coreclr/jit/codegenlinear.cpp index f2528f6f3c628d..b9026bfedd6f40 100644 --- a/src/coreclr/jit/codegenlinear.cpp +++ b/src/coreclr/jit/codegenlinear.cpp @@ -753,24 +753,27 @@ void CodeGen::genCodeForBBlist() break; case BBJ_ALWAYS: - inst_JMP(EJ_jmp, block->bbJumpDest +#ifdef TARGET_XARCH + { + // If a block was selected to place an alignment instruction because it ended + // with a jump, do not remove jumps from such blocks. + // Do not remove a jump between hot and cold regions. + bool isRemovableJmpCandidate = + !block->hasAlign() && !compiler->fgInDifferentRegions(block, block->bbJumpDest); + #ifdef TARGET_AMD64 - // AMD64 requires an instruction after a call instruction for unwinding - // inside an EH region so if the last instruction generated was a call instruction - // do not allow this jump to be marked for possible later removal. - // - // If a block was selected to place an alignment instruction because it ended - // with a jump, do not remove jumps from such blocks. - , - /* isRemovableJmpCandidate */ !GetEmitter()->emitIsLastInsCall() && !block->hasAlign() + // AMD64 requires an instruction after a call instruction for unwinding + // inside an EH region so if the last instruction generated was a call instruction + // do not allow this jump to be marked for possible later removal. + isRemovableJmpCandidate = isRemovableJmpCandidate && !GetEmitter()->emitIsLastInsCall(); +#endif // TARGET_AMD64 + + inst_JMP(EJ_jmp, block->bbJumpDest, isRemovableJmpCandidate); + } #else -#ifdef TARGET_XARCH - , - /* isRemovableJmpCandidate */ !block->hasAlign() -#endif + inst_JMP(EJ_jmp, block->bbJumpDest); +#endif // TARGET_XARCH -#endif - ); FALLTHROUGH; case BBJ_COND: diff --git a/src/coreclr/jit/flowgraph.cpp b/src/coreclr/jit/flowgraph.cpp index 52399aa6c16929..ac240be9a2d27f 100644 --- a/src/coreclr/jit/flowgraph.cpp +++ b/src/coreclr/jit/flowgraph.cpp @@ -3421,6 +3421,7 @@ PhaseStatus Compiler::fgDetermineFirstColdBlock() { firstColdBlock = fgFirstBB->bbNext; prevToFirstColdBlock = fgFirstBB; + JITDUMP("JitStressProcedureSplitting is enabled: Splitting after the first basic block\n"); } else { From f25caab2211a411f3682124a89266da6cdaad1de Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Thu, 16 Jun 2022 08:11:43 -0700 Subject: [PATCH 155/337] JIT: relax fwd sub restriction on changing class handle (#70587) For HW SIMD types, at least. Fixes #64879. --- src/coreclr/jit/forwardsub.cpp | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/coreclr/jit/forwardsub.cpp b/src/coreclr/jit/forwardsub.cpp index 4c3fae5f1d9f9e..4da3c62323f234 100644 --- a/src/coreclr/jit/forwardsub.cpp +++ b/src/coreclr/jit/forwardsub.cpp @@ -504,12 +504,6 @@ bool Compiler::fgForwardSubStatement(Statement* stmt) return false; } - if (gtGetStructHandleIfPresent(fwdSubNode) != gtGetStructHandleIfPresent(lhsNode)) - { - JITDUMP(" would change struct handle (assignment)\n"); - return false; - } - // If lhs is mulit-reg, rhs must be too. // if (lhsNode->IsMultiRegNode() && !fwdSubNode->IsMultiRegNode()) @@ -667,10 +661,29 @@ bool Compiler::fgForwardSubStatement(Statement* stmt) // // We may sometimes lose or change a type handle. Avoid substituting if so. // - if (gtGetStructHandleIfPresent(fwdSubNode) != gtGetStructHandleIfPresent(fsv.GetNode())) + // However, we allow free substitution of hardware SIMD types. + // + CORINFO_CLASS_HANDLE fwdHnd = gtGetStructHandleIfPresent(fwdSubNode); + CORINFO_CLASS_HANDLE useHnd = gtGetStructHandleIfPresent(fsv.GetNode()); + if (fwdHnd != useHnd) { - JITDUMP(" would change struct handle (substitution)\n"); - return false; + if ((fwdHnd == NO_CLASS_HANDLE) || (useHnd == NO_CLASS_HANDLE)) + { + JITDUMP(" would add/remove struct handle (substitution)\n"); + return false; + } + +#ifdef FEATURE_SIMD + const bool bothHWSIMD = isHWSIMDClass(fwdHnd) && isHWSIMDClass(useHnd); +#else + const bool bothHWSIMD = false; +#endif + + if (!bothHWSIMD) + { + JITDUMP(" would change struct handle (substitution)\n"); + return false; + } } #ifdef FEATURE_SIMD From 9ab00ef5c8904f28fba9b01b4fefd4ad672567fb Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Thu, 16 Jun 2022 11:14:27 -0400 Subject: [PATCH 156/337] Use LastIndexOf in ZipArchiveEntry.GetFileName_Unix (#70701) There's not particularly good reason to open-code the loop here. --- .../src/System/IO/Compression/ZipArchiveEntry.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs index 0e1fb42209594e..3a672848eebe10 100644 --- a/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs +++ b/src/libraries/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs @@ -1104,11 +1104,10 @@ private static string GetFileName_Windows(string path) /// private static string GetFileName_Unix(string path) { - int length = path.Length; - for (int i = length; --i >= 0;) - if (path[i] == '/') - return path.Substring(i + 1); - return path; + int i = path.LastIndexOf('/'); + return i >= 0 ? + path.Substring(i + 1) : + path; } private sealed class DirectToArchiveWriterStream : Stream From cfeab727717e1873631d7180a220d5475d8530a5 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Thu, 16 Jun 2022 08:49:18 -0700 Subject: [PATCH 157/337] Update dogfooding instructions (#70833) - Delete note about multilevel lookup. It is not relevant anymore. - Fix nightly feed url to net7 - Replace .NET Core with just .NET --- docs/project/dogfooding.md | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/docs/project/dogfooding.md b/docs/project/dogfooding.md index 3ff4160095b1e9..69f405a7f80764 100644 --- a/docs/project/dogfooding.md +++ b/docs/project/dogfooding.md @@ -19,9 +19,9 @@ dotnet nuget add source -n dotnet7 https://dnceng.pkgs.visualstudio.com/public/_ Then, you will be able to add the latest prerelease version of the desired package to your project. -**Example:** To add version 7.0.100-preview.5.22226.4 of the System.Data.OleDb package, use the [dotnet add package](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-add-package) command: +**Example:** To add version 7.0-preview.5.22226.4 of the System.Data.OleDb package, use the [dotnet add package](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-add-package) command: ``` -dotnet add package System.Data.OleDb -v 7.0.100-preview.5.22226.4 +dotnet add package System.Data.OleDb -v 7.0-preview.5.22226.4 ``` To use nightly builds of the entire runtime, follow the steps given in the rest of this document instead. @@ -30,9 +30,7 @@ To use nightly builds of the entire runtime, follow the steps given in the rest 1. Acquire the latest nightly .NET SDK by downloading and extracting a zip/tarball or using an installer from the [installers and binaries table in dotnet/installer](https://github.com/dotnet/installer#installers-and-binaries) (for example, https://aka.ms/dotnet/7.0/daily/dotnet-sdk-win-x64.zip). -2. By default, the dotnet CLI will use the globally installed SDK if it matches the major/minor version you request and has a higher revision. To force it to use a locally installed SDK, you must set an environment variable `DOTNET_MULTILEVEL_LOOKUP=0` in your shell. You can use `dotnet --info` to verify what version of the Shared Framework it is using. - -3. Reminder: if you are using a local copy of the dotnet CLI, take care that when you type `dotnet` you do not inadvertently pick up a different copy that you may have in your path. On Windows, for example, if you use a Command Prompt, a global copy may be in the path, so use the fully qualified path to your local `dotnet` (e.g. `C:\dotnet\dotnet.exe`). If you receive an error "error NETSDK1045: The current .NET SDK does not support targeting .NET 7.0." then you may be executing an older `dotnet`. +2. If you are using a local copy of the dotnet CLI, take care that when you type `dotnet` you do not inadvertently pick up a different copy that you may have in your path. On Windows, for example, if you use a Command Prompt, a global copy may be in the path, so use the fully qualified path to your local `dotnet` (e.g. `C:\dotnet\dotnet.exe`). If you receive an error "error NETSDK1045: The current .NET SDK does not support targeting .NET 7.0." then you may be executing an older `dotnet`. After setting up dotnet you can verify you are using the dogfooding version by executing `dotnet --info`. Here is an example output at the time of writing: ``` @@ -70,11 +68,10 @@ Learn about .NET Runtimes and SDKs: ``` -4. Our nightly builds are uploaded to dotnet-blob feeds, not NuGet - so ensure the .NET Core blob feed is in your nuget configuration in case you need other packages from .NET Core that aren't included in the download. For example, on Windows you could edit `%userprofile%\appdata\roaming\nuget\nuget.config` or on Linux edit `~/.nuget/NuGet/NuGet.Config` to add these lines: +3. Our nightly builds are uploaded to nightly feed, not NuGet - so ensure the nightly feed is in your nuget configuration in case you need other packages that aren't included in the download. For example, on Windows you could edit `%userprofile%\appdata\roaming\nuget\nuget.config` or on Linux edit `~/.nuget/NuGet/NuGet.Config` to add these lines: ```xml - - + ... ``` @@ -145,7 +142,7 @@ make it self-contained by adding a RuntimeIdentifier (RID). net7.0 - + 7.0.0-preview.5.22224.3 win-x64 From ab998cc9dc5dcd51881d2e98e3a35102ce83e193 Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Thu, 16 Jun 2022 09:49:57 -0700 Subject: [PATCH 158/337] Add icon to dotnet.exe on Windows (#70578) --- src/native/corehost/dotnet/CMakeLists.txt | 3 ++- src/native/corehost/dotnet/dotnet.ico | Bin 0 -> 45150 bytes src/native/corehost/dotnet/dotnet.rc | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 src/native/corehost/dotnet/dotnet.ico create mode 100644 src/native/corehost/dotnet/dotnet.rc diff --git a/src/native/corehost/dotnet/CMakeLists.txt b/src/native/corehost/dotnet/CMakeLists.txt index fe1b3512d9a684..986a09b253252a 100644 --- a/src/native/corehost/dotnet/CMakeLists.txt +++ b/src/native/corehost/dotnet/CMakeLists.txt @@ -6,7 +6,8 @@ set(DOTNET_PROJECT_NAME "dotnet") if(CLR_CMAKE_TARGET_WIN32) list(APPEND SOURCES - dotnet.manifest) + dotnet.manifest + dotnet.rc) endif() list(APPEND SOURCES diff --git a/src/native/corehost/dotnet/dotnet.ico b/src/native/corehost/dotnet/dotnet.ico new file mode 100644 index 0000000000000000000000000000000000000000..16c9148e8609531b6bde8509f503ec29010985c6 GIT binary patch literal 45150 zcmeHQ3s}`f7M}~4kSme6E181jmtgLS=KF=$bTvzb(liT`G!a&jLLP|%x5p-CXr(L~ zA-bk$3R);CE)SoqXoZFg0*Yn`B3dAVf_Qh%#gpSS_kmmVCE0wi%hvy0TA8qT?r?$T38A9&7NQi?&ZQY|YA)DVJq+7SU{Z@on zE+@psrnVkxK}bR*Assu`*7rU_h|?xQtSBGo^DrZ%VjCgLTqccc|7hn&sp|IQUl{WW z^g=eL{KVB~i#s9aoyLzDHRZjpuAUv~@l|Elw9@Ep4(2tA$xnU$-{li}_I+XF#S{KT zn`d1-V*B$KfjzUoo@dgdYX_4bP8~U%am2!JX`si>t$R8wS`qcKNrdIVHbcf93=8!+ zFvZ-@VSMq?o9p7&?JvCMv?I&Gc0^Uzo9B`X7bX9=u-ZQ$pxtMe?I$`Cj}=7ON1<{v zAqULJ2NuN4nwa+>Ruf3KHGk}=IQVAptzUlrW~qhJ)M>`_>}hGiOH2$Lt5xX3-;tD2 zZc=qRrdPZ0JxOI34*6U!-q<_tQrqP_Catb?TIaq0?6D)KS5)L4yAu0Tai`d_Ymt@F zH>aP@%H9*ZWO$G=0`u_2u7^`p&Sl?L05=372KW z_rM!=T|5FUT$T+{^>6srdD=f5HzjWvm*8cHUN!`eZ zge5`o+k;Qu$@Mt#NJcx83=*#>Z>R7`t;$Il7kaXj+4`qmO#^$%Zp`uxBmK9OSsd6i z)89ck&0P86)N8w*4YT<1L|Cx;#;mxg$@U75*G~7nuxZfd;|E614jS}is++ayEVy1Y~K}Y{XynLQk7a5?G>JT{0*-?ks)(V%qP1$sGQ!V7H^8Nh;|w|*>l*I=SkI= zdGlgU4QjvAdBv`z2=WbOfpz)f?1L_y6h-~0NgFIj`wjc8z^eaNtt9TBtbDCXos5nv`5=Iwx<;b;;DYuS{ zeB|dlL>7>ccVHhDN!%UQG{Pl(1oN+nscBPOU91J@&az`Ivw^ zimce;HGN8sxR{+kzv0{TT+35YepyaA?|dH}*O{vLAt}4OL*lsR%wjt&|4p7-WncEOijRB@DH%804w-rG5Y?gJ$UJ}KUvoG`<4g3ZtY z9Tgs4S62t*|3`hod`b29llI-r4Y54@OlnNu9uo$Y`%!YIn)naT=s$Px?6>Hd0vZ4JNn_%kcl&^zo)9I?Dw^RuLneuUL_jwJ znY~_Cw}z|@h1TFZ_$d7sBOvEruK(5$1LEi>q&4_1_dmJ+%lH=~AlJV<{WpE&&GXWXp|b}3R6q>pN;$S)Lgeg30QJO$qkO?a$DUq!Sb{nr)4E!BS!#?86S z*z@0It)=wK`4=P5Qs!5m zA7bz2`qzhBOX-*MFGirH%&$H_#NNyGuMfAD(l6&A8swBU(UZa z1Z2BJpmiaj?YYwVS{T|&ssZAm$3fdX!|z1UpSB`yG|S(Kpdd8!^st?S@Ni1|8}}W1 ziGSnb&BwRIU*gZlL|y7Keq{XAC0=-589y?9_?W0my*0%Tysyl^vs@Rf8iLnQ{K0Na z=mXY8cCqj1V?Xlqlz*oa`*EBuYN-AA%>=wdteKg1g* z)QNTWU31a9+{lOHbWvm34|ZU}Z=$e{`mxSZ(fi=okK=SvW7rQ^W8A!ozp?omT81|z+j2pBE+qKoPou~XbzMrid z%YObC1UfLGKCJWm|HXx2_kB|);uEcNkZTP4wS5nRcJTINJJQ0?by(C&`ME`z^|2pi zG$obx%j=i=#Gi~G89y?9?yZ9QV9^v~?^#}3Y6=_bqf^>1_a7NQ_f|oDuxN_0_biwD zPjkSZpAT7Y90Y1FJPE0#FRN2Qt!Z7U`tCTS`C8;`;rLJwj!VAVAH-2tu8#dU4(mu! zt~N?Yt)D#A#;>m(?Lg{t*Is_yz2AvKyx~19$SyQL?C)tc#Xe$)P719i8N%BXJkq}U zol8pmBz{e?Zc(RRoLK|&j$%s+dDXEd15ZmhGEf7S(k zyeu5gQeE}|AKC_GkxYC>3w24}5n5c@5ER2oK29 zhac+X?ZbCEz&5}E67m|N+Yp}m*oW_G!2FBsL%X3*G>;8wAFc`1E3yytvk9?93Vk>p z+eEak^9$<%VjmJd9~RlCPdAL$#{>4()jnJc?0(Ul>;u2~cP2#k@%sy`Cw9L7JL?;ijpaYcVZZ(1 z^|SGpGsgY*|8WE3un+G$vo;!vKgeOn^ZKD5leTY+_}BnD4AIZpYwWVrUyFdTaWzz) z#9!hM2pAeK#^#gphX^zsh2w^b-Xds<47%Yyg$>Q{+l5VipTgMjjq<2#nuK*@Qz>8f z{ced*-SL6732}-P%J};U*skfMfAIX9 Date: Thu, 16 Jun 2022 10:37:25 -0700 Subject: [PATCH 159/337] Add two new stages to prepare for our new custom type marshalling design. (#70598) --- .../PInvokeStubCodeGenerator.cs | 14 +- .../GeneratedStatements.cs | 15 +- ...ributedMarshallingModelGeneratorFactory.cs | 27 +- .../CustomNativeTypeMarshallingGenerator.cs | 12 + .../Marshalling/DelegateMarshaller.cs | 2 +- .../ICustomNativeTypeMarshallingStrategy.cs | 238 ++++++++++-------- .../StubCodeContext.cs | 19 +- .../SyntaxExtensions.cs | 11 +- 8 files changed, 198 insertions(+), 140 deletions(-) diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/PInvokeStubCodeGenerator.cs b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/PInvokeStubCodeGenerator.cs index 856a7b4d1c2142..66b7c5f2f85442 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/PInvokeStubCodeGenerator.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/PInvokeStubCodeGenerator.cs @@ -146,18 +146,20 @@ public BlockSyntax GeneratePInvokeBody(string dllImportName) var tryStatements = new List(); tryStatements.AddRange(statements.Marshal); - var invokeStatement = statements.InvokeStatement; + BlockSyntax fixedBlock = Block(statements.PinnedMarshal); if (_setLastError) { StatementSyntax clearLastError = MarshallerHelpers.CreateClearLastSystemErrorStatement(SuccessErrorCode); StatementSyntax getLastError = MarshallerHelpers.CreateGetLastSystemErrorStatement(LastErrorIdentifier); - invokeStatement = Block(clearLastError, invokeStatement, getLastError); + fixedBlock = fixedBlock.AddStatements(clearLastError, statements.InvokeStatement, getLastError); } - invokeStatement = statements.Pin.NestFixedStatements(invokeStatement); - - tryStatements.Add(invokeStatement); + else + { + fixedBlock = fixedBlock.AddStatements(statements.InvokeStatement); + } + tryStatements.Add(statements.Pin.NestFixedStatements(fixedBlock)); // = true; if (!statements.GuaranteedUnmarshal.IsEmpty) { @@ -166,7 +168,7 @@ public BlockSyntax GeneratePInvokeBody(string dllImportName) LiteralExpression(SyntaxKind.TrueLiteralExpression)))); } - tryStatements.AddRange(statements.KeepAlive); + tryStatements.AddRange(statements.NotifyForSuccessfulInvoke); tryStatements.AddRange(statements.Unmarshal); List allStatements = setupStatements; diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/GeneratedStatements.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/GeneratedStatements.cs index 50572f3c6da4df..5f46ca36737818 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/GeneratedStatements.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/GeneratedStatements.cs @@ -18,9 +18,10 @@ public struct GeneratedStatements public ImmutableArray Setup { get; init; } public ImmutableArray Marshal { get; init; } public ImmutableArray Pin { get; init; } + public ImmutableArray PinnedMarshal { get; init; } public StatementSyntax InvokeStatement { get; init; } public ImmutableArray Unmarshal { get; init; } - public ImmutableArray KeepAlive { get; init; } + public ImmutableArray NotifyForSuccessfulInvoke { get; init; } public ImmutableArray GuaranteedUnmarshal { get; init; } public ImmutableArray Cleanup { get; init; } @@ -31,9 +32,11 @@ public static GeneratedStatements Create(BoundGenerators marshallers, StubCodeCo Setup = GenerateStatementsForStubContext(marshallers, context with { CurrentStage = StubCodeContext.Stage.Setup }), Marshal = GenerateStatementsForStubContext(marshallers, context with { CurrentStage = StubCodeContext.Stage.Marshal }), Pin = GenerateStatementsForStubContext(marshallers, context with { CurrentStage = StubCodeContext.Stage.Pin }).Cast().ToImmutableArray(), + PinnedMarshal = GenerateStatementsForStubContext(marshallers, context with { CurrentStage = StubCodeContext.Stage.PinnedMarshal }), InvokeStatement = GenerateStatementForNativeInvoke(marshallers, context with { CurrentStage = StubCodeContext.Stage.Invoke }, expressionToInvoke), - Unmarshal = GenerateStatementsForStubContext(marshallers, context with { CurrentStage = StubCodeContext.Stage.Unmarshal }), - KeepAlive = GenerateStatementsForStubContext(marshallers, context with { CurrentStage = StubCodeContext.Stage.KeepAlive }), + Unmarshal = GenerateStatementsForStubContext(marshallers, context with { CurrentStage = StubCodeContext.Stage.UnmarshalCapture }) + .AddRange(GenerateStatementsForStubContext(marshallers, context with { CurrentStage = StubCodeContext.Stage.Unmarshal })), + NotifyForSuccessfulInvoke = GenerateStatementsForStubContext(marshallers, context with { CurrentStage = StubCodeContext.Stage.NotifyForSuccessfulInvoke }), GuaranteedUnmarshal = GenerateStatementsForStubContext(marshallers, context with { CurrentStage = StubCodeContext.Stage.GuaranteedUnmarshal }), Cleanup = GenerateStatementsForStubContext(marshallers, context with { CurrentStage = StubCodeContext.Stage.Cleanup }), }; @@ -48,7 +51,7 @@ private static ImmutableArray GenerateStatementsForStubContext( statementsToUpdate.AddRange(retStatements); } - if (context.CurrentStage is StubCodeContext.Stage.Unmarshal or StubCodeContext.Stage.GuaranteedUnmarshal) + if (context.CurrentStage is StubCodeContext.Stage.UnmarshalCapture or StubCodeContext.Stage.Unmarshal or StubCodeContext.Stage.GuaranteedUnmarshal) { // For Unmarshal and GuaranteedUnmarshal stages, use the topologically sorted // marshaller list to generate the marshalling statements @@ -113,10 +116,12 @@ private static SyntaxTriviaList GenerateStageTrivia(StubCodeContext.Stage stage) StubCodeContext.Stage.Setup => "Perform required setup.", StubCodeContext.Stage.Marshal => "Convert managed data to native data.", StubCodeContext.Stage.Pin => "Pin data in preparation for calling the P/Invoke.", + StubCodeContext.Stage.PinnedMarshal => "Convert managed data to native data that requires the managed data to be pinned.", StubCodeContext.Stage.Invoke => "Call the P/Invoke.", + StubCodeContext.Stage.UnmarshalCapture => "Capture the native data into marshaller instances in case conversion to managed data throws an exception.", StubCodeContext.Stage.Unmarshal => "Convert native data to managed data.", StubCodeContext.Stage.Cleanup => "Perform required cleanup.", - StubCodeContext.Stage.KeepAlive => "Keep alive any managed objects that need to stay alive across the call.", + StubCodeContext.Stage.NotifyForSuccessfulInvoke => "Keep alive any managed objects that need to stay alive across the call.", StubCodeContext.Stage.GuaranteedUnmarshal => "Convert native data to managed data even in the case of an exception during the non-cleanup phases.", _ => throw new ArgumentOutOfRangeException(nameof(stage)) }; diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/AttributedMarshallingModelGeneratorFactory.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/AttributedMarshallingModelGeneratorFactory.cs index e2d5a0513846af..80afc1731f0c94 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/AttributedMarshallingModelGeneratorFactory.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/AttributedMarshallingModelGeneratorFactory.cs @@ -212,10 +212,13 @@ private IMarshallingGenerator CreateCustomNativeTypeMarshaller(TypePositionInfo { return CreateNativeCollectionMarshaller(info, context, collectionMarshallingInfo, marshallingStrategy); } - - if (marshalInfo.NativeValueType is not null) + else if (marshalInfo.NativeValueType is not null) { - marshallingStrategy = DecorateWithTwoStageMarshallingStrategy(marshalInfo, marshallingStrategy); + marshallingStrategy = new CustomNativeTypeWithToFromNativeValueMarshalling(marshallingStrategy, marshalInfo.NativeValueType.Syntax); + if (marshalInfo.PinningFeatures.HasFlag(CustomTypeMarshallerPinning.NativeType) && marshalInfo.MarshallingFeatures.HasFlag(CustomTypeMarshallerFeatures.TwoStageMarshalling)) + { + marshallingStrategy = new PinnableMarshallerTypeMarshalling(marshallingStrategy); + } } IMarshallingGenerator marshallingGenerator = new CustomNativeTypeMarshallingGenerator(marshallingStrategy, enableByValueContentsMarshalling: false); @@ -283,18 +286,6 @@ private static void ValidateCustomNativeTypeMarshallingSupported(TypePositionInf } } - private static ICustomNativeTypeMarshallingStrategy DecorateWithTwoStageMarshallingStrategy(NativeMarshallingAttributeInfo marshalInfo, ICustomNativeTypeMarshallingStrategy nativeTypeMarshaller) - { - TypeSyntax nativeValueTypeSyntax = marshalInfo.NativeValueType!.Syntax; - - if (marshalInfo.PinningFeatures.HasFlag(CustomTypeMarshallerPinning.NativeType) && marshalInfo.MarshallingFeatures.HasFlag(CustomTypeMarshallerFeatures.TwoStageMarshalling)) - { - return new PinnableMarshallerTypeMarshalling(nativeTypeMarshaller, nativeValueTypeSyntax); - } - - return new CustomNativeTypeWithToFromNativeValueMarshalling(nativeTypeMarshaller, nativeValueTypeSyntax); - } - private IMarshallingGenerator CreateNativeCollectionMarshaller( TypePositionInfo info, StubCodeContext context, @@ -324,10 +315,10 @@ private IMarshallingGenerator CreateNativeCollectionMarshaller( marshallingStrategy = new LinearCollectionWithNonBlittableElementsMarshalling(marshallingStrategy, elementMarshaller, elementInfo, numElementsExpression); } - // Explicitly insert the Value property handling here (before numElements handling) so that the numElements handling will be emitted before the Value property handling in unmarshalling. - if (collectionInfo.NativeValueType is not null) + marshallingStrategy = new CustomNativeTypeWithToFromNativeValueMarshalling(marshallingStrategy, collectionInfo.NativeValueType.Syntax); + if (collectionInfo.PinningFeatures.HasFlag(CustomTypeMarshallerPinning.NativeType) && collectionInfo.MarshallingFeatures.HasFlag(CustomTypeMarshallerFeatures.TwoStageMarshalling)) { - marshallingStrategy = DecorateWithTwoStageMarshallingStrategy(collectionInfo, marshallingStrategy); + marshallingStrategy = new PinnableMarshallerTypeMarshalling(marshallingStrategy); } TypeSyntax nativeElementType = elementMarshaller.AsNativeType(elementInfo); diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/CustomNativeTypeMarshallingGenerator.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/CustomNativeTypeMarshallingGenerator.cs index c770312495087c..de758a34d23e0b 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/CustomNativeTypeMarshallingGenerator.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/CustomNativeTypeMarshallingGenerator.cs @@ -63,6 +63,18 @@ public IEnumerable Generate(TypePositionInfo info, StubCodeCont return _nativeTypeMarshaller.GeneratePinStatements(info, context); } break; + case StubCodeContext.Stage.PinnedMarshal: + if (!info.IsManagedReturnPosition && info.RefKind != RefKind.Out) + { + return _nativeTypeMarshaller.GeneratePinnedMarshalStatements(info, context); + } + break; + case StubCodeContext.Stage.UnmarshalCapture: + if (info.IsManagedReturnPosition || (info.IsByRef && info.RefKind != RefKind.In)) + { + return _nativeTypeMarshaller.GenerateUnmarshalCaptureStatements(info, context); + } + break; case StubCodeContext.Stage.Unmarshal: if (info.IsManagedReturnPosition || (info.IsByRef && info.RefKind != RefKind.In) || (_enableByValueContentsMarshalling && !info.IsByRef && info.ByValueContentsMarshalKind.HasFlag(ByValueContentsMarshalKind.Out))) diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/DelegateMarshaller.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/DelegateMarshaller.cs index ff9873c93b3b9e..00c7f6e2b941b0 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/DelegateMarshaller.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/DelegateMarshaller.cs @@ -87,7 +87,7 @@ public IEnumerable Generate(TypePositionInfo info, StubCodeCont LiteralExpression(SyntaxKind.NullLiteralExpression)))); } break; - case StubCodeContext.Stage.KeepAlive: + case StubCodeContext.Stage.NotifyForSuccessfulInvoke: if (info.RefKind != RefKind.Out) { yield return ExpressionStatement( diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ICustomNativeTypeMarshallingStrategy.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ICustomNativeTypeMarshallingStrategy.cs index 5ba85d6806dc15..0d89208515d78f 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ICustomNativeTypeMarshallingStrategy.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ICustomNativeTypeMarshallingStrategy.cs @@ -22,12 +22,16 @@ internal interface ICustomNativeTypeMarshallingStrategy IEnumerable GenerateMarshalStatements(TypePositionInfo info, StubCodeContext context, IEnumerable nativeTypeConstructorArguments); + IEnumerable GeneratePinnedMarshalStatements(TypePositionInfo info, StubCodeContext context); + IEnumerable GenerateSetupStatements(TypePositionInfo info, StubCodeContext context); IEnumerable GenerateCleanupStatements(TypePositionInfo info, StubCodeContext context); IEnumerable GeneratePinStatements(TypePositionInfo info, StubCodeContext context); + IEnumerable GenerateUnmarshalCaptureStatements(TypePositionInfo info, StubCodeContext context); + IEnumerable GenerateUnmarshalStatements(TypePositionInfo info, StubCodeContext context); bool UsesNativeIdentifier(TypePositionInfo info, StubCodeContext context); @@ -71,6 +75,11 @@ public IEnumerable GenerateMarshalStatements(TypePositionInfo i .WithArgumentList(ArgumentList(SeparatedList(nativeTypeConstructorArguments))))); } + public IEnumerable GeneratePinnedMarshalStatements(TypePositionInfo info, StubCodeContext context) + { + return Array.Empty(); + } + public IEnumerable GenerateUnmarshalStatements(TypePositionInfo info, StubCodeContext context) { // If the current element is being marshalled by-value [Out], then don't call the ToManaged method and do the assignment. @@ -92,6 +101,11 @@ public IEnumerable GenerateUnmarshalStatements(TypePositionInfo IdentifierName(ShapeMemberNames.Value.ToManaged))))); } + public IEnumerable GenerateUnmarshalCaptureStatements(TypePositionInfo info, StubCodeContext context) + { + return Array.Empty(); + } + public IEnumerable GetNativeTypeConstructorArguments(TypePositionInfo info, StubCodeContext context) { yield return Argument(IdentifierName(context.GetIdentifiers(info).managed)); @@ -181,6 +195,16 @@ public IEnumerable GenerateMarshalStatements(TypePositionInfo i { yield return statement; } + } + + public IEnumerable GeneratePinnedMarshalStatements(TypePositionInfo info, StubCodeContext context) + { + var subContext = new CustomNativeTypeWithToFromNativeValueContext(context); + + foreach (StatementSyntax statement in _innerMarshaller.GeneratePinnedMarshalStatements(info, subContext)) + { + yield return statement; + } // = .ToNativeValue(); yield return ExpressionStatement( @@ -205,7 +229,7 @@ private static StatementSyntax GenerateFromNativeValueInvocation(TypePositionInf ArgumentList(SingletonSeparatedList(Argument(IdentifierName(context.GetIdentifiers(info).native)))))); } - public IEnumerable GenerateUnmarshalStatements(TypePositionInfo info, StubCodeContext context) + public IEnumerable GenerateUnmarshalCaptureStatements(TypePositionInfo info, StubCodeContext context) { var subContext = new CustomNativeTypeWithToFromNativeValueContext(context); @@ -213,6 +237,11 @@ public IEnumerable GenerateUnmarshalStatements(TypePositionInfo { yield return GenerateFromNativeValueInvocation(info, context, subContext); } + } + + public IEnumerable GenerateUnmarshalStatements(TypePositionInfo info, StubCodeContext context) + { + var subContext = new CustomNativeTypeWithToFromNativeValueContext(context); foreach (StatementSyntax statement in _innerMarshaller.GenerateUnmarshalStatements(info, subContext)) { @@ -300,6 +329,11 @@ public IEnumerable GenerateMarshalStatements(TypePositionInfo i } } + public IEnumerable GeneratePinnedMarshalStatements(TypePositionInfo info, StubCodeContext context) + { + return _innerMarshaller.GeneratePinnedMarshalStatements(info, context); + } + private static bool StackAllocOptimizationValid(TypePositionInfo info, StubCodeContext context) { return context.SingleFrameSpansNativeContext && (!info.IsByRef || info.RefKind == RefKind.In); @@ -320,6 +354,11 @@ public IEnumerable GenerateSetupStatements(TypePositionInfo inf return _innerMarshaller.GenerateSetupStatements(info, context); } + public IEnumerable GenerateUnmarshalCaptureStatements(TypePositionInfo info, StubCodeContext context) + { + return _innerMarshaller.GenerateUnmarshalCaptureStatements(info, context); + } + public IEnumerable GenerateUnmarshalStatements(TypePositionInfo info, StubCodeContext context) { return _innerMarshaller.GenerateUnmarshalStatements(info, context); @@ -390,6 +429,11 @@ public IEnumerable GenerateMarshalStatements(TypePositionInfo i return _innerMarshaller.GenerateMarshalStatements(info, context, nativeTypeConstructorArguments); } + public IEnumerable GeneratePinnedMarshalStatements(TypePositionInfo info, StubCodeContext context) + { + return _innerMarshaller.GeneratePinnedMarshalStatements(info, context); + } + public IEnumerable GeneratePinStatements(TypePositionInfo info, StubCodeContext context) { return _innerMarshaller.GeneratePinStatements(info, context); @@ -400,6 +444,11 @@ public IEnumerable GenerateSetupStatements(TypePositionInfo inf return _innerMarshaller.GenerateSetupStatements(info, context); } + public IEnumerable GenerateUnmarshalCaptureStatements(TypePositionInfo info, StubCodeContext context) + { + return _innerMarshaller.GenerateUnmarshalCaptureStatements(info, context); + } + public IEnumerable GenerateUnmarshalStatements(TypePositionInfo info, StubCodeContext context) { return _innerMarshaller.GenerateUnmarshalStatements(info, context); @@ -422,71 +471,36 @@ public bool UsesNativeIdentifier(TypePositionInfo info, StubCodeContext context) internal sealed class PinnableMarshallerTypeMarshalling : ICustomNativeTypeMarshallingStrategy { private readonly ICustomNativeTypeMarshallingStrategy _innerMarshaller; - private readonly TypeSyntax _nativeValueType; - public PinnableMarshallerTypeMarshalling(ICustomNativeTypeMarshallingStrategy innerMarshaller, TypeSyntax nativeValueType) + public PinnableMarshallerTypeMarshalling(ICustomNativeTypeMarshallingStrategy innerMarshaller) { _innerMarshaller = innerMarshaller; - _nativeValueType = nativeValueType; - } - - private static bool CanPinMarshaller(TypePositionInfo info, StubCodeContext context) - { - return context.SingleFrameSpansNativeContext && !info.IsManagedReturnPosition && !info.IsByRef || info.RefKind == RefKind.In; } public TypeSyntax AsNativeType(TypePositionInfo info) { - return _nativeValueType; + return _innerMarshaller.AsNativeType(info); } public IEnumerable GenerateCleanupStatements(TypePositionInfo info, StubCodeContext context) { - var subContext = new CustomNativeTypeWithToFromNativeValueContext(context); - - if (!context.AdditionalTemporaryStateLivesAcrossStages) - { - // .Value = ; - yield return GenerateFromNativeValueInvocation(info, context, subContext); - } - - foreach (StatementSyntax statement in _innerMarshaller.GenerateCleanupStatements(info, subContext)) - { - yield return statement; - } + return _innerMarshaller.GenerateCleanupStatements(info, context); } public IEnumerable GenerateMarshalStatements(TypePositionInfo info, StubCodeContext context, IEnumerable nativeTypeConstructorArguments) { - var subContext = new CustomNativeTypeWithToFromNativeValueContext(context); - foreach (StatementSyntax statement in _innerMarshaller.GenerateMarshalStatements(info, subContext, nativeTypeConstructorArguments)) - { - yield return statement; - } - - if (!CanPinMarshaller(info, context)) - yield return GenerateToNativeValueInvocation(info, context, subContext); + return _innerMarshaller.GenerateMarshalStatements(info, context, nativeTypeConstructorArguments); } - private static StatementSyntax GenerateToNativeValueInvocation(TypePositionInfo info, StubCodeContext context, CustomNativeTypeWithToFromNativeValueContext subContext) + public IEnumerable GeneratePinnedMarshalStatements(TypePositionInfo info, StubCodeContext context) { - // = .ToNativeValue(); - return ExpressionStatement( - AssignmentExpression( - SyntaxKind.SimpleAssignmentExpression, - IdentifierName(context.GetIdentifiers(info).native), - InvocationExpression( - MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, - IdentifierName(subContext.GetIdentifiers(info).native), - IdentifierName(ShapeMemberNames.Value.ToNativeValue)), - ArgumentList()))); + return _innerMarshaller.GeneratePinnedMarshalStatements(info, context); } public IEnumerable GeneratePinStatements(TypePositionInfo info, StubCodeContext context) { // The type of the ignored identifier isn't relevant, so we use void* for all. - // fixed (void* = &) - // + // fixed (void* = &); var subContext = new CustomNativeTypeWithToFromNativeValueContext(context); yield return FixedStatement( VariableDeclaration( @@ -495,56 +509,27 @@ public IEnumerable GeneratePinStatements(TypePositionInfo info, VariableDeclarator(Identifier(context.GetAdditionalIdentifier(info, "ignored"))) .WithInitializer(EqualsValueClause( IdentifierName(subContext.GetIdentifiers(info).native))))), - GenerateToNativeValueInvocation(info, context, subContext)); + EmptyStatement()); } public IEnumerable GenerateSetupStatements(TypePositionInfo info, StubCodeContext context) { - var subContext = new CustomNativeTypeWithToFromNativeValueContext(context); - yield return LocalDeclarationStatement( - VariableDeclaration( - _innerMarshaller.AsNativeType(info), - SingletonSeparatedList( - VariableDeclarator(subContext.GetIdentifiers(info).native) - .WithInitializer(EqualsValueClause(LiteralExpression(SyntaxKind.DefaultLiteralExpression)))))); - - foreach (StatementSyntax statement in _innerMarshaller.GenerateSetupStatements(info, subContext)) - { - yield return statement; - } + return _innerMarshaller.GenerateSetupStatements(info, context); } - private static StatementSyntax GenerateFromNativeValueInvocation(TypePositionInfo info, StubCodeContext context, CustomNativeTypeWithToFromNativeValueContext subContext) + public IEnumerable GenerateUnmarshalCaptureStatements(TypePositionInfo info, StubCodeContext context) { - // .FromNativeValue(); - return ExpressionStatement( - InvocationExpression( - MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, - IdentifierName(subContext.GetIdentifiers(info).native), - IdentifierName(ShapeMemberNames.Value.FromNativeValue)), - ArgumentList(SingletonSeparatedList(Argument(IdentifierName(context.GetIdentifiers(info).native)))))); + return _innerMarshaller.GenerateUnmarshalCaptureStatements(info, context); } public IEnumerable GenerateUnmarshalStatements(TypePositionInfo info, StubCodeContext context) { - var subContext = new CustomNativeTypeWithToFromNativeValueContext(context); - - if (info.IsManagedReturnPosition || (info.IsByRef && info.RefKind != RefKind.In)) - { - // .Value = ; - yield return GenerateFromNativeValueInvocation(info, context, subContext); - } - - foreach (StatementSyntax statement in _innerMarshaller.GenerateUnmarshalStatements(info, subContext)) - { - yield return statement; - } + return _innerMarshaller.GenerateUnmarshalStatements(info, context); } public IEnumerable GetNativeTypeConstructorArguments(TypePositionInfo info, StubCodeContext context) { - var subContext = new CustomNativeTypeWithToFromNativeValueContext(context); - return _innerMarshaller.GetNativeTypeConstructorArguments(info, subContext); + return _innerMarshaller.GetNativeTypeConstructorArguments(info, context); } public bool UsesNativeIdentifier(TypePositionInfo info, StubCodeContext context) @@ -596,6 +581,12 @@ public IEnumerable GenerateMarshalStatements(TypePositionInfo i return _innerMarshaller.GenerateMarshalStatements(info, context, nativeTypeConstructorArguments); } + public IEnumerable GeneratePinnedMarshalStatements(TypePositionInfo info, StubCodeContext context) + { + return _innerMarshaller.GeneratePinnedMarshalStatements(info, context); + } + + public IEnumerable GeneratePinStatements(TypePositionInfo info, StubCodeContext context) { return _innerMarshaller.GeneratePinStatements(info, context); @@ -606,18 +597,7 @@ public IEnumerable GenerateSetupStatements(TypePositionInfo inf return _innerMarshaller.GenerateSetupStatements(info, context); } - private IEnumerable GenerateUnmarshallerCollectionInitialization(TypePositionInfo info, StubCodeContext context) - { - string marshalerIdentifier = MarshallerHelpers.GetMarshallerIdentifier(info, context); - if (info.RefKind == RefKind.Out || info.IsManagedReturnPosition) - { - yield return ExpressionStatement(AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, - IdentifierName(marshalerIdentifier), - ImplicitObjectCreationExpression().AddArgumentListArguments(Argument(_sizeOfElementExpression)))); - } - } - - public IEnumerable GenerateUnmarshalStatements(TypePositionInfo info, StubCodeContext context) + public IEnumerable GenerateUnmarshalCaptureStatements(TypePositionInfo info, StubCodeContext context) { // To fulfill the generic contiguous collection marshaller design, // we need to emit code to initialize the collection marshaller with the size of native elements @@ -628,13 +608,28 @@ public IEnumerable GenerateUnmarshalStatements(TypePositionInfo { yield return statement; } - - foreach (StatementSyntax statement in _innerMarshaller.GenerateUnmarshalStatements(info, context)) + foreach (StatementSyntax statement in _innerMarshaller.GenerateUnmarshalCaptureStatements(info, context)) { yield return statement; } } + private IEnumerable GenerateUnmarshallerCollectionInitialization(TypePositionInfo info, StubCodeContext context) + { + string marshalerIdentifier = MarshallerHelpers.GetMarshallerIdentifier(info, context); + if (info.RefKind == RefKind.Out || info.IsManagedReturnPosition) + { + yield return ExpressionStatement(AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, + IdentifierName(marshalerIdentifier), + ImplicitObjectCreationExpression().AddArgumentListArguments(Argument(_sizeOfElementExpression)))); + } + } + + public IEnumerable GenerateUnmarshalStatements(TypePositionInfo info, StubCodeContext context) + { + return _innerMarshaller.GenerateUnmarshalStatements(info, context); + } + public IEnumerable GetNativeTypeConstructorArguments(TypePositionInfo info, StubCodeContext context) { foreach (ArgumentSyntax arg in _innerMarshaller.GetNativeTypeConstructorArguments(info, context)) @@ -741,6 +736,11 @@ public IEnumerable GenerateMarshalStatements(TypePositionInfo i ArgumentList())))))); } + public IEnumerable GeneratePinnedMarshalStatements(TypePositionInfo info, StubCodeContext context) + { + return _innerMarshaller.GeneratePinnedMarshalStatements(info, context); + } + public IEnumerable GeneratePinStatements(TypePositionInfo info, StubCodeContext context) { return _innerMarshaller.GeneratePinStatements(info, context); @@ -751,6 +751,11 @@ public IEnumerable GenerateSetupStatements(TypePositionInfo inf return _innerMarshaller.GenerateSetupStatements(info, context); } + public IEnumerable GenerateUnmarshalCaptureStatements(TypePositionInfo info, StubCodeContext context) + { + return _innerMarshaller.GenerateUnmarshalCaptureStatements(info, context); + } + public IEnumerable GenerateUnmarshalStatements(TypePositionInfo info, StubCodeContext context) { string nativeIdentifier = context.GetIdentifiers(info).native; @@ -999,7 +1004,7 @@ private LocalDeclarationStatementSyntax GeneratedManagedValuesDestinationDeclara ArgumentList(SingletonSeparatedList(Argument(IdentifierName(numElementsIdentifier)))))))))); } - private StatementSyntax GenerateContentsMarshallingStatement(TypePositionInfo info, StubCodeContext context, ExpressionSyntax lengthExpression) + private StatementSyntax GenerateContentsMarshallingStatement(TypePositionInfo info, StubCodeContext context, ExpressionSyntax lengthExpression, params StubCodeContext.Stage[] stagesToGeneratePerElement) { string managedSpanIdentifier = MarshallerHelpers.GetManagedSpanIdentifier(info, context); string nativeSpanIdentifier = MarshallerHelpers.GetNativeSpanIdentifier(info, context); @@ -1008,11 +1013,6 @@ private StatementSyntax GenerateContentsMarshallingStatement(TypePositionInfo in managedSpanIdentifier, nativeSpanIdentifier, context); - var elementSubContext = new LinearCollectionElementMarshallingCodeContext( - context.CurrentStage, - managedSpanIdentifier, - nativeSpanIdentifier, - context); TypePositionInfo localElementInfo = _elementInfo with { @@ -1022,7 +1022,13 @@ private StatementSyntax GenerateContentsMarshallingStatement(TypePositionInfo in NativeIndex = info.NativeIndex }; - List elementStatements = _elementMarshaller.Generate(localElementInfo, elementSubContext).ToList(); + List elementStatements = new(); + + foreach (var stage in stagesToGeneratePerElement) + { + var elementSubContext = elementSetupSubContext with { CurrentStage = stage }; + elementStatements.AddRange(_elementMarshaller.Generate(localElementInfo, elementSubContext)); + } if (elementStatements.Any()) { @@ -1032,12 +1038,12 @@ private StatementSyntax GenerateContentsMarshallingStatement(TypePositionInfo in if (_elementMarshaller.AsNativeType(_elementInfo) is PointerTypeSyntax elementNativeType) { - PointerNativeTypeAssignmentRewriter rewriter = new(elementSubContext.GetIdentifiers(localElementInfo).native, elementNativeType); + PointerNativeTypeAssignmentRewriter rewriter = new(elementSetupSubContext.GetIdentifiers(localElementInfo).native, elementNativeType); marshallingStatement = (StatementSyntax)rewriter.Visit(marshallingStatement); } // Iterate through the elements of the native collection to unmarshal them - return MarshallerHelpers.GetForLoop(lengthExpression, elementSubContext.IndexerIdentifier) + return MarshallerHelpers.GetForLoop(lengthExpression, elementSetupSubContext.IndexerIdentifier) .WithStatement(marshallingStatement); } return EmptyStatement(); @@ -1053,7 +1059,8 @@ public IEnumerable GenerateCleanupStatements(TypePositionInfo i StatementSyntax contentsCleanupStatements = GenerateContentsMarshallingStatement(info, context, MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName(MarshallerHelpers.GetNativeSpanIdentifier(info, context)), - IdentifierName("Length"))); + IdentifierName("Length")), + StubCodeContext.Stage.Cleanup); if (!contentsCleanupStatements.IsKind(SyntaxKind.EmptyStatement)) { @@ -1101,9 +1108,21 @@ public IEnumerable GenerateMarshalStatements(TypePositionInfo i GenerateContentsMarshallingStatement(info, context, MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName(MarshallerHelpers.GetManagedSpanIdentifier(info, context)), - IdentifierName("Length")))); + IdentifierName("Length")), + StubCodeContext.Stage.Marshal, + // Using the PinnedMarshal stage here isn't strictly valid as we don't guarantee that GetPinnableReference + // is pinned, but for our existing marshallers this is not an issue and we'll be removing support for stateful element marshallers soon + // (at which point we can remove this) + // and address this problem better when we bring them back in the future. + StubCodeContext.Stage.PinnedMarshal)); + } + + public IEnumerable GeneratePinnedMarshalStatements(TypePositionInfo info, StubCodeContext context) + { + return _innerMarshaller.GeneratePinnedMarshalStatements(info, context); } + public IEnumerable GeneratePinStatements(TypePositionInfo info, StubCodeContext context) { return _innerMarshaller.GeneratePinStatements(info, context); @@ -1114,6 +1133,11 @@ public IEnumerable GenerateSetupStatements(TypePositionInfo inf return _innerMarshaller.GenerateSetupStatements(info, context); } + public IEnumerable GenerateUnmarshalCaptureStatements(TypePositionInfo info, StubCodeContext context) + { + return _innerMarshaller.GenerateUnmarshalCaptureStatements(info, context); + } + private StatementSyntax GenerateByValueUnmarshalStatement(TypePositionInfo info, StubCodeContext context) { // Use ManagedSource and NativeDestination spans for by-value marshalling since we're just marshalling back the contents, @@ -1186,7 +1210,9 @@ private StatementSyntax GenerateByValueUnmarshalStatement(TypePositionInfo info, managedValuesDeclaration, nativeValuesDeclaration, GenerateContentsMarshallingStatement(info, context, - IdentifierName(numElementsIdentifier))); + IdentifierName(numElementsIdentifier), + StubCodeContext.Stage.UnmarshalCapture, + StubCodeContext.Stage.Unmarshal)); } public IEnumerable GenerateUnmarshalStatements(TypePositionInfo info, StubCodeContext context) @@ -1206,7 +1232,9 @@ public IEnumerable GenerateUnmarshalStatements(TypePositionInfo GeneratedManagedValuesDestinationDeclaration(info, context, numElementsIdentifier), GenerateNativeValuesSourceDeclaration(info, context, numElementsIdentifier), GenerateContentsMarshallingStatement(info, context, - IdentifierName(numElementsIdentifier))); + IdentifierName(numElementsIdentifier), + StubCodeContext.Stage.UnmarshalCapture, + StubCodeContext.Stage.Unmarshal)); } foreach (StatementSyntax statement in _innerMarshaller.GenerateUnmarshalStatements(info, context)) diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/StubCodeContext.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/StubCodeContext.cs index 84d17e8c88ed91..9822d1cf70ba9a 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/StubCodeContext.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/StubCodeContext.cs @@ -33,6 +33,11 @@ public enum Stage /// Pin, + /// + /// Convert managed data to native data, assuming that any values pinned in the stage are pinned. + /// + PinnedMarshal, + /// /// Call the generated P/Invoke /// @@ -42,20 +47,26 @@ public enum Stage /// Invoke, + /// + /// Capture native values to ensure that we do not leak if an exception is thrown during unmarshalling + /// + UnmarshalCapture, + /// /// Convert native data to managed data /// Unmarshal, /// - /// Perform any cleanup required + /// Notify a marshaller object that the Invoke stage and all stages preceeding the Invoke stage + /// successfully completed without any exceptions. /// - Cleanup, + NotifyForSuccessfulInvoke, /// - /// Keep alive any managed objects that need to stay alive across the call. + /// Perform any cleanup required /// - KeepAlive, + Cleanup, /// /// Convert native data to managed data even in the case of an exception during diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/SyntaxExtensions.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/SyntaxExtensions.cs index 02a0d80743d59e..2457328d2e6c5b 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/SyntaxExtensions.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/SyntaxExtensions.cs @@ -52,7 +52,7 @@ public static StatementSyntax NestFixedStatements(this ImmutableArray= 0; i--) { @@ -60,6 +60,15 @@ public static StatementSyntax NestFixedStatements(this ImmutableArray Date: Thu, 16 Jun 2022 21:06:52 +0300 Subject: [PATCH 160/337] Simplify `Environment.IsWindows8OrAbove`. (#70818) * Simplify Environment.IsWindows8OrAbove. Since .NET 5, the regular Windows version detecton code always returns the correct version. * Remove two unused interop files. --- .../Kernel32/Interop.VerSetConditionMask.cs | 13 --------- .../Kernel32/Interop.VerifyVersionExW.cs | 20 -------------- .../System.Private.CoreLib.Shared.projitems | 6 ----- .../src/System/Environment.Win32.cs | 27 ++----------------- 4 files changed, 2 insertions(+), 64 deletions(-) delete mode 100644 src/libraries/Common/src/Interop/Windows/Kernel32/Interop.VerSetConditionMask.cs delete mode 100644 src/libraries/Common/src/Interop/Windows/Kernel32/Interop.VerifyVersionExW.cs diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.VerSetConditionMask.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.VerSetConditionMask.cs deleted file mode 100644 index 791124d11839fe..00000000000000 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.VerSetConditionMask.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.InteropServices; - -internal static partial class Interop -{ - internal static partial class Kernel32 - { - [LibraryImport(Libraries.Kernel32)] - internal static partial ulong VerSetConditionMask(ulong ConditionMask, uint TypeMask, byte Condition); - } -} diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.VerifyVersionExW.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.VerifyVersionExW.cs deleted file mode 100644 index aa4536511e1b46..00000000000000 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.VerifyVersionExW.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Runtime.InteropServices; - -internal static partial class Interop -{ - internal static partial class Kernel32 - { - internal const byte VER_GREATER_EQUAL = 0x3; - internal const uint VER_MAJORVERSION = 0x0000002; - internal const uint VER_MINORVERSION = 0x0000001; - internal const uint VER_SERVICEPACKMAJOR = 0x0000020; - internal const uint VER_SERVICEPACKMINOR = 0x0000010; - - [LibraryImport(Libraries.Kernel32)] - [return: MarshalAs(UnmanagedType.Bool)] - internal static partial bool VerifyVersionInfoW(ref OSVERSIONINFOEX lpVersionInfo, uint dwTypeMask, ulong dwlConditionMask); - } -} diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index ebdb96165b0116..d0040d54427692 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -1756,12 +1756,6 @@ Common\Interop\Windows\Kernel32\Interop.TzSpecificLocalTimeToSystemTime.cs - - Common\Interop\Windows\Kernel32\Interop.VerifyVersionExW.cs - - - Common\Interop\Windows\Kernel32\Interop.VerSetConditionMask.cs - Common\Interop\Windows\Kernel32\Interop.VirtualAlloc_Ptr.cs diff --git a/src/libraries/System.Private.CoreLib/src/System/Environment.Win32.cs b/src/libraries/System.Private.CoreLib/src/System/Environment.Win32.cs index 07af75661e9c5a..032f4b16ad3b6d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Environment.Win32.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Environment.Win32.cs @@ -4,7 +4,6 @@ using System.Collections; using System.Diagnostics; using System.IO; -using System.Reflection; using System.Runtime.InteropServices; using System.Text; using Internal.Win32; @@ -383,30 +382,8 @@ private static string GetKnownFolderPath(string folderGuid, SpecialFolderOption private static class WindowsVersion { // Cache the value in static readonly that can be optimized out by the JIT - internal static readonly bool IsWindows8OrAbove = GetIsWindows8OrAbove(); - - private static bool GetIsWindows8OrAbove() - { - ulong conditionMask = Interop.Kernel32.VerSetConditionMask(0, Interop.Kernel32.VER_MAJORVERSION, Interop.Kernel32.VER_GREATER_EQUAL); - conditionMask = Interop.Kernel32.VerSetConditionMask(conditionMask, Interop.Kernel32.VER_MINORVERSION, Interop.Kernel32.VER_GREATER_EQUAL); - conditionMask = Interop.Kernel32.VerSetConditionMask(conditionMask, Interop.Kernel32.VER_SERVICEPACKMAJOR, Interop.Kernel32.VER_GREATER_EQUAL); - conditionMask = Interop.Kernel32.VerSetConditionMask(conditionMask, Interop.Kernel32.VER_SERVICEPACKMINOR, Interop.Kernel32.VER_GREATER_EQUAL); - - // Windows 8 version is 6.2 - Interop.Kernel32.OSVERSIONINFOEX version = default; - unsafe - { - version.dwOSVersionInfoSize = sizeof(Interop.Kernel32.OSVERSIONINFOEX); - } - version.dwMajorVersion = 6; - version.dwMinorVersion = 2; - version.wServicePackMajor = 0; - version.wServicePackMinor = 0; - - return Interop.Kernel32.VerifyVersionInfoW(ref version, - Interop.Kernel32.VER_MAJORVERSION | Interop.Kernel32.VER_MINORVERSION | Interop.Kernel32.VER_SERVICEPACKMAJOR | Interop.Kernel32.VER_SERVICEPACKMINOR, - conditionMask); - } + // Windows 8 version is 6.2 + internal static readonly bool IsWindows8OrAbove = OperatingSystem.IsWindowsVersionAtLeast(6, 2); } } } From 3874c65fa0b090100dbb58112261db7af424177c Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Thu, 16 Jun 2022 11:07:56 -0700 Subject: [PATCH 161/337] Delete redundant aliases for primitive types (#70805) --- src/coreclr/vm/debugdebugger.cpp | 26 +++++++++++++------------- src/coreclr/vm/interoputil.cpp | 2 +- src/coreclr/vm/invokeutil.cpp | 20 ++++++++++---------- src/coreclr/vm/methodtable.cpp | 2 +- src/coreclr/vm/object.h | 30 +++++++++++++++--------------- src/coreclr/vm/olevariant.cpp | 4 ++-- src/coreclr/vm/util.hpp | 16 ---------------- 7 files changed, 42 insertions(+), 58 deletions(-) diff --git a/src/coreclr/vm/debugdebugger.cpp b/src/coreclr/vm/debugdebugger.cpp index 46d5b81631c714..bae0051baef635 100644 --- a/src/coreclr/vm/debugdebugger.cpp +++ b/src/coreclr/vm/debugdebugger.cpp @@ -474,11 +474,11 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal, pElem[iNumValidFrames] = (size_t)pFunc; // Native offset - I4 *pI4 = (I4 *)((I4ARRAYREF)pStackFrameHelper->rgiOffset)->GetDirectPointerToNonObjectElements(); + CLR_I4 *pI4 = (CLR_I4 *)((I4ARRAYREF)pStackFrameHelper->rgiOffset)->GetDirectPointerToNonObjectElements(); pI4[iNumValidFrames] = data.pElements[i].dwOffset; // IL offset - I4 *pILI4 = (I4 *)((I4ARRAYREF)pStackFrameHelper->rgiILOffset)->GetDirectPointerToNonObjectElements(); + CLR_I4 *pILI4 = (CLR_I4 *)((I4ARRAYREF)pStackFrameHelper->rgiILOffset)->GetDirectPointerToNonObjectElements(); pILI4[iNumValidFrames] = data.pElements[i].dwILOffset; // Assembly @@ -488,9 +488,9 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal, if (data.fDoWeHaveAnyFramesFromForeignStackTrace) { // Set the BOOL indicating if the frame represents the last frame from a foreign exception stack trace. - U1 *pIsLastFrameFromForeignExceptionStackTraceU1 = (U1 *)((BOOLARRAYREF)pStackFrameHelper->rgiLastFrameFromForeignExceptionStackTrace) + CLR_U1 *pIsLastFrameFromForeignExceptionStackTraceU1 = (CLR_U1 *)((BOOLARRAYREF)pStackFrameHelper->rgiLastFrameFromForeignExceptionStackTrace) ->GetDirectPointerToNonObjectElements(); - pIsLastFrameFromForeignExceptionStackTraceU1 [iNumValidFrames] = (U1)(data.pElements[i].flags & STEF_LAST_FRAME_FROM_FOREIGN_STACK_TRACE); + pIsLastFrameFromForeignExceptionStackTraceU1 [iNumValidFrames] = (CLR_U1)(data.pElements[i].flags & STEF_LAST_FRAME_FROM_FOREIGN_STACK_TRACE); } MethodDesc *pMethod = data.pElements[i].pFunc; @@ -727,10 +727,10 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal, if (fFileInfoSet) { // Set the line and column numbers - I4 *pI4Line = (I4 *)((I4ARRAYREF)pStackFrameHelper->rgiLineNumber)->GetDirectPointerToNonObjectElements(); + CLR_I4 *pI4Line = (CLR_I4 *)((I4ARRAYREF)pStackFrameHelper->rgiLineNumber)->GetDirectPointerToNonObjectElements(); pI4Line[iNumValidFrames] = sourceLine; - I4 *pI4Column = (I4 *)((I4ARRAYREF)pStackFrameHelper->rgiColumnNumber)->GetDirectPointerToNonObjectElements(); + CLR_I4 *pI4Column = (CLR_I4 *)((I4ARRAYREF)pStackFrameHelper->rgiColumnNumber)->GetDirectPointerToNonObjectElements(); pI4Column[iNumValidFrames] = sourceColumn; // Set the file name @@ -745,7 +745,7 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal, #endif // FEATURE_ISYM_READER { // Save MethodToken for the function - I4 *pMethodToken = (I4 *)((I4ARRAYREF)pStackFrameHelper->rgiMethodToken)->GetDirectPointerToNonObjectElements(); + CLR_I4 *pMethodToken = (CLR_I4 *)((I4ARRAYREF)pStackFrameHelper->rgiMethodToken)->GetDirectPointerToNonObjectElements(); pMethodToken[iNumValidFrames] = pMethod->GetMemberDef(); PEAssembly *pPEAssembly = pModule->GetPEAssembly(); @@ -758,15 +758,15 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal, PTR_CVOID *pLoadedPeAddress = (PTR_CVOID *)pStackFrameHelper->rgLoadedPeAddress->GetDataPtr(); pLoadedPeAddress[iNumValidFrames] = peAddress; - I4 *pLoadedPeSize = (I4 *)((I4ARRAYREF)pStackFrameHelper->rgiLoadedPeSize)->GetDirectPointerToNonObjectElements(); - pLoadedPeSize[iNumValidFrames] = (I4)peSize; + CLR_I4 *pLoadedPeSize = (CLR_I4 *)((I4ARRAYREF)pStackFrameHelper->rgiLoadedPeSize)->GetDirectPointerToNonObjectElements(); + pLoadedPeSize[iNumValidFrames] = (CLR_I4)peSize; // Set flag indicating PE file in memory has the on disk layout if (!pPEAssembly->IsDynamic()) { // This flag is only available for non-dynamic assemblies. - U1 *pIsFileLayout = (U1 *)((BOOLARRAYREF)pStackFrameHelper->rgiIsFileLayout)->GetDirectPointerToNonObjectElements(); - pIsFileLayout[iNumValidFrames] = (U1) pPEAssembly->GetLoadedLayout()->IsFlat(); + CLR_U1 *pIsFileLayout = (CLR_U1 *)((BOOLARRAYREF)pStackFrameHelper->rgiIsFileLayout)->GetDirectPointerToNonObjectElements(); + pIsFileLayout[iNumValidFrames] = (CLR_U1) pPEAssembly->GetLoadedLayout()->IsFlat(); } // If there is a in memory symbol stream @@ -779,8 +779,8 @@ FCIMPL4(void, DebugStackTrace::GetStackFramesInternal, PTR_VOID *pInMemoryPdbAddress = (PTR_VOID *)pStackFrameHelper->rgInMemoryPdbAddress->GetDataPtr(); pInMemoryPdbAddress[iNumValidFrames] = range.StartAddress(); - I4 *pInMemoryPdbSize = (I4 *)((I4ARRAYREF)pStackFrameHelper->rgiInMemoryPdbSize)->GetDirectPointerToNonObjectElements(); - pInMemoryPdbSize[iNumValidFrames] = (I4)range.Size(); + CLR_I4 *pInMemoryPdbSize = (CLR_I4 *)((I4ARRAYREF)pStackFrameHelper->rgiInMemoryPdbSize)->GetDirectPointerToNonObjectElements(); + pInMemoryPdbSize[iNumValidFrames] = (CLR_I4)range.Size(); } else { diff --git a/src/coreclr/vm/interoputil.cpp b/src/coreclr/vm/interoputil.cpp index dd5443c0c75b85..a37639bb4526e6 100644 --- a/src/coreclr/vm/interoputil.cpp +++ b/src/coreclr/vm/interoputil.cpp @@ -1018,7 +1018,7 @@ namespace if (FAILED(cap.ValidateProlog())) return COR_E_BADIMAGEFORMAT; - U1 u1; + UINT8 u1; if (FAILED(cap.GetU1(&u1))) return COR_E_BADIMAGEFORMAT; diff --git a/src/coreclr/vm/invokeutil.cpp b/src/coreclr/vm/invokeutil.cpp index 944490f280b721..4b69f5895031b2 100644 --- a/src/coreclr/vm/invokeutil.cpp +++ b/src/coreclr/vm/invokeutil.cpp @@ -338,10 +338,10 @@ void InvokeUtil::CreatePrimitiveValue(CorElementType dstType, *pDst = data; break; case ELEMENT_TYPE_R4: - *pDst = (I8)(*(R4*)pSrc); + *pDst = (CLR_I8)(*(CLR_R4*)pSrc); break; case ELEMENT_TYPE_R8: - *pDst = (I8)(*(R8*)pSrc); + *pDst = (CLR_I8)(*(CLR_R8*)pSrc); break; default: _ASSERTE(!"Unknown conversion"); @@ -352,35 +352,35 @@ void InvokeUtil::CreatePrimitiveValue(CorElementType dstType, case ELEMENT_TYPE_R4: case ELEMENT_TYPE_R8: { - R8 r8 = 0; + CLR_R8 r8 = 0; switch (srcType) { case ELEMENT_TYPE_BOOLEAN: case ELEMENT_TYPE_I1: case ELEMENT_TYPE_I2: case ELEMENT_TYPE_I4: IN_TARGET_32BIT(case ELEMENT_TYPE_I:) - r8 = (R8)((INT32)data); + r8 = (CLR_R8)((INT32)data); break; case ELEMENT_TYPE_U1: case ELEMENT_TYPE_CHAR: case ELEMENT_TYPE_U2: case ELEMENT_TYPE_U4: IN_TARGET_32BIT(case ELEMENT_TYPE_U:) - r8 = (R8)((UINT32)data); + r8 = (CLR_R8)((UINT32)data); break; case ELEMENT_TYPE_U8: IN_TARGET_64BIT(case ELEMENT_TYPE_U:) - r8 = (R8)((UINT64)data); + r8 = (CLR_R8)((UINT64)data); break; case ELEMENT_TYPE_I8: IN_TARGET_64BIT(case ELEMENT_TYPE_I:) - r8 = (R8)((INT64)data); + r8 = (CLR_R8)((INT64)data); break; case ELEMENT_TYPE_R4: - r8 = *(R4*)pSrc; + r8 = *(CLR_R4*)pSrc; break; case ELEMENT_TYPE_R8: - r8 = *(R8*)pSrc; + r8 = *(CLR_R8*)pSrc; break; default: _ASSERTE(!"Unknown R4 or R8 conversion"); @@ -389,7 +389,7 @@ void InvokeUtil::CreatePrimitiveValue(CorElementType dstType, } if (dstType == ELEMENT_TYPE_R4) { - R4 r4 = (R4)r8; + CLR_R4 r4 = (CLR_R4)r8; *pDst = (UINT32&)r4; } else { diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index b8a234966e341f..fdbdfed16b80f6 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -6454,7 +6454,7 @@ void MethodTable::SetCl(mdTypeDef token) } else { - _ASSERTE(FitsIn(rid)); + _ASSERTE(FitsIn(rid)); m_wToken = (WORD)rid; } diff --git a/src/coreclr/vm/object.h b/src/coreclr/vm/object.h index 93306dfd89e173..0c4535209ce9a2 100644 --- a/src/coreclr/vm/object.h +++ b/src/coreclr/vm/object.h @@ -785,18 +785,18 @@ class TypedByRef typedef DPTR(TypedByRef) PTR_TypedByRef; -typedef Array I1Array; -typedef Array I2Array; -typedef Array I4Array; -typedef Array I8Array; -typedef Array R4Array; -typedef Array R8Array; -typedef Array U1Array; -typedef Array BOOLArray; -typedef Array U2Array; -typedef Array CHARArray; -typedef Array U4Array; -typedef Array U8Array; +typedef Array I1Array; +typedef Array I2Array; +typedef Array I4Array; +typedef Array I8Array; +typedef Array R4Array; +typedef Array R8Array; +typedef Array U1Array; +typedef Array BOOLArray; +typedef Array U2Array; +typedef Array CHARArray; +typedef Array U4Array; +typedef Array U8Array; typedef Array UPTRArray; typedef PtrArray PTRArray; @@ -2184,7 +2184,7 @@ class StackTraceArray return dac_cast(GetRaw() + sizeof(ArrayHeader)); } - I1 const * GetRaw() const + CLR_I1 const * GetRaw() const { WRAPPER_NO_CONTRACT; assert(!!m_array); @@ -2192,13 +2192,13 @@ class StackTraceArray return const_cast(m_array)->GetDirectPointerToNonObjectElements(); } - PTR_I1 GetRaw() + PTR_INT8 GetRaw() { WRAPPER_NO_CONTRACT; SUPPORTS_DAC; assert(!!m_array); - return dac_cast(m_array->GetDirectPointerToNonObjectElements()); + return dac_cast(m_array->GetDirectPointerToNonObjectElements()); } ArrayHeader const * GetHeader() const diff --git a/src/coreclr/vm/olevariant.cpp b/src/coreclr/vm/olevariant.cpp index 6f90f9a3ff8a2c..223c6901c57ee5 100644 --- a/src/coreclr/vm/olevariant.cpp +++ b/src/coreclr/vm/olevariant.cpp @@ -2812,7 +2812,7 @@ void OleVariant::MarshalOleVariantForObject(OBJECTREF * const & pObj, VARIANT *p } else if (pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_BOOLEAN)) { - V_BOOL(pOle) = *(U1*)( (*pObj)->GetData() ) ? VARIANT_TRUE : VARIANT_FALSE; + V_BOOL(pOle) = *(CLR_BOOL*)( (*pObj)->GetData() ) ? VARIANT_TRUE : VARIANT_FALSE; V_VT(pOle) = VT_BOOL; } else if (pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_I)) @@ -2985,7 +2985,7 @@ HRESULT OleVariant::MarshalCommonOleRefVariantForObject(OBJECTREF *pObj, VARIANT // deallocation of old value optimized away since there's nothing to // deallocate for this vartype. - *(V_BOOLREF(pOle)) = ( *(U1*)( (*pObj)->GetData() ) ) ? VARIANT_TRUE : VARIANT_FALSE; + *(V_BOOLREF(pOle)) = ( *(CLR_BOOL*)( (*pObj)->GetData() ) ) ? VARIANT_TRUE : VARIANT_FALSE; } else if ( (V_VT(pOle) == (VT_BYREF | VT_INT) || V_VT(pOle) == (VT_BYREF | VT_UINT)) && (pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_I4) || pMT == CoreLibBinder::GetElementType(ELEMENT_TYPE_U4)) ) { diff --git a/src/coreclr/vm/util.hpp b/src/coreclr/vm/util.hpp index 47058659dfe54a..f5dc51daf7ee9e 100644 --- a/src/coreclr/vm/util.hpp +++ b/src/coreclr/vm/util.hpp @@ -25,22 +25,6 @@ #define MAX_CACHE_LINE_SIZE 64 #endif -//======================================================================== -// More convenient names for integer types of a guaranteed size. -//======================================================================== - -typedef __int8 I1; -typedef ArrayDPTR(I1) PTR_I1; -typedef unsigned __int8 U1; -typedef __int16 I2; -typedef unsigned __int16 U2; -typedef __int32 I4; -typedef unsigned __int32 U4; -typedef __int64 I8; -typedef unsigned __int64 U8; -typedef float R4; -typedef double R8; - #ifndef TARGET_UNIX // Copied from malloc.h: don't want to bring in the whole header file. void * __cdecl _alloca(size_t); From 9a80f1d38857d779c211e6ac7e51cceb4def2dfc Mon Sep 17 00:00:00 2001 From: Radek Zikmund <32671551+rzikm@users.noreply.github.com> Date: Thu, 16 Jun 2022 20:22:50 +0200 Subject: [PATCH 162/337] Add limited support for LocalCertificateSelectionCallback for QUIC (#70716) * Inline state transition helpers Fixes #55437 * Add high level comments for HandleEventReceive and ReadAsync * [QUIC] Call `LocalCertificateSelectionCallback` to get client certificate * Code review feedback --- .../Interop/SafeMsQuicConfigurationHandle.cs | 37 +++++++++++++------ .../tests/FunctionalTests/MsQuicTests.cs | 19 +++++++--- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs index 7fd84cc8ce3a8e..1ace58df055d6b 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs @@ -26,27 +26,40 @@ public static SafeMsQuicConfigurationHandle Create(QuicClientConnectionOptions o if (options.ClientAuthenticationOptions != null) { + SslClientAuthenticationOptions clientAuthenticationOptions = options.ClientAuthenticationOptions; + #pragma warning disable SYSLIB0040 // NoEncryption and AllowNoEncryption are obsolete - if (options.ClientAuthenticationOptions.EncryptionPolicy == EncryptionPolicy.NoEncryption) + if (clientAuthenticationOptions.EncryptionPolicy == EncryptionPolicy.NoEncryption) { - throw new PlatformNotSupportedException(SR.Format(SR.net_quic_ssl_option, nameof(options.ClientAuthenticationOptions.EncryptionPolicy))); + throw new PlatformNotSupportedException(SR.Format(SR.net_quic_ssl_option, nameof(clientAuthenticationOptions.EncryptionPolicy))); } #pragma warning restore SYSLIB0040 - if (options.ClientAuthenticationOptions.ClientCertificates != null) + if (clientAuthenticationOptions.LocalCertificateSelectionCallback != null) + { + X509Certificate? cert = clientAuthenticationOptions.LocalCertificateSelectionCallback( + options, + clientAuthenticationOptions.TargetHost ?? string.Empty, + clientAuthenticationOptions.ClientCertificates ?? new X509CertificateCollection(), + null, + Array.Empty()); + + if (cert is X509Certificate2 cert2 && cert2.Handle != IntPtr.Zero && cert2.HasPrivateKey) + { + certificate = cert; + } + } + else if (clientAuthenticationOptions.ClientCertificates != null) { - foreach (var cert in options.ClientAuthenticationOptions.ClientCertificates) + foreach (X509Certificate cert in clientAuthenticationOptions.ClientCertificates) { - try + + if (cert is X509Certificate2 cert2 && cert2.Handle != IntPtr.Zero && cert2.HasPrivateKey) { - if (((X509Certificate2)cert).HasPrivateKey) - { - // Pick first certificate with private key. - certificate = cert; - break; - } + // Pick first certificate with private key. + certificate = cert; + break; } - catch { } } } } diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs index 65e78735e1282a..0a273445bec9f3 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs @@ -190,7 +190,7 @@ public async Task CertificateCallbackThrowPropagates() } [Fact] - public async Task ConnectWithCertificateCallback() + public async Task ConnectWithServerCertificateCallback() { X509Certificate2 c1 = System.Net.Test.Common.Configuration.Certificates.GetServerCertificate(); X509Certificate2 c2 = System.Net.Test.Common.Configuration.Certificates.GetClientCertificate(); // This 'wrong' certificate but should be sufficient @@ -340,10 +340,12 @@ public async Task ConnectWithCertificateForLoopbackIP_IndicatesExpectedError(str } [ConditionalTheory] - [InlineData(true)] - [InlineData(false)] + [InlineData(true, true)] + [InlineData(false, true)] + [InlineData(true, false)] + [InlineData(false, false)] [ActiveIssue("https://github.com/dotnet/runtime/issues/64944", TestPlatforms.Windows)] - public async Task ConnectWithClientCertificate(bool sendCertificate) + public async Task ConnectWithClientCertificate(bool sendCertificate, bool useClientSelectionCallback) { if (PlatformDetection.IsWindows10Version20348OrLower) { @@ -371,7 +373,14 @@ public async Task ConnectWithClientCertificate(bool sendCertificate) using QuicListener listener = new QuicListener(QuicImplementationProviders.MsQuic, listenerOptions); QuicClientConnectionOptions clientOptions = CreateQuicClientOptions(); - if (sendCertificate) + if (useClientSelectionCallback) + { + clientOptions.ClientAuthenticationOptions.LocalCertificateSelectionCallback = delegate + { + return sendCertificate ? ClientCertificate : null; + }; + } + else if (sendCertificate) { clientOptions.ClientAuthenticationOptions.ClientCertificates = new X509CertificateCollection() { ClientCertificate }; } From 401722be72ce2e6230ebb1a5bf5d610b299fb75f Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Thu, 16 Jun 2022 20:34:25 +0200 Subject: [PATCH 163/337] JIT: Optimize range checks for X >> CNS and for short/byte indices (#67141) Co-authored-by: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> --- src/coreclr/jit/rangecheck.cpp | 81 ++++++++++++++------- src/coreclr/jit/rangecheck.h | 127 +++++++++++++++++++++++++-------- 2 files changed, 151 insertions(+), 57 deletions(-) diff --git a/src/coreclr/jit/rangecheck.cpp b/src/coreclr/jit/rangecheck.cpp index 970e799d9b509b..6b1575ab5f928f 100644 --- a/src/coreclr/jit/rangecheck.cpp +++ b/src/coreclr/jit/rangecheck.cpp @@ -947,14 +947,14 @@ Range RangeCheck::ComputeRangeForBinOp(BasicBlock* block, GenTreeOp* binop, bool return range; } // Generalized range computation not implemented for these operators - else if (binop->OperIs(GT_AND, GT_UMOD, GT_RSH)) + else if (binop->OperIs(GT_AND, GT_UMOD)) { return Range(Limit::keUnknown); } } // other operators are expected to be handled above. - assert(binop->OperIs(GT_ADD, GT_MUL, GT_LSH)); + assert(binop->OperIs(GT_ADD, GT_MUL, GT_LSH, GT_RSH)); Range* op1RangeCached = nullptr; Range op1Range = Limit(Limit::keUndef); @@ -1024,9 +1024,43 @@ Range RangeCheck::ComputeRangeForBinOp(BasicBlock* block, GenTreeOp* binop, bool convertedOp2Range.ToString(m_pCompiler->getAllocatorDebugOnly()), r.ToString(m_pCompiler->getAllocatorDebugOnly())); } + else if (binop->OperIs(GT_RSH)) + { + r = RangeOps::ShiftRight(op1Range, op2Range); + JITDUMP("Right shift range: %s >> %s = %s\n", op1Range.ToString(m_pCompiler->getAllocatorDebugOnly()), + op2Range.ToString(m_pCompiler->getAllocatorDebugOnly()), + r.ToString(m_pCompiler->getAllocatorDebugOnly())); + } return r; } +//------------------------------------------------------------------------ +// GetRangeFromType: Compute the range from the given type +// +// Arguments: +// type - input type +// +// Return value: +// range that represents the values given type allows +// +Range RangeCheck::GetRangeFromType(var_types type) +{ + switch (type) + { + case TYP_BOOL: + case TYP_UBYTE: + return Range(Limit(Limit::keConstant, 0), Limit(Limit::keConstant, BYTE_MAX)); + case TYP_BYTE: + return Range(Limit(Limit::keConstant, INT8_MIN), Limit(Limit::keConstant, INT8_MAX)); + case TYP_USHORT: + return Range(Limit(Limit::keConstant, 0), Limit(Limit::keConstant, UINT16_MAX)); + case TYP_SHORT: + return Range(Limit(Limit::keConstant, INT16_MIN), Limit(Limit::keConstant, INT16_MAX)); + default: + return Range(Limit(Limit::keUnknown)); + } +} + // Compute the range for a local var definition. Range RangeCheck::ComputeRangeForLocalDef(BasicBlock* block, GenTreeLclVarCommon* lcl, @@ -1242,11 +1276,11 @@ bool RangeCheck::ComputeDoesOverflow(BasicBlock* block, GenTree* expr) { overflows = false; } - else if (expr->OperGet() == GT_IND) + else if (expr->OperIs(GT_IND)) { overflows = false; } - else if (expr->OperGet() == GT_COMMA) + else if (expr->OperIs(GT_COMMA)) { overflows = ComputeDoesOverflow(block, expr->gtEffectiveVal()); } @@ -1256,7 +1290,7 @@ bool RangeCheck::ComputeDoesOverflow(BasicBlock* block, GenTree* expr) overflows = DoesVarDefOverflow(expr->AsLclVarCommon()); } // Check if add overflows. - else if (expr->OperGet() == GT_ADD || expr->OperGet() == GT_MUL) + else if (expr->OperIs(GT_ADD, GT_MUL)) { overflows = DoesBinOpOverflow(block, expr->AsOp()); } @@ -1267,10 +1301,14 @@ bool RangeCheck::ComputeDoesOverflow(BasicBlock* block, GenTree* expr) overflows = false; } // Walk through phi arguments to check if phi arguments involve arithmetic that overflows. - else if (expr->OperGet() == GT_PHI) + else if (expr->OperIs(GT_PHI)) { overflows = DoesPhiOverflow(block, expr); } + else if (expr->OperIs(GT_CAST)) + { + overflows = ComputeDoesOverflow(block, expr->gtGetOp1()); + } GetOverflowMap()->Set(expr, overflows, OverflowMap::Overwrite); m_pSearchPath->Remove(expr); JITDUMP("[%06d] %s\n", Compiler::dspTreeID(expr), ((overflows) ? "overflows" : "does not overflow")); @@ -1357,7 +1395,7 @@ Range RangeCheck::ComputeRange(BasicBlock* block, GenTree* expr, bool monIncreas range = ComputeRangeForBinOp(block, expr->AsOp(), monIncreasing DEBUGARG(indent + 1)); } // If phi, then compute the range for arguments, calling the result "dependent" when looping begins. - else if (expr->OperGet() == GT_PHI) + else if (expr->OperIs(GT_PHI)) { for (GenTreePhi::Use& use : expr->AsPhi()->Uses()) { @@ -1382,31 +1420,20 @@ Range RangeCheck::ComputeRange(BasicBlock* block, GenTree* expr, bool monIncreas } else if (varTypeIsSmallInt(expr->TypeGet())) { - switch (expr->TypeGet()) - { - case TYP_UBYTE: - range = Range(Limit(Limit::keConstant, 0), Limit(Limit::keConstant, 255)); - break; - case TYP_BYTE: - range = Range(Limit(Limit::keConstant, -128), Limit(Limit::keConstant, 127)); - break; - case TYP_USHORT: - range = Range(Limit(Limit::keConstant, 0), Limit(Limit::keConstant, 65535)); - break; - case TYP_SHORT: - range = Range(Limit(Limit::keConstant, -32768), Limit(Limit::keConstant, 32767)); - break; - default: - range = Range(Limit(Limit::keUnknown)); - break; - } - + range = GetRangeFromType(expr->TypeGet()); JITDUMP("%s\n", range.ToString(m_pCompiler->getAllocatorDebugOnly())); } - else if (expr->OperGet() == GT_COMMA) + else if (expr->OperIs(GT_COMMA)) { range = GetRange(block, expr->gtEffectiveVal(), monIncreasing DEBUGARG(indent + 1)); } + else if (expr->OperIs(GT_CAST)) + { + GenTreeCast* castTree = expr->AsCast(); + // TODO: consider computing range for CastOp and intersect it + // with this + range = GetRangeFromType(castTree->CastToType()); + } else { // The expression is not recognized, so the result is unknown. diff --git a/src/coreclr/jit/rangecheck.h b/src/coreclr/jit/rangecheck.h index 49c5a2950a939d..db1c25a09eda54 100644 --- a/src/coreclr/jit/rangecheck.h +++ b/src/coreclr/jit/rangecheck.h @@ -101,27 +101,27 @@ struct Limit assert(type == keBinOpArray); } - bool IsUndef() + bool IsUndef() const { return type == keUndef; } - bool IsDependent() + bool IsDependent() const { return type == keDependent; } - bool IsUnknown() + bool IsUnknown() const { return type == keUnknown; } - bool IsConstant() + bool IsConstant() const { return type == keConstant; } - int GetConstant() + int GetConstant() const { return cns; } - bool IsBinOpArray() + bool IsBinOpArray() const { return type == keBinOpArray; } @@ -170,6 +170,27 @@ struct Limit return false; } + bool ShiftRightConstant(int i) + { + switch (type) + { + case keDependent: + return true; + case keBinOpArray: + case keConstant: + // >> never overflows + assert((unsigned)i <= 31); + cns >>= i; + return true; + case keUndef: + case keUnknown: + // For these values of 'type', conservatively return false + break; + } + + return false; + } + bool Equals(Limit& l) { switch (type) @@ -257,34 +278,40 @@ struct Range // Helpers for operations performed on ranges struct RangeOps { - // Given a constant limit in "l1", add it to l2 and mutate "l2". - static Limit AddConstantLimit(Limit& l1, Limit& l2) + // Perform 'value' + 'cns' + static Limit AddConstantLimit(const Limit& value, const Limit& cns) { - assert(l1.IsConstant()); - Limit l = l2; - if (l.AddConstant(l1.GetConstant())) + assert(cns.IsConstant()); + Limit l = value; + if (l.AddConstant(cns.GetConstant())) { return l; } - else - { - return Limit(Limit::keUnknown); - } + return Limit(Limit::keUnknown); } - // Given a constant limit in "l1", multiply it to l2 and mutate "l2". - static Limit MultiplyConstantLimit(Limit& l1, Limit& l2) + // Perform 'value' * 'cns' + static Limit MultiplyConstantLimit(const Limit& value, const Limit& cns) { - assert(l1.IsConstant()); - Limit l = l2; - if (l.MultiplyConstant(l1.GetConstant())) + assert(cns.IsConstant()); + Limit l = value; + if (l.MultiplyConstant(cns.GetConstant())) { return l; } - else + return Limit(Limit::keUnknown); + } + + // Perform 'value' >> 'cns' + static Limit ShiftRightConstantLimit(const Limit& value, const Limit& cns) + { + assert(value.IsConstant()); + Limit result = value; + if (result.ShiftRightConstant(cns.GetConstant())) { - return Limit(Limit::keUnknown); + return result; } + return Limit(Limit::keUnknown); } // Given two ranges "r1" and "r2", perform an add operation on the @@ -311,20 +338,57 @@ struct RangeOps if (r1lo.IsConstant()) { - result.lLimit = AddConstantLimit(r1lo, r2lo); + result.lLimit = AddConstantLimit(r2lo, r1lo); } if (r2lo.IsConstant()) { - result.lLimit = AddConstantLimit(r2lo, r1lo); + result.lLimit = AddConstantLimit(r1lo, r2lo); } if (r1hi.IsConstant()) { - result.uLimit = AddConstantLimit(r1hi, r2hi); + result.uLimit = AddConstantLimit(r2hi, r1hi); } if (r2hi.IsConstant()) { - result.uLimit = AddConstantLimit(r2hi, r1hi); + result.uLimit = AddConstantLimit(r1hi, r2hi); + } + return result; + } + + static Range ShiftRight(Range& r1, Range& r2) + { + Limit& r1lo = r1.LowerLimit(); + Limit& r1hi = r1.UpperLimit(); + Limit& r2lo = r2.LowerLimit(); + Limit& r2hi = r2.UpperLimit(); + + Range result = Limit(Limit::keUnknown); + + // For now we only support r1 >> positive_cns (to simplify) + if (!r2lo.IsConstant() || !r2hi.IsConstant() || (r2lo.cns < 0) || (r2hi.cns < 0)) + { + return result; + } + + // Check lo ranges if they are dependent and not unknown. + if (r1lo.IsDependent()) + { + result.lLimit = Limit(Limit::keDependent); + } + else if (r1lo.IsConstant()) + { + result.lLimit = ShiftRightConstantLimit(r1lo, r2lo); + } + + if (r1hi.IsDependent()) + { + result.uLimit = Limit(Limit::keDependent); } + else if (r1hi.IsConstant()) + { + result.uLimit = ShiftRightConstantLimit(r1hi, r2hi); + } + return result; } @@ -352,19 +416,19 @@ struct RangeOps if (r1lo.IsConstant()) { - result.lLimit = MultiplyConstantLimit(r1lo, r2lo); + result.lLimit = MultiplyConstantLimit(r2lo, r1lo); } if (r2lo.IsConstant()) { - result.lLimit = MultiplyConstantLimit(r2lo, r1lo); + result.lLimit = MultiplyConstantLimit(r1lo, r2lo); } if (r1hi.IsConstant()) { - result.uLimit = MultiplyConstantLimit(r1hi, r2hi); + result.uLimit = MultiplyConstantLimit(r2hi, r1hi); } if (r2hi.IsConstant()) { - result.uLimit = MultiplyConstantLimit(r2hi, r1hi); + result.uLimit = MultiplyConstantLimit(r1hi, r2hi); } return result; } @@ -560,6 +624,9 @@ class RangeCheck // at phi definitions for the lower bound. Range GetRange(BasicBlock* block, GenTree* expr, bool monIncreasing DEBUGARG(int indent)); + // Compute the range from the given type + Range GetRangeFromType(var_types type); + // Given the local variable, first find the definition of the local and find the range of the rhs. // Helper for GetRange. Range ComputeRangeForLocalDef(BasicBlock* block, GenTreeLclVarCommon* lcl, bool monIncreasing DEBUGARG(int indent)); From 195a0a900b5c3b9ab5f19934b5544f5bb485b40a Mon Sep 17 00:00:00 2001 From: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> Date: Thu, 16 Jun 2022 22:10:08 +0300 Subject: [PATCH 164/337] Tighten checks in `areArgumentsContiguous` (#70829) * Tighten checks in "areArgumentsContiguous" * Add a test --- src/coreclr/jit/simd.cpp | 10 +++- .../JitBlue/Runtime_70824/Runtime_70824.cs | 48 +++++++++++++++++++ .../Runtime_70824/Runtime_70824.csproj | 10 ++++ 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_70824/Runtime_70824.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_70824/Runtime_70824.csproj diff --git a/src/coreclr/jit/simd.cpp b/src/coreclr/jit/simd.cpp index 92706856a0dce8..f55e8911e10408 100644 --- a/src/coreclr/jit/simd.cpp +++ b/src/coreclr/jit/simd.cpp @@ -1685,7 +1685,15 @@ bool Compiler::areArrayElementsContiguous(GenTree* op1, GenTree* op2) // bool Compiler::areArgumentsContiguous(GenTree* op1, GenTree* op2) { - if (op1->OperIs(GT_IND) && op2->OperIs(GT_IND)) + if (op1->TypeGet() != op2->TypeGet()) + { + return false; + } + + assert(!op1->TypeIs(TYP_STRUCT)); + + if (op1->OperIs(GT_IND) && op1->AsIndir()->Addr()->OperIs(GT_INDEX_ADDR) && op2->OperIs(GT_IND) && + op2->AsIndir()->Addr()->OperIs(GT_INDEX_ADDR)) { return areArrayElementsContiguous(op1, op2); } diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_70824/Runtime_70824.cs b/src/tests/JIT/Regression/JitBlue/Runtime_70824/Runtime_70824.cs new file mode 100644 index 00000000000000..e312cf524a8ed1 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_70824/Runtime_70824.cs @@ -0,0 +1,48 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Numerics; +using System.Runtime.CompilerServices; + +public unsafe class Runtime_70824 +{ + public static int Main() + { + long lng = 2; + float flt = 3; + Vector2 vtor = new Vector2(4, 5); + float[] arr = new float[] { 6, 7 }; + + if (ProblemWithTypes(&lng, &flt, vtor)) + { + return 101; + } + if (ProblemWithAddrs(&flt, arr, vtor)) + { + return 102; + } + + return 100; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool ProblemWithTypes(long* p1, float* pF, Vector2 vtor) + { + *pF = vtor.X; + *p1 = (long)*pF; + + return *p1 != (long)*pF; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool ProblemWithAddrs(float* pF, float[] arr, Vector2 vtor) + { + *pF = vtor.X; + arr[0] = vtor.Y; + + arr[1] = vtor.X; + *pF = vtor.Y; + + return arr[0] != vtor.Y || *pF != vtor.Y; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_70824/Runtime_70824.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_70824/Runtime_70824.csproj new file mode 100644 index 00000000000000..cf94135633b19a --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_70824/Runtime_70824.csproj @@ -0,0 +1,10 @@ + + + Exe + True + true + + + + + \ No newline at end of file From 52cced2d9d8e49c83570c8c077090813572c648d Mon Sep 17 00:00:00 2001 From: Will Smith Date: Thu, 16 Jun 2022 12:10:53 -0700 Subject: [PATCH 165/337] Narrow cast fix (#70518) * Added genActualTypeSize. Remove narrow cast if the actual type sizes are the same * Trying to fix build * Fixing build * Removed genActualTypeSize. Using genActualType instead * Added helper function * Comments * Moving back to morph * Removing part of the test * Added fgOptimizeCastOnAssignment * Fixing build * Removing extra bits * Removed fgIsSafeToRemoveIntToIntCastOnAssignment, inlining the implementation, adding extra logic when actual types are not the same --- src/coreclr/jit/compiler.h | 1 + src/coreclr/jit/morph.cpp | 94 +++++++++++++++---- .../JitBlue/Runtime_70333/Runtime_70333.cs | 28 ++++++ .../Runtime_70333/Runtime_70333.csproj | 9 ++ 4 files changed, 112 insertions(+), 20 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_70333/Runtime_70333.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_70333/Runtime_70333.csproj diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index a7ece7e80e9cd3..39356888b99731 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -5698,6 +5698,7 @@ class Compiler GenTree* fgMorphForRegisterFP(GenTree* tree); GenTree* fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac = nullptr); GenTree* fgOptimizeCast(GenTreeCast* cast); + GenTree* fgOptimizeCastOnAssignment(GenTreeOp* asg); GenTree* fgOptimizeEqualityComparisonWithConst(GenTreeOp* cmp); GenTree* fgOptimizeRelationalComparisonWithConst(GenTreeOp* cmp); #ifdef FEATURE_HW_INTRINSICS diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index ac07cb20ddc18e..9146eb5db1ba47 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -11248,7 +11248,6 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac) GenTree* temp; GenTree* lclVarTree; - GenTree* effectiveOp1; FieldSeqNode* fieldSeq = nullptr; switch (oper) @@ -11268,28 +11267,14 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac) lclVarTree->gtFlags |= GTF_VAR_DEF; } - effectiveOp1 = op1->gtEffectiveVal(); - - // If we are storing a small type, we might be able to omit a cast. - if ((effectiveOp1->OperIs(GT_IND) || - (effectiveOp1->OperIs(GT_LCL_VAR) && - lvaGetDesc(effectiveOp1->AsLclVarCommon()->GetLclNum())->lvNormalizeOnLoad())) && - varTypeIsSmall(effectiveOp1)) + if (op2->OperIs(GT_CAST)) { - if (!gtIsActiveCSE_Candidate(op2) && op2->OperIs(GT_CAST) && - varTypeIsIntegral(op2->AsCast()->CastOp()) && !op2->gtOverflow()) - { - var_types castType = op2->CastToType(); + tree = fgOptimizeCastOnAssignment(tree->AsOp()); - // If we are performing a narrowing cast and - // castType is larger or the same as op1's type - // then we can discard the cast. + assert(tree->OperIs(GT_ASG)); - if (varTypeIsSmall(castType) && (genTypeSize(castType) >= genTypeSize(effectiveOp1))) - { - tree->AsOp()->gtOp2 = op2 = op2->AsCast()->CastOp(); - } - } + op1 = tree->gtGetOp1(); + op2 = tree->gtGetOp2(); } fgAssignSetVarDef(tree); @@ -12256,6 +12241,75 @@ GenTree* Compiler::fgOptimizeCast(GenTreeCast* cast) return cast; } +//------------------------------------------------------------------------ +// fgOptimizeCastOnAssignment: Optimizes the supplied GT_ASG tree with a GT_CAST node. +// +// Arguments: +// tree - the cast tree to optimize +// +// Return Value: +// The optimized tree (must be GT_ASG). +// +GenTree* Compiler::fgOptimizeCastOnAssignment(GenTreeOp* asg) +{ + assert(asg->OperIs(GT_ASG)); + + GenTree* const op1 = asg->gtGetOp1(); + GenTree* const op2 = asg->gtGetOp2(); + + assert(op2->OperIs(GT_CAST)); + + GenTree* const effectiveOp1 = op1->gtEffectiveVal(); + + if (!effectiveOp1->OperIs(GT_IND, GT_LCL_VAR)) + return asg; + + if (effectiveOp1->OperIs(GT_LCL_VAR) && + !lvaGetDesc(effectiveOp1->AsLclVarCommon()->GetLclNum())->lvNormalizeOnLoad()) + return asg; + + if (op2->gtOverflow()) + return asg; + + if (gtIsActiveCSE_Candidate(op2)) + return asg; + + GenTreeCast* cast = op2->AsCast(); + var_types castToType = cast->CastToType(); + var_types castFromType = cast->CastFromType(); + + if (gtIsActiveCSE_Candidate(cast->CastOp())) + return asg; + + if (!varTypeIsSmall(effectiveOp1)) + return asg; + + if (!varTypeIsSmall(castToType)) + return asg; + + if (!varTypeIsIntegral(castFromType)) + return asg; + + // If we are performing a narrowing cast and + // castToType is larger or the same as op1's type + // then we can discard the cast. + if (genTypeSize(castToType) < genTypeSize(effectiveOp1)) + return asg; + + if (genActualType(castFromType) == genActualType(castToType)) + { + // Removes the cast. + asg->gtOp2 = cast->CastOp(); + } + else + { + // This is a type-changing cast so we cannot remove it entirely. + cast->gtCastType = genActualType(castToType); + } + + return asg; +} + //------------------------------------------------------------------------ // fgOptimizeEqualityComparisonWithConst: optimizes various EQ/NE(OP, CONST) patterns. // diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_70333/Runtime_70333.cs b/src/tests/JIT/Regression/JitBlue/Runtime_70333/Runtime_70333.cs new file mode 100644 index 00000000000000..ef675c85726404 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_70333/Runtime_70333.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; + +public class Program +{ + public static int Main() + { + Test(); + + return 100; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void Test() + { + M1(0); + } + + public static void M1(byte arg0) + { + long var6 = default(long); + arg0 = (byte)(~(ulong)var6 % 3545460779U); + System.Console.WriteLine(arg0); + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_70333/Runtime_70333.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_70333/Runtime_70333.csproj new file mode 100644 index 00000000000000..f492aeac9d056b --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_70333/Runtime_70333.csproj @@ -0,0 +1,9 @@ + + + Exe + True + + + + + \ No newline at end of file From 3b0951964b330533de771b04165f931b1f1e4078 Mon Sep 17 00:00:00 2001 From: Ankit Jain Date: Thu, 16 Jun 2022 16:33:58 -0400 Subject: [PATCH 166/337] [wasm] Disable WBT test failing on windows (#70808) Issue: https://github.com/dotnet/runtime/issues/70675 --- src/tests/BuildWasmApps/Wasm.Build.Tests/WasmTemplateTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmTemplateTests.cs b/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmTemplateTests.cs index bf0b9e52a8f654..f5826363ae8077 100644 --- a/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmTemplateTests.cs +++ b/src/tests/BuildWasmApps/Wasm.Build.Tests/WasmTemplateTests.cs @@ -148,6 +148,7 @@ public void ConsoleBuildAndRun(string config) } [ConditionalTheory(typeof(BuildTestBase), nameof(IsUsingWorkloads))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/70675", TestPlatforms.Windows)] [InlineData("Debug", false)] [InlineData("Debug", true)] [InlineData("Release", false)] From 502f9acc71722e5057f3261f462daaca28492b59 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Thu, 16 Jun 2022 16:57:36 -0400 Subject: [PATCH 167/337] Enable IDE1005 (Delegate invocation can be simplified) (#70522) --- eng/CodeAnalysis.src.globalconfig | 2 +- .../Internal/Runtime/TypeLoader/ModuleList.cs | 10 +-- .../ComposablePartCatalogCollection.cs | 12 +--- .../Composition/Hosting/DirectoryCatalog.cs | 12 +--- .../Diagnostics/Reader/EventLogWatcher.cs | 5 +- .../src/System/Drawing/ImageInfo.cs | 5 +- .../src/System/IO/Ports/SerialStream.Unix.cs | 22 +++---- .../ManagementNamedValueCollection.cs | 3 +- .../src/System/Management/ManagementObject.cs | 3 +- .../System/Management/ManagementOptions.cs | 3 +- .../src/System/Management/ManagementPath.cs | 3 +- .../src/System/Management/ManagementQuery.cs | 3 +- .../src/System/Management/ManagementScope.cs | 3 +- .../src/System/Net/TaskExtensions.cs | 5 +- .../src/System/Xml/Linq/XObject.cs | 10 +-- .../src/System/Xml/Core/XmlTextReaderImpl.cs | 5 +- .../src/System/Xml/Dom/XmlDocument.cs | 18 ++--- .../src/System/Xml/Schema/BaseProcessor.cs | 5 +- .../src/System/Xml/Schema/SchemaInfo.cs | 5 +- .../Xml/Xsl/Runtime/XmlAttributeCache.cs | 3 +- .../System/Xml/Xsl/Runtime/XmlQueryContext.cs | 5 +- .../src/Internal/Cryptography/PkcsHelpers.cs | 5 +- .../src/Internal/AsyncSerializedWorker.cs | 4 +- .../src/Internal/SrgsParser/XmlParser.cs | 5 +- .../System.Speech/src/Recognition/Grammar.cs | 6 +- .../src/Recognition/RecognizerBase.cs | 19 +----- .../Recognition/SpeechRecognitionEngine.cs | 66 ++++--------------- .../src/Recognition/SpeechRecognizer.cs | 66 ++++--------------- .../src/Blocks/BroadcastBlock.cs | 2 +- 29 files changed, 69 insertions(+), 246 deletions(-) diff --git a/eng/CodeAnalysis.src.globalconfig b/eng/CodeAnalysis.src.globalconfig index 51da5a2e70b974..24427d2df83ba3 100644 --- a/eng/CodeAnalysis.src.globalconfig +++ b/eng/CodeAnalysis.src.globalconfig @@ -1570,7 +1570,7 @@ dotnet_diagnostic.IDE0160.severity = silent dotnet_diagnostic.IDE0161.severity = silent # IDE1005: Delegate invocation can be simplified. -dotnet_diagnostic.IDE1005.severity = suggestion +dotnet_diagnostic.IDE1005.severity = warning # IDE1006: Naming styles dotnet_diagnostic.IDE1006.severity = silent diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/ModuleList.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/ModuleList.cs index f6e52ed013dd20..efafe262ed4d51 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/ModuleList.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/ModuleList.cs @@ -710,10 +710,7 @@ public void RegisterNewModules(ModuleType moduleType) updatedModules[oldModuleCount + newModuleIndex] = newModuleInfo; - if (_moduleRegistrationCallbacks != null) - { - _moduleRegistrationCallbacks(newModuleInfo); - } + _moduleRegistrationCallbacks?.Invoke(newModuleInfo); } // Atomically update the module map @@ -734,10 +731,7 @@ public void RegisterModule(ModuleInfo newModuleInfo) Array.Copy(_loadedModuleMap.Modules, 0, updatedModules, 0, oldModuleCount); } updatedModules[oldModuleCount] = newModuleInfo; - if (_moduleRegistrationCallbacks != null) - { - _moduleRegistrationCallbacks(newModuleInfo); - } + _moduleRegistrationCallbacks?.Invoke(newModuleInfo); // Atomically update the module map _loadedModuleMap = new ModuleMap(updatedModules); diff --git a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/ComposablePartCatalogCollection.cs b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/ComposablePartCatalogCollection.cs index d084df496f51b5..58007738a8ed4d 100644 --- a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/ComposablePartCatalogCollection.cs +++ b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/ComposablePartCatalogCollection.cs @@ -308,11 +308,7 @@ private void RaiseChangedEvent( public void OnChanged(object sender, ComposablePartCatalogChangeEventArgs e) { - var changedEvent = Changed; - if (changedEvent != null) - { - changedEvent(sender, e); - } + Changed?.Invoke(sender, e); } private void RaiseChangingEvent( @@ -332,11 +328,7 @@ private void RaiseChangingEvent( public void OnChanging(object sender, ComposablePartCatalogChangeEventArgs e) { - var changingEvent = Changing; - if (changingEvent != null) - { - changingEvent(sender, e); - } + Changing?.Invoke(sender, e); } private void OnContainedCatalogChanged(object? sender, ComposablePartCatalogChangeEventArgs e) diff --git a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/DirectoryCatalog.cs b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/DirectoryCatalog.cs index e89a4e9eac7a39..ff8ea6d86b14d8 100644 --- a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/DirectoryCatalog.cs +++ b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/DirectoryCatalog.cs @@ -539,11 +539,7 @@ public override IEnumerable> G /// protected virtual void OnChanged(ComposablePartCatalogChangeEventArgs e) { - EventHandler? changedEvent = Changed; - if (changedEvent != null) - { - changedEvent(this, e); - } + Changed?.Invoke(this, e); } /// @@ -554,11 +550,7 @@ protected virtual void OnChanged(ComposablePartCatalogChangeEventArgs e) /// protected virtual void OnChanging(ComposablePartCatalogChangeEventArgs e) { - EventHandler? changingEvent = Changing; - if (changingEvent != null) - { - changingEvent(this, e); - } + Changing?.Invoke(this, e); } /// diff --git a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/EventLogWatcher.cs b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/EventLogWatcher.cs index 112b1fa2bbf844..547e63241c2dd0 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/EventLogWatcher.cs +++ b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/EventLogWatcher.cs @@ -256,10 +256,7 @@ private void RequestEvents() private void IssueCallback(EventRecordWrittenEventArgs eventArgs) { - if (EventRecordWritten != null) - { - EventRecordWritten(this, eventArgs); - } + EventRecordWritten?.Invoke(this, eventArgs); } private void HandleEventsRequestCompletion() diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/ImageInfo.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/ImageInfo.cs index a5eed455409732..822cdeda47a246 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/ImageInfo.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/ImageInfo.cs @@ -217,10 +217,7 @@ internal void UpdateFrame() /// private void OnFrameChanged(EventArgs e) { - if (_onFrameChangedHandler != null) - { - _onFrameChangedHandler(_image, e); - } + _onFrameChangedHandler?.Invoke(_image, e); } } } diff --git a/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Unix.cs b/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Unix.cs index c2beb7ef0d9932..9cc733c2b96be6 100644 --- a/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Unix.cs +++ b/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Unix.cs @@ -709,9 +709,9 @@ private void RaiseDataReceivedChars() if (_dataReceived != null) { ThreadPool.QueueUserWorkItem(s => { - var thisRef = (SerialStream)s; - thisRef._dataReceived?.Invoke(thisRef, new SerialDataReceivedEventArgs(SerialData.Chars)); - }, this); + var thisRef = (SerialStream)s; + thisRef._dataReceived?.Invoke(thisRef, new SerialDataReceivedEventArgs(SerialData.Chars)); + }, this); } } @@ -720,9 +720,9 @@ private void RaisePinChanged(SerialPinChange pinChanged) if (_pinChanged != null) { ThreadPool.QueueUserWorkItem(s => { - var thisRef = (SerialStream)s; - thisRef._pinChanged?.Invoke(thisRef, new SerialPinChangedEventArgs(pinChanged)); - }, this); + var thisRef = (SerialStream)s; + thisRef._pinChanged?.Invoke(thisRef, new SerialPinChangedEventArgs(pinChanged)); + }, this); } } @@ -731,13 +731,9 @@ private void RaiseDataReceivedEof() if (_dataReceived != null) { ThreadPool.QueueUserWorkItem(s => { - var thisRef = (SerialStream)s; - SerialDataReceivedEventHandler dataReceived = thisRef._dataReceived; - if (dataReceived != null) - { - dataReceived(thisRef, new SerialDataReceivedEventArgs(SerialData.Eof)); - } - }, this); + var thisRef = (SerialStream)s; + thisRef._dataReceived?.Invoke(thisRef, new SerialDataReceivedEventArgs(SerialData.Eof)); + }, this); } } diff --git a/src/libraries/System.Management/src/System/Management/ManagementNamedValueCollection.cs b/src/libraries/System.Management/src/System/Management/ManagementNamedValueCollection.cs index 7da647095b362a..862419ff4631c3 100644 --- a/src/libraries/System.Management/src/System/Management/ManagementNamedValueCollection.cs +++ b/src/libraries/System.Management/src/System/Management/ManagementNamedValueCollection.cs @@ -21,8 +21,7 @@ public class ManagementNamedValueCollection : NameObjectCollectionBase //Fires IdentifierChanged event private void FireIdentifierChanged() { - if (IdentifierChanged != null) - IdentifierChanged(this, null); + IdentifierChanged?.Invoke(this, null); } //default constructor diff --git a/src/libraries/System.Management/src/System/Management/ManagementObject.cs b/src/libraries/System.Management/src/System/Management/ManagementObject.cs index 4bd2095392917f..d6df1d4005d0d7 100644 --- a/src/libraries/System.Management/src/System/Management/ManagementObject.cs +++ b/src/libraries/System.Management/src/System/Management/ManagementObject.cs @@ -114,8 +114,7 @@ protected override void GetObjectData(SerializationInfo info, StreamingContext c internal void FireIdentifierChanged() { - if (IdentifierChanged != null) - IdentifierChanged(this, null); + IdentifierChanged?.Invoke(this, null); } internal bool PutButNotGot diff --git a/src/libraries/System.Management/src/System/Management/ManagementOptions.cs b/src/libraries/System.Management/src/System/Management/ManagementOptions.cs index 71e7bbe6ecb3d5..6b05f5ef2b2bd2 100644 --- a/src/libraries/System.Management/src/System/Management/ManagementOptions.cs +++ b/src/libraries/System.Management/src/System/Management/ManagementOptions.cs @@ -135,8 +135,7 @@ public abstract class ManagementOptions : ICloneable //Fires IdentifierChanged event internal void FireIdentifierChanged() { - if (IdentifierChanged != null) - IdentifierChanged(this, null); + IdentifierChanged?.Invoke(this, null); } //Called when IdentifierChanged() event fires diff --git a/src/libraries/System.Management/src/System/Management/ManagementPath.cs b/src/libraries/System.Management/src/System/Management/ManagementPath.cs index def7a2f356d1a3..7dd7af05b81a86 100644 --- a/src/libraries/System.Management/src/System/Management/ManagementPath.cs +++ b/src/libraries/System.Management/src/System/Management/ManagementPath.cs @@ -83,8 +83,7 @@ public class ManagementPath : ICloneable //Fires IdentifierChanged event private void FireIdentifierChanged() { - if (IdentifierChanged != null) - IdentifierChanged(this, null); + IdentifierChanged?.Invoke(this, null); } //internal factory diff --git a/src/libraries/System.Management/src/System/Management/ManagementQuery.cs b/src/libraries/System.Management/src/System/Management/ManagementQuery.cs index 4d37fdc4abcdb6..e9e0fe736317c4 100644 --- a/src/libraries/System.Management/src/System/Management/ManagementQuery.cs +++ b/src/libraries/System.Management/src/System/Management/ManagementQuery.cs @@ -31,8 +31,7 @@ public abstract class ManagementQuery : ICloneable //Fires IdentifierChanged event internal void FireIdentifierChanged() { - if (IdentifierChanged != null) - IdentifierChanged(this, null); + IdentifierChanged?.Invoke(this, null); } private string queryLanguage; diff --git a/src/libraries/System.Management/src/System/Management/ManagementScope.cs b/src/libraries/System.Management/src/System/Management/ManagementScope.cs index a1b10722738e2d..f7d81159035551 100644 --- a/src/libraries/System.Management/src/System/Management/ManagementScope.cs +++ b/src/libraries/System.Management/src/System/Management/ManagementScope.cs @@ -494,8 +494,7 @@ public class ManagementScope : ICloneable //Fires IdentifierChanged event private void FireIdentifierChanged() { - if (IdentifierChanged != null) - IdentifierChanged(this, null); + IdentifierChanged?.Invoke(this, null); } //Called when IdentifierChanged() event fires diff --git a/src/libraries/System.Net.Requests/src/System/Net/TaskExtensions.cs b/src/libraries/System.Net.Requests/src/System/Net/TaskExtensions.cs index ddf2365014ba79..7732cf149317b8 100644 --- a/src/libraries/System.Net.Requests/src/System/Net/TaskExtensions.cs +++ b/src/libraries/System.Net.Requests/src/System/Net/TaskExtensions.cs @@ -38,10 +38,7 @@ public static TaskCompletionSource ToApm( // already transitioned to a Canceled state via a previous HttpWebRequest.Abort() call. if (shouldInvokeCallback) { - if (callback != null) - { - callback(tcs.Task); - } + callback?.Invoke(tcs.Task); } else { diff --git a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XObject.cs b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XObject.cs index 055d2ed9c15c7a..5bd9d3f1a2a8ae 100644 --- a/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XObject.cs +++ b/src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XObject.cs @@ -430,10 +430,7 @@ internal bool NotifyChanged(object sender, XObjectChangeEventArgs e) if (a != null) { notify = true; - if (a.changed != null) - { - a.changed(sender, e); - } + a.changed?.Invoke(sender, e); } o = o.parent; } @@ -455,10 +452,7 @@ internal bool NotifyChanging(object sender, XObjectChangeEventArgs e) if (a != null) { notify = true; - if (a.changing != null) - { - a.changing(sender, e); - } + a.changing?.Invoke(sender, e); } o = o.parent; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs index e7595f82e1cfaf..9819b04db6c302 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs @@ -9332,10 +9332,7 @@ private bool AddDefaultAttributeDtd(IDtdDefaultAttributeInfo defAttrInfo, bool d if (DtdValidation) { - if (_onDefaultAttributeUse != null) - { - _onDefaultAttributeUse(defAttrInfo, this); - } + _onDefaultAttributeUse?.Invoke(defAttrInfo, this); attr.typedValue = defAttrInfo.DefaultValueTyped; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDocument.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDocument.cs index 15d845fc8c3518..ae6a6c3d2c47bb 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDocument.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/XmlDocument.cs @@ -1646,18 +1646,15 @@ internal override void BeforeEvent(XmlNodeChangedEventArgs args) switch (args.Action) { case XmlNodeChangedAction.Insert: - if (_onNodeInsertingDelegate != null) - _onNodeInsertingDelegate(this, args); + _onNodeInsertingDelegate?.Invoke(this, args); break; case XmlNodeChangedAction.Remove: - if (_onNodeRemovingDelegate != null) - _onNodeRemovingDelegate(this, args); + _onNodeRemovingDelegate?.Invoke(this, args); break; case XmlNodeChangedAction.Change: - if (_onNodeChangingDelegate != null) - _onNodeChangingDelegate(this, args); + _onNodeChangingDelegate?.Invoke(this, args); break; } } @@ -1670,18 +1667,15 @@ internal override void AfterEvent(XmlNodeChangedEventArgs args) switch (args.Action) { case XmlNodeChangedAction.Insert: - if (_onNodeInsertedDelegate != null) - _onNodeInsertedDelegate(this, args); + _onNodeInsertedDelegate?.Invoke(this, args); break; case XmlNodeChangedAction.Remove: - if (_onNodeRemovedDelegate != null) - _onNodeRemovedDelegate(this, args); + _onNodeRemovedDelegate?.Invoke(this, args); break; case XmlNodeChangedAction.Change: - if (_onNodeChangedDelegate != null) - _onNodeChangedDelegate(this, args); + _onNodeChangedDelegate?.Invoke(this, args); break; } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/BaseProcessor.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/BaseProcessor.cs index 83b3ccac5e0801..fc9f499731afb3 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/BaseProcessor.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/BaseProcessor.cs @@ -282,10 +282,7 @@ protected void SendValidationEventNoThrow(XmlSchemaException e, XmlSeverityType { _errorCount++; } - if (_eventHandler != null) - { - _eventHandler(null, new ValidationEventArgs(e, severity)); - } + _eventHandler?.Invoke(null, new ValidationEventArgs(e, severity)); } }; } // namespace System.Xml diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaInfo.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaInfo.cs index 55f07c28b5804f..f85e4352619087 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaInfo.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaInfo.cs @@ -320,10 +320,7 @@ internal void Add(SchemaInfo sinfo, ValidationEventHandler? eventhandler) } else if (_schemaType != sinfo.SchemaType) { - if (eventhandler != null) - { - eventhandler(this, new ValidationEventArgs(new XmlSchemaException(SR.Sch_MixSchemaTypes, string.Empty))); - } + eventhandler?.Invoke(this, new ValidationEventArgs(new XmlSchemaException(SR.Sch_MixSchemaTypes, string.Empty))); return; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XmlAttributeCache.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XmlAttributeCache.cs index 200f1456e298f8..2cbe985cdfe604 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XmlAttributeCache.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XmlAttributeCache.cs @@ -262,8 +262,7 @@ private void FlushAttributes() } // Notify event listener that attributes have been flushed - if (_onRemove != null) - _onRemove(_wrapped); + _onRemove?.Invoke(_wrapped); } private struct AttrNameVal diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XmlQueryContext.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XmlQueryContext.cs index b98814770aac12..3aa16dd7e9c7ae 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XmlQueryContext.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/Runtime/XmlQueryContext.cs @@ -331,10 +331,7 @@ public IList InvokeXsltLateBoundFunction(string name, string namespac /// public void OnXsltMessageEncountered(string message) { - XsltMessageEncounteredEventHandler onMessage = (_argList != null) ? _argList.xsltMessageEncountered : null; - - if (onMessage != null) - onMessage(this, new XmlILQueryEventArgs(message)); + _argList?.xsltMessageEncountered?.Invoke(this, new XmlILQueryEventArgs(message)); } } diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/PkcsHelpers.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/PkcsHelpers.cs index 7e810dae5e7bdd..ba85dfd745c26a 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/PkcsHelpers.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/Internal/Cryptography/PkcsHelpers.cs @@ -149,10 +149,7 @@ public static AttributeAsn[] NormalizeAttributeSet( writer.PopSetOf(); normalizedValue = writer.Encode(); - if (encodedValueProcessor != null) - { - encodedValueProcessor(normalizedValue); - } + encodedValueProcessor?.Invoke(normalizedValue); try { diff --git a/src/libraries/System.Speech/src/Internal/AsyncSerializedWorker.cs b/src/libraries/System.Speech/src/Internal/AsyncSerializedWorker.cs index 5396cd09d6c2e0..5d9184f0593288 100644 --- a/src/libraries/System.Speech/src/Internal/AsyncSerializedWorker.cs +++ b/src/libraries/System.Speech/src/Internal/AsyncSerializedWorker.cs @@ -236,9 +236,9 @@ private void OnWorkItemPending() _syncContext.Post(_workerPostCallback, null); } } - else if (WorkItemPending != null) + else { - WorkItemPending(null); + WorkItemPending?.Invoke(null); } } } diff --git a/src/libraries/System.Speech/src/Internal/SrgsParser/XmlParser.cs b/src/libraries/System.Speech/src/Internal/SrgsParser/XmlParser.cs index 7ac31ddfa34418..964f860690b0e1 100644 --- a/src/libraries/System.Speech/src/Internal/SrgsParser/XmlParser.cs +++ b/src/libraries/System.Speech/src/Internal/SrgsParser/XmlParser.cs @@ -175,10 +175,7 @@ internal static void ParseText(IElement parent, string sChars, string pronunciat } // Parse the token. - if (createTokens != null) - { - createTokens(parent, sToken, pronunciation, display, reqConfidence); - } + createTokens?.Invoke(parent, sToken, pronunciation, display, reqConfidence); } } diff --git a/src/libraries/System.Speech/src/Recognition/Grammar.cs b/src/libraries/System.Speech/src/Recognition/Grammar.cs index 9166d026c5aa92..0f57d4ca07fbb7 100644 --- a/src/libraries/System.Speech/src/Recognition/Grammar.cs +++ b/src/libraries/System.Speech/src/Recognition/Grammar.cs @@ -474,11 +474,7 @@ internal void OnRecognitionInternal(SpeechRecognizedEventArgs eventArgs) { Debug.Assert(eventArgs.Result.Grammar == this); - EventHandler recognitionHandler = SpeechRecognized; - if (recognitionHandler != null) - { - recognitionHandler(this, eventArgs); - } + SpeechRecognized?.Invoke(this, eventArgs); } // Helper method used to indicate if this grammar has a dictation Uri or not. diff --git a/src/libraries/System.Speech/src/Recognition/RecognizerBase.cs b/src/libraries/System.Speech/src/Recognition/RecognizerBase.cs index a39edc4a79be2f..cfcf67c105987d 100644 --- a/src/libraries/System.Speech/src/Recognition/RecognizerBase.cs +++ b/src/libraries/System.Speech/src/Recognition/RecognizerBase.cs @@ -1762,12 +1762,7 @@ private void LoadGrammarAsyncCompletedCallback(object grammarObject) Debug.WriteLine("Raising LoadGrammarCompleted event."); Grammar grammar = (Grammar)grammarObject; - EventHandler loadGrammarCompletedHandler = LoadGrammarCompleted; - if (loadGrammarCompletedHandler != null) - { - // When a LoadGrammarAsync completes all we must do is raise the LoadGrammarCompleted event. - loadGrammarCompletedHandler(this, new LoadGrammarCompletedEventArgs(grammar, grammar.LoadException, false, null)); - } + LoadGrammarCompleted?.Invoke(this, new LoadGrammarCompletedEventArgs(grammar, grammar.LoadException, false, null)); } // Create a new sapi grammarId and SapiGrammar object. @@ -2091,11 +2086,7 @@ private void RecognizeAsyncWaitForGrammarsToLoadFailed(object eventArgs) } // Now raise RecognizeCompleted event. - EventHandler recognizeCompletedHandler = RecognizeCompleted; - if (recognizeCompletedHandler != null) - { - recognizeCompletedHandler(this, (RecognizeCompletedEventArgs)eventArgs); - } + RecognizeCompleted?.Invoke(this, (RecognizeCompletedEventArgs)eventArgs); } // This method will be called asynchronously @@ -2264,11 +2255,7 @@ private void ProcessBookmarkEvent(SpeechEvent speechEvent) { object userToken = GetBookmarkItemAndRemove(bookmarkId); - EventHandler updateHandler = RecognizerUpdateReached; - if (updateHandler != null) - { - updateHandler(this, new RecognizerUpdateReachedEventArgs(userToken, speechEvent.AudioPosition)); - } + RecognizerUpdateReached?.Invoke(this, new RecognizerUpdateReachedEventArgs(userToken, speechEvent.AudioPosition)); } } catch (COMException e) diff --git a/src/libraries/System.Speech/src/Recognition/SpeechRecognitionEngine.cs b/src/libraries/System.Speech/src/Recognition/SpeechRecognitionEngine.cs index e13b59a5e2c6cc..1551e22f02925e 100644 --- a/src/libraries/System.Speech/src/Recognition/SpeechRecognitionEngine.cs +++ b/src/libraries/System.Speech/src/Recognition/SpeechRecognitionEngine.cs @@ -546,101 +546,57 @@ private void Initialize(RecognizerInfo recognizerInfo) private void RecognizeCompletedProxy(object sender, RecognizeCompletedEventArgs e) { - EventHandler recognizeCompletedHandler = RecognizeCompleted; - if (recognizeCompletedHandler != null) - { - recognizeCompletedHandler(this, e); - } + RecognizeCompleted?.Invoke(this, e); } private void EmulateRecognizeCompletedProxy(object sender, EmulateRecognizeCompletedEventArgs e) { - EventHandler emulateRecognizeCompletedHandler = EmulateRecognizeCompleted; - if (emulateRecognizeCompletedHandler != null) - { - emulateRecognizeCompletedHandler(this, e); - } + EmulateRecognizeCompleted?.Invoke(this, e); } private void LoadGrammarCompletedProxy(object sender, LoadGrammarCompletedEventArgs e) { - EventHandler loadGrammarCompletedHandler = LoadGrammarCompleted; - if (loadGrammarCompletedHandler != null) - { - loadGrammarCompletedHandler(this, e); - } + LoadGrammarCompleted?.Invoke(this, e); } private void SpeechDetectedProxy(object sender, SpeechDetectedEventArgs e) { - EventHandler speechDetectedHandler = SpeechDetected; - if (speechDetectedHandler != null) - { - speechDetectedHandler(this, e); - } + SpeechDetected?.Invoke(this, e); } private void SpeechRecognizedProxy(object sender, SpeechRecognizedEventArgs e) { - EventHandler speechRecognizedHandler = SpeechRecognized; - if (speechRecognizedHandler != null) - { - speechRecognizedHandler(this, e); - } + SpeechRecognized?.Invoke(this, e); } private void SpeechRecognitionRejectedProxy(object sender, SpeechRecognitionRejectedEventArgs e) { - EventHandler speechRecognitionRejectedHandler = SpeechRecognitionRejected; - if (speechRecognitionRejectedHandler != null) - { - speechRecognitionRejectedHandler(this, e); - } + SpeechRecognitionRejected?.Invoke(this, e); } private void RecognizerUpdateReachedProxy(object sender, RecognizerUpdateReachedEventArgs e) { - EventHandler recognizerUpdateReachedHandler = RecognizerUpdateReached; - if (recognizerUpdateReachedHandler != null) - { - recognizerUpdateReachedHandler(this, e); - } + RecognizerUpdateReached?.Invoke(this, e); } private void SpeechHypothesizedProxy(object sender, SpeechHypothesizedEventArgs e) { - EventHandler speechHypothesizedHandler = _speechHypothesizedDelegate; - if (speechHypothesizedHandler != null) - { - speechHypothesizedHandler(this, e); - } + _speechHypothesizedDelegate?.Invoke(this, e); } private void AudioSignalProblemOccurredProxy(object sender, AudioSignalProblemOccurredEventArgs e) { - EventHandler audioSignalProblemOccurredHandler = _audioSignalProblemOccurredDelegate; - if (audioSignalProblemOccurredHandler != null) - { - audioSignalProblemOccurredHandler(this, e); - } + _audioSignalProblemOccurredDelegate?.Invoke(this, e); } private void AudioLevelUpdatedProxy(object sender, AudioLevelUpdatedEventArgs e) { - EventHandler audioLevelUpdatedHandler = _audioLevelUpdatedDelegate; - if (audioLevelUpdatedHandler != null) - { - audioLevelUpdatedHandler(this, e); - } + _audioLevelUpdatedDelegate?.Invoke(this, e); } private void AudioStateChangedProxy(object sender, AudioStateChangedEventArgs e) { - EventHandler audioStateChangedHandler = _audioStateChangedDelegate; - if (audioStateChangedHandler != null) - { - audioStateChangedHandler(this, e); - } + _audioStateChangedDelegate?.Invoke(this, e); } #endregion diff --git a/src/libraries/System.Speech/src/Recognition/SpeechRecognizer.cs b/src/libraries/System.Speech/src/Recognition/SpeechRecognizer.cs index 91c01424b63ec9..9f6b96542bc297 100644 --- a/src/libraries/System.Speech/src/Recognition/SpeechRecognizer.cs +++ b/src/libraries/System.Speech/src/Recognition/SpeechRecognizer.cs @@ -333,101 +333,57 @@ public event EventHandler AudioStateChanged private void StateChangedProxy(object sender, StateChangedEventArgs e) { - EventHandler stateChangedHandler = StateChanged; - if (stateChangedHandler != null) - { - stateChangedHandler(this, e); - } + StateChanged?.Invoke(this, e); } private void EmulateRecognizeCompletedProxy(object sender, EmulateRecognizeCompletedEventArgs e) { - EventHandler emulateRecognizeCompletedHandler = EmulateRecognizeCompleted; - if (emulateRecognizeCompletedHandler != null) - { - emulateRecognizeCompletedHandler(this, e); - } + EmulateRecognizeCompleted?.Invoke(this, e); } private void LoadGrammarCompletedProxy(object sender, LoadGrammarCompletedEventArgs e) { - EventHandler loadGrammarCompletedHandler = LoadGrammarCompleted; - if (loadGrammarCompletedHandler != null) - { - loadGrammarCompletedHandler(this, e); - } + LoadGrammarCompleted?.Invoke(this, e); } private void SpeechDetectedProxy(object sender, SpeechDetectedEventArgs e) { - EventHandler speechDetectedHandler = SpeechDetected; - if (speechDetectedHandler != null) - { - speechDetectedHandler(this, e); - } + SpeechDetected?.Invoke(this, e); } private void SpeechRecognizedProxy(object sender, SpeechRecognizedEventArgs e) { - EventHandler speechRecognizedHandler = SpeechRecognized; - if (speechRecognizedHandler != null) - { - speechRecognizedHandler(this, e); - } + SpeechRecognized?.Invoke(this, e); } private void SpeechRecognitionRejectedProxy(object sender, SpeechRecognitionRejectedEventArgs e) { - EventHandler speechRecognitionRejectedHandler = SpeechRecognitionRejected; - if (speechRecognitionRejectedHandler != null) - { - speechRecognitionRejectedHandler(this, e); - } + SpeechRecognitionRejected?.Invoke(this, e); } private void RecognizerUpdateReachedProxy(object sender, RecognizerUpdateReachedEventArgs e) { - EventHandler recognizerUpdateReachedHandler = RecognizerUpdateReached; - if (recognizerUpdateReachedHandler != null) - { - recognizerUpdateReachedHandler(this, e); - } + RecognizerUpdateReached?.Invoke(this, e); } private void SpeechHypothesizedProxy(object sender, SpeechHypothesizedEventArgs e) { - EventHandler speechHypothesizedHandler = _speechHypothesizedDelegate; - if (speechHypothesizedHandler != null) - { - speechHypothesizedHandler(this, e); - } + _speechHypothesizedDelegate?.Invoke(this, e); } private void AudioSignalProblemOccurredProxy(object sender, AudioSignalProblemOccurredEventArgs e) { - EventHandler audioSignalProblemOccurredHandler = _audioSignalProblemOccurredDelegate; - if (audioSignalProblemOccurredHandler != null) - { - audioSignalProblemOccurredHandler(this, e); - } + _audioSignalProblemOccurredDelegate?.Invoke(this, e); } private void AudioLevelUpdatedProxy(object sender, AudioLevelUpdatedEventArgs e) { - EventHandler audioLevelUpdatedHandler = _audioLevelUpdatedDelegate; - if (audioLevelUpdatedHandler != null) - { - audioLevelUpdatedHandler(this, e); - } + _audioLevelUpdatedDelegate?.Invoke(this, e); } private void AudioStateChangedProxy(object sender, AudioStateChangedEventArgs e) { - EventHandler audioStateChangedHandler = _audioStateChangedDelegate; - if (audioStateChangedHandler != null) - { - audioStateChangedHandler(this, e); - } + _audioStateChangedDelegate?.Invoke(this, e); } #endregion diff --git a/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/BroadcastBlock.cs b/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/BroadcastBlock.cs index d0b0cead273331..d042235dc245a3 100644 --- a/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/BroadcastBlock.cs +++ b/src/libraries/System.Threading.Tasks.Dataflow/src/Blocks/BroadcastBlock.cs @@ -759,7 +759,7 @@ private bool OfferToTargets() if (header.IsValid) { // Notify the owner block that our count has decreased - if (_itemsRemovedAction != null) _itemsRemovedAction(numDequeuedMessages); + _itemsRemovedAction?.Invoke(numDequeuedMessages); // Offer it to each target, unless a soleTarget was provided, which case just offer it to that one. TargetRegistry.LinkedTargetInfo? cur = _targetRegistry.FirstTargetNode; From 1dbda71ca2b297ae5b72a2c871c1d6e341153d80 Mon Sep 17 00:00:00 2001 From: Fan Yang <52458914+fanyang-mono@users.noreply.github.com> Date: Thu, 16 Jun 2022 17:14:12 -0400 Subject: [PATCH 168/337] Disable long running test (#70843) --- src/tests/issues.targets | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tests/issues.targets b/src/tests/issues.targets index a4e91296655d74..beb49a9d74d9fa 100644 --- a/src/tests/issues.targets +++ b/src/tests/issues.targets @@ -3710,6 +3710,9 @@ needs triage + + https://github.com/dotnet/runtime/issues/70820 + needs triage From ae49f52e6bd29cd272e3a1c97e2c785ac83a9f1d Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Thu, 16 Jun 2022 23:19:35 +0200 Subject: [PATCH 169/337] [wasm] Enabled WriteToReadOnly tests - emscripten bug got fixed (#70814) Fixes #53021. Enabled tests from #53021 - they are passing now because issue reported by @radekdoulik got fixed: https://github.com/emscripten-core/emscripten/issues/14299. --- .../System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs | 1 - .../System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs | 1 - .../System.IO.FileSystem/tests/File/ReadWriteAllLines.cs | 2 -- .../System.IO.FileSystem/tests/File/ReadWriteAllLinesAsync.cs | 1 - .../System.IO.FileSystem/tests/File/ReadWriteAllText.cs | 1 - .../System.IO.FileSystem/tests/File/ReadWriteAllTextAsync.cs | 1 - .../tests/MemoryMappedFile.CreateFromFile.Tests.cs | 2 -- 7 files changed, 9 deletions(-) diff --git a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs index bcb3de4825c737..a3abe2311868ec 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs @@ -86,7 +86,6 @@ public void OpenFile_ThrowsIOException() /// file is allowed. /// [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/53021", TestPlatforms.Browser)] public void WriteToReadOnlyFile() { string path = GetTestFilePath(); diff --git a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs index 2c6df24b702f0b..8ae63fe3c9e0a5 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs @@ -97,7 +97,6 @@ public async Task OpenFile_ThrowsIOExceptionAsync() /// file is allowed. /// [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/53021", TestPlatforms.Browser)] public async Task WriteToReadOnlyFileAsync() { string path = GetTestFilePath(); diff --git a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllLines.cs b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllLines.cs index 99de941c391757..bbd5ceeed4c252 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllLines.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllLines.cs @@ -118,7 +118,6 @@ public void Read_FileNotFound() /// file is allowed. /// [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/53021", TestPlatforms.Browser)] public void WriteToReadOnlyFile() { string path = GetTestFilePath(); @@ -307,7 +306,6 @@ public void Read_FileNotFound() /// file is allowed. /// [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/53021", TestPlatforms.Browser)] public void WriteToReadOnlyFile() { string path = GetTestFilePath(); diff --git a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllLinesAsync.cs b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllLinesAsync.cs index 44389dddc8e90e..17c6e565bc79db 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllLinesAsync.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllLinesAsync.cs @@ -113,7 +113,6 @@ public Task Read_FileNotFound() => /// file is allowed. /// [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/53021", TestPlatforms.Browser)] public async Task WriteToReadOnlyFile() { string path = GetTestFilePath(); diff --git a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllText.cs b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllText.cs index 8c9c1e66e72a4b..fd4abc7b60166b 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllText.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllText.cs @@ -131,7 +131,6 @@ public void Read_FileNotFound() /// file is allowed. /// [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/53021", TestPlatforms.Browser)] public void WriteToReadOnlyFile() { string path = GetTestFilePath(); diff --git a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllTextAsync.cs b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllTextAsync.cs index 660daf3437e0af..0c9d7cb699c453 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllTextAsync.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllTextAsync.cs @@ -122,7 +122,6 @@ public Task Read_FileNotFoundAsync() => /// file is allowed. /// [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/53021", TestPlatforms.Browser)] public async Task WriteToReadOnlyFileAsync() { string path = GetTestFilePath(); diff --git a/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFile.CreateFromFile.Tests.cs b/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFile.CreateFromFile.Tests.cs index e99b727ebec355..5e92b74b94d285 100644 --- a/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFile.CreateFromFile.Tests.cs +++ b/src/libraries/System.IO.MemoryMappedFiles/tests/MemoryMappedFile.CreateFromFile.Tests.cs @@ -699,7 +699,6 @@ private void WriteToReadOnlyFile(MemoryMappedFileAccess access, bool succeeds) [Theory] [InlineData(MemoryMappedFileAccess.Read)] [InlineData(MemoryMappedFileAccess.ReadWrite)] - [ActiveIssue("https://github.com/dotnet/runtime/issues/53021", TestPlatforms.Browser)] public void WriteToReadOnlyFile_ReadWrite(MemoryMappedFileAccess access) { WriteToReadOnlyFile(access, access == MemoryMappedFileAccess.Read || @@ -707,7 +706,6 @@ public void WriteToReadOnlyFile_ReadWrite(MemoryMappedFileAccess access) } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/53021", TestPlatforms.Browser)] public void WriteToReadOnlyFile_CopyOnWrite() { WriteToReadOnlyFile(MemoryMappedFileAccess.CopyOnWrite, PlatformDetection.IsSuperUser); From 11d8e2644e0bd2f0e89c2659681b5501efd629bb Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Thu, 16 Jun 2022 17:20:12 -0400 Subject: [PATCH 170/337] Use IndexOf{Any} in a few more places (#70176) * Use IndexOf{Any} in a few more places * Address PR feedback --- .../System.Console/src/System/TermInfo.cs | 5 ++-- .../src/System/IO/FileSystemWatcher.Linux.cs | 11 +++----- .../System/Net/Http/HttpResponseMessage.cs | 14 +--------- .../src/System/Net/Mail/MailBnfHelper.cs | 19 +++---------- .../System/Reflection/Emit/TypeNameBuilder.cs | 11 +++++--- .../TimeZoneInfo.FullGlobalizationData.cs | 27 +++++-------------- 6 files changed, 24 insertions(+), 63 deletions(-) diff --git a/src/libraries/System.Console/src/System/TermInfo.cs b/src/libraries/System.Console/src/System/TermInfo.cs index 173d756e1b60f9..0ac9b5a49afec1 100644 --- a/src/libraries/System.Console/src/System/TermInfo.cs +++ b/src/libraries/System.Console/src/System/TermInfo.cs @@ -498,9 +498,8 @@ private static string ReadString(byte[] buffer, int pos) /// Finds the null-terminator for a string that begins at the specified position. private static int FindNullTerminator(byte[] buffer, int pos) { - int termPos = pos; - while (termPos < buffer.Length && buffer[termPos] != '\0') termPos++; - return termPos; + int i = buffer.AsSpan(pos).IndexOf((byte)'\0'); + return i >= 0 ? pos + i : buffer.Length; } } diff --git a/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.Linux.cs b/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.Linux.cs index 07cb9a9ad4e3b0..9117b90b074574 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.Linux.cs +++ b/src/libraries/System.IO.FileSystem.Watcher/src/System/IO/FileSystemWatcher.Linux.cs @@ -843,16 +843,11 @@ private string ReadName(int position, int nameLength) Debug.Assert(position > 0); Debug.Assert(nameLength >= 0 && (position + nameLength) <= _buffer.Length); - int lengthWithoutNullTerm = nameLength; - for (int i = 0; i < nameLength; i++) + int lengthWithoutNullTerm = _buffer.AsSpan(position, nameLength).IndexOf((byte)'\0'); + if (lengthWithoutNullTerm < 0) { - if (_buffer[position + i] == '\0') - { - lengthWithoutNullTerm = i; - break; - } + lengthWithoutNullTerm = nameLength; } - Debug.Assert(lengthWithoutNullTerm <= nameLength); // should be null terminated or empty return lengthWithoutNullTerm > 0 ? Encoding.UTF8.GetString(_buffer, position, lengthWithoutNullTerm) : diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpResponseMessage.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpResponseMessage.cs index 4dc7a1f2d3b7ba..1256c07c5d96be 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpResponseMessage.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpResponseMessage.cs @@ -92,7 +92,7 @@ public string? ReasonPhrase } set { - if ((value != null) && ContainsNewLineCharacter(value)) + if ((value != null) && HttpRuleParser.ContainsNewLine(value)) { throw new FormatException(SR.net_http_reasonphrase_format_error); } @@ -207,18 +207,6 @@ public override string ToString() return sb.ToString(); } - private static bool ContainsNewLineCharacter(string value) - { - foreach (char character in value) - { - if ((character == HttpRuleParser.CR) || (character == HttpRuleParser.LF)) - { - return true; - } - } - return false; - } - #region IDisposable Members protected virtual void Dispose(bool disposing) diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mail/MailBnfHelper.cs b/src/libraries/System.Net.Mail/src/System/Net/Mail/MailBnfHelper.cs index 49220b21488876..b932fa90f0667c 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mail/MailBnfHelper.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mail/MailBnfHelper.cs @@ -379,23 +379,12 @@ private static bool CheckForUnicode(char ch, bool allowUnicode) return true; } - internal static bool IsAllowedWhiteSpace(char c) - { + internal static bool IsAllowedWhiteSpace(char c) => // all allowed whitespace characters - return c == Tab || c == Space || c == CR || c == LF; - } + c == Tab || c == Space || c == CR || c == LF; - internal static bool HasCROrLF(string data) - { - for (int i = 0; i < data.Length; i++) - { - if (data[i] == '\r' || data[i] == '\n') - { - return true; - } - } - return false; - } + internal static bool HasCROrLF(string data) => + data.AsSpan().IndexOfAny(CR, LF) >= 0; // Is there a FWS ("\r\n " or "\r\n\t") starting at the given index? internal static bool IsFWSAt(string data, int index) diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/TypeNameBuilder.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/TypeNameBuilder.cs index b402b32f7f1ab3..ac5be3901f3b55 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/TypeNameBuilder.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/TypeNameBuilder.cs @@ -246,11 +246,14 @@ private void SetUseAngleBracketsForGenerics(bool value) private void Append(string pStr) { - foreach (char c in pStr) + int i = pStr.IndexOf('\0'); + if (i < 0) { - if (c == '\0') - break; - _str.Append(c); + _str.Append(pStr); + } + else if (i > 0) + { + _str.Append(pStr.AsSpan(0, i)); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.FullGlobalizationData.cs b/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.FullGlobalizationData.cs index eb29e849aeb45e..a885f0a83c9b24 100644 --- a/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.FullGlobalizationData.cs +++ b/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.FullGlobalizationData.cs @@ -9,23 +9,15 @@ public sealed partial class TimeZoneInfo { private static unsafe bool TryConvertIanaIdToWindowsId(string ianaId, bool allocate, out string? windowsId) { - if (GlobalizationMode.Invariant || GlobalizationMode.UseNls || ianaId is null) + if (GlobalizationMode.Invariant || + GlobalizationMode.UseNls || + ianaId is null || + ianaId.AsSpan().IndexOfAny('\\', '\n', '\r') >= 0) // ICU uses these characters as a separator { windowsId = null; return false; } - foreach (char c in ianaId) - { - // ICU uses some characters as a separator and trim the id at that character. - // while we should fail if the Id contained one of these characters. - if (c == '\\' || c == '\n' || c == '\r') - { - windowsId = null; - return false; - } - } - char* buffer = stackalloc char[100]; int length = Interop.Globalization.IanaIdToWindowsId(ianaId, buffer, 100); if (length > 0) @@ -54,15 +46,10 @@ private static unsafe bool TryConvertWindowsIdToIanaId(string windowsId, string? return true; } - foreach (char c in windowsId) + if (windowsId.AsSpan().IndexOfAny('\\', '\n', '\r') >= 0) // ICU uses these characters as a separator { - // ICU uses some characters as a separator and trim the id at that character. - // while we should fail if the Id contained one of these characters. - if (c == '\\' || c == '\n' || c == '\r') - { - ianaId = null; - return false; - } + ianaId = null; + return false; } // regionPtr will point at the region name encoded as ASCII. From 5713beacf9b8191fd2700d274ba3469f9e1c9adc Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Thu, 16 Jun 2022 14:51:46 -0700 Subject: [PATCH 171/337] Fix corerun for assemblies with mismatched filename (#70800) corerun gracefully handled filename not matching the assembly name. Handling of this case regressed in #68186. This change is fixing the regression. Fixes #68455 --- src/coreclr/binder/assemblybindercommon.cpp | 3 ++- src/coreclr/binder/customassemblybinder.cpp | 3 ++- src/coreclr/binder/defaultassemblybinder.cpp | 3 ++- src/coreclr/binder/inc/assemblybindercommon.hpp | 1 + src/coreclr/binder/inc/customassemblybinder.h | 1 + src/coreclr/binder/inc/defaultassemblybinder.h | 1 + src/coreclr/vm/assemblybinder.h | 2 +- src/coreclr/vm/assemblynative.cpp | 4 ++-- src/coreclr/vm/assemblynative.hpp | 2 +- src/coreclr/vm/assemblyspec.cpp | 2 +- 10 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/coreclr/binder/assemblybindercommon.cpp b/src/coreclr/binder/assemblybindercommon.cpp index b3edff82d7cbc5..e23c00dfc25687 100644 --- a/src/coreclr/binder/assemblybindercommon.cpp +++ b/src/coreclr/binder/assemblybindercommon.cpp @@ -1180,6 +1180,7 @@ HRESULT AssemblyBinderCommon::BindUsingHostAssemblyResolver(/* in */ INT_PTR pMa HRESULT AssemblyBinderCommon::BindUsingPEImage(/* in */ AssemblyBinder* pBinder, /* in */ BINDER_SPACE::AssemblyName *pAssemblyName, /* in */ PEImage *pPEImage, + /* in */ bool excludeAppPaths, /* [retval] [out] */ Assembly **ppAssembly) { HRESULT hr = E_FAIL; @@ -1208,7 +1209,7 @@ HRESULT AssemblyBinderCommon::BindUsingPEImage(/* in */ AssemblyBinder* pBinder pAssemblyName, true, // skipFailureCaching true, // skipVersionCompatibilityCheck - false, // excludeAppPaths + excludeAppPaths, // excludeAppPaths &bindResult); if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) diff --git a/src/coreclr/binder/customassemblybinder.cpp b/src/coreclr/binder/customassemblybinder.cpp index 98e0fd25de81b6..02a8d2e918dc79 100644 --- a/src/coreclr/binder/customassemblybinder.cpp +++ b/src/coreclr/binder/customassemblybinder.cpp @@ -102,6 +102,7 @@ Exit:; } HRESULT CustomAssemblyBinder::BindUsingPEImage( /* in */ PEImage *pPEImage, + /* in */ bool excludeAppPaths, /* [retval][out] */ BINDER_SPACE::Assembly **ppAssembly) { HRESULT hr = S_OK; @@ -128,7 +129,7 @@ HRESULT CustomAssemblyBinder::BindUsingPEImage( /* in */ PEImage *pPEImage, IF_FAIL_GO(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)); } - hr = AssemblyBinderCommon::BindUsingPEImage(this, pAssemblyName, pPEImage, &pCoreCLRFoundAssembly); + hr = AssemblyBinderCommon::BindUsingPEImage(this, pAssemblyName, pPEImage, excludeAppPaths, &pCoreCLRFoundAssembly); if (hr == S_OK) { _ASSERTE(pCoreCLRFoundAssembly != NULL); diff --git a/src/coreclr/binder/defaultassemblybinder.cpp b/src/coreclr/binder/defaultassemblybinder.cpp index 28157a11244cd0..2461ca4b1397d6 100644 --- a/src/coreclr/binder/defaultassemblybinder.cpp +++ b/src/coreclr/binder/defaultassemblybinder.cpp @@ -111,6 +111,7 @@ Exit:; #if !defined(DACCESS_COMPILE) HRESULT DefaultAssemblyBinder::BindUsingPEImage( /* in */ PEImage *pPEImage, + /* in */ bool excludeAppPaths, /* [retval][out] */ BINDER_SPACE::Assembly **ppAssembly) { HRESULT hr = S_OK; @@ -157,7 +158,7 @@ HRESULT DefaultAssemblyBinder::BindUsingPEImage( /* in */ PEImage *pPEImage, } } - hr = AssemblyBinderCommon::BindUsingPEImage(this, pAssemblyName, pPEImage, &pCoreCLRFoundAssembly); + hr = AssemblyBinderCommon::BindUsingPEImage(this, pAssemblyName, pPEImage, excludeAppPaths, &pCoreCLRFoundAssembly); if (hr == S_OK) { _ASSERTE(pCoreCLRFoundAssembly != NULL); diff --git a/src/coreclr/binder/inc/assemblybindercommon.hpp b/src/coreclr/binder/inc/assemblybindercommon.hpp index b3b21587159288..3bd529bd9c0a97 100644 --- a/src/coreclr/binder/inc/assemblybindercommon.hpp +++ b/src/coreclr/binder/inc/assemblybindercommon.hpp @@ -56,6 +56,7 @@ namespace BINDER_SPACE static HRESULT BindUsingPEImage(/* in */ AssemblyBinder *pBinder, /* in */ BINDER_SPACE::AssemblyName *pAssemblyName, /* in */ PEImage *pPEImage, + /* in */ bool excludeAppPaths, /* [retval] [out] */ Assembly **ppAssembly); #endif // !defined(DACCESS_COMPILE) diff --git a/src/coreclr/binder/inc/customassemblybinder.h b/src/coreclr/binder/inc/customassemblybinder.h index 9d59832f3c9798..7a89c5033b9e50 100644 --- a/src/coreclr/binder/inc/customassemblybinder.h +++ b/src/coreclr/binder/inc/customassemblybinder.h @@ -18,6 +18,7 @@ class CustomAssemblyBinder final : public AssemblyBinder public: HRESULT BindUsingPEImage(PEImage* pPEImage, + bool excludeAppPaths, BINDER_SPACE::Assembly** ppAssembly) override; HRESULT BindUsingAssemblyName(BINDER_SPACE::AssemblyName* pAssemblyName, diff --git a/src/coreclr/binder/inc/defaultassemblybinder.h b/src/coreclr/binder/inc/defaultassemblybinder.h index 398174c65a078b..3d35854e09f3ff 100644 --- a/src/coreclr/binder/inc/defaultassemblybinder.h +++ b/src/coreclr/binder/inc/defaultassemblybinder.h @@ -16,6 +16,7 @@ class DefaultAssemblyBinder final : public AssemblyBinder public: HRESULT BindUsingPEImage(PEImage* pPEImage, + bool excludeAppPaths, BINDER_SPACE::Assembly** ppAssembly) override; HRESULT BindUsingAssemblyName(BINDER_SPACE::AssemblyName* pAssemblyName, diff --git a/src/coreclr/vm/assemblybinder.h b/src/coreclr/vm/assemblybinder.h index 7137a46309d8c1..259527cf186de3 100644 --- a/src/coreclr/vm/assemblybinder.h +++ b/src/coreclr/vm/assemblybinder.h @@ -19,7 +19,7 @@ class AssemblyBinder public: HRESULT BindAssemblyByName(AssemblyNameData* pAssemblyNameData, BINDER_SPACE::Assembly** ppAssembly); - virtual HRESULT BindUsingPEImage(PEImage* pPEImage, BINDER_SPACE::Assembly** ppAssembly) = 0; + virtual HRESULT BindUsingPEImage(PEImage* pPEImage, bool excludeAppPaths, BINDER_SPACE::Assembly** ppAssembly) = 0; virtual HRESULT BindUsingAssemblyName(BINDER_SPACE::AssemblyName* pAssemblyName, BINDER_SPACE::Assembly** ppAssembly) = 0; /// diff --git a/src/coreclr/vm/assemblynative.cpp b/src/coreclr/vm/assemblynative.cpp index a0879b0290c0fa..cd0222b96b953e 100644 --- a/src/coreclr/vm/assemblynative.cpp +++ b/src/coreclr/vm/assemblynative.cpp @@ -124,7 +124,7 @@ extern "C" void QCALLTYPE AssemblyNative_InternalLoad(NativeAssemblyNameParts* p } /* static */ -Assembly* AssemblyNative::LoadFromPEImage(AssemblyBinder* pBinder, PEImage *pImage) +Assembly* AssemblyNative::LoadFromPEImage(AssemblyBinder* pBinder, PEImage *pImage, bool excludeAppPaths) { CONTRACT(Assembly*) { @@ -152,7 +152,7 @@ Assembly* AssemblyNative::LoadFromPEImage(AssemblyBinder* pBinder, PEImage *pIma HRESULT hr = S_OK; PTR_AppDomain pCurDomain = GetAppDomain(); - hr = pBinder->BindUsingPEImage(pImage, &pAssembly); + hr = pBinder->BindUsingPEImage(pImage, excludeAppPaths, &pAssembly); if (hr != S_OK) { diff --git a/src/coreclr/vm/assemblynative.hpp b/src/coreclr/vm/assemblynative.hpp index bbff58bb6a9b10..944c327fb6693e 100644 --- a/src/coreclr/vm/assemblynative.hpp +++ b/src/coreclr/vm/assemblynative.hpp @@ -25,7 +25,7 @@ class AssemblyNative public: - static Assembly* LoadFromPEImage(AssemblyBinder* pBinder, PEImage *pImage); + static Assembly* LoadFromPEImage(AssemblyBinder* pBinder, PEImage *pImage, bool excludeAppPaths = false); // static FCALLs static FCDECL0(FC_BOOL_RET, IsTracingEnabled); diff --git a/src/coreclr/vm/assemblyspec.cpp b/src/coreclr/vm/assemblyspec.cpp index 14ad9e680b122f..2270d62c803926 100644 --- a/src/coreclr/vm/assemblyspec.cpp +++ b/src/coreclr/vm/assemblyspec.cpp @@ -503,7 +503,7 @@ Assembly *AssemblySpec::LoadAssembly(LPCWSTR pFilePath) if (!pILImage->CheckILFormat()) THROW_BAD_FORMAT(BFA_BAD_IL, pILImage.GetValue()); - RETURN AssemblyNative::LoadFromPEImage(AppDomain::GetCurrentDomain()->GetDefaultBinder(), pILImage); + RETURN AssemblyNative::LoadFromPEImage(AppDomain::GetCurrentDomain()->GetDefaultBinder(), pILImage, true /* excludeAppPaths */); } HRESULT AssemblySpec::CheckFriendAssemblyName() From 36f2dc251ff2d47b571a0964b76177cdca79724e Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Thu, 16 Jun 2022 18:20:28 -0400 Subject: [PATCH 172/337] Fix a few Stream-related issues in System.Net.Http (#70731) * Fix a few Stream-related issues in System.Net.Http * Put back WriteTimeout * Fix tests --- .../Common/src/System/IO/DelegatingStream.cs | 15 +- .../src/System/IO/ReadOnlyMemoryStream.cs | 14 +- .../System/IO/StreamConformanceTests.cs | 18 +- .../src/System/Net/Http/MultipartContent.cs | 8 + .../src/System/Net/Http/StreamContent.cs | 52 ++-- .../ReadOnlyMemoryContentTest.cs | 237 +++++++++--------- .../FunctionalTests/StreamContentTest.cs | 103 +------- 7 files changed, 183 insertions(+), 264 deletions(-) diff --git a/src/libraries/Common/src/System/IO/DelegatingStream.cs b/src/libraries/Common/src/System/IO/DelegatingStream.cs index 316d81d43f058c..96d7b360cbfa76 100644 --- a/src/libraries/Common/src/System/IO/DelegatingStream.cs +++ b/src/libraries/Common/src/System/IO/DelegatingStream.cs @@ -122,6 +122,16 @@ public override int EndRead(IAsyncResult asyncResult) return _innerStream.EndRead(asyncResult); } + public override void CopyTo(Stream destination, int bufferSize) + { + _innerStream.CopyTo(destination, bufferSize); + } + + public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken) + { + return _innerStream.CopyToAsync(destination, bufferSize, cancellationToken); + } + #endregion Read #region Write @@ -175,11 +185,6 @@ public override void EndWrite(IAsyncResult asyncResult) { _innerStream.EndWrite(asyncResult); } - - public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken) - { - return _innerStream.CopyToAsync(destination, bufferSize, cancellationToken); - } #endregion Write } } diff --git a/src/libraries/Common/src/System/IO/ReadOnlyMemoryStream.cs b/src/libraries/Common/src/System/IO/ReadOnlyMemoryStream.cs index 5e2ecc2cf50b58..5e73fd57dda0d1 100644 --- a/src/libraries/Common/src/System/IO/ReadOnlyMemoryStream.cs +++ b/src/libraries/Common/src/System/IO/ReadOnlyMemoryStream.cs @@ -159,6 +159,7 @@ public override void CopyTo(Stream destination, int bufferSize) if (_content.Length > _position) { destination.Write(_content.Span.Slice(_position)); + _position = _content.Length; } } @@ -166,9 +167,16 @@ public override Task CopyToAsync(Stream destination, int bufferSize, Cancellatio { ValidateCopyToArguments(destination, bufferSize); EnsureNotClosed(); - return _content.Length > _position ? - destination.WriteAsync(_content.Slice(_position), cancellationToken).AsTask() : - Task.CompletedTask; + if (_content.Length > _position) + { + ReadOnlyMemory content = _content.Slice(_position); + _position = _content.Length; + return destination.WriteAsync(content, cancellationToken).AsTask(); + } + else + { + return Task.CompletedTask; + } } #endif diff --git a/src/libraries/Common/tests/StreamConformanceTests/System/IO/StreamConformanceTests.cs b/src/libraries/Common/tests/StreamConformanceTests/System/IO/StreamConformanceTests.cs index 1086ffeed62a04..d8479fcf84465f 100644 --- a/src/libraries/Common/tests/StreamConformanceTests/System/IO/StreamConformanceTests.cs +++ b/src/libraries/Common/tests/StreamConformanceTests/System/IO/StreamConformanceTests.cs @@ -399,10 +399,17 @@ protected async Task ValidateMisuseExceptionsAsync(Stream stream) Assert.Throws(() => { stream.Seek(-1, SeekOrigin.Begin); }); Assert.Throws(() => { stream.Seek(-stream.Position - 1, SeekOrigin.Current); }); Assert.Throws(() => { stream.Seek(-stream.Length - 1, SeekOrigin.End); }); - Assert.Throws(() => { stream.Seek(0, (SeekOrigin)(-1)); }); - Assert.Throws(() => { stream.Seek(0, (SeekOrigin)3); }); - Assert.Throws(() => { stream.Seek(0, ~SeekOrigin.Begin); }); - Assert.Throws(() => { stream.SetLength(-1); }); + Assert.ThrowsAny(() => { stream.Seek(0, (SeekOrigin)(-1)); }); + Assert.ThrowsAny(() => { stream.Seek(0, (SeekOrigin)3); }); + Assert.ThrowsAny(() => { stream.Seek(0, ~SeekOrigin.Begin); }); + if (CanSetLength) + { + Assert.Throws(() => { stream.SetLength(-1); }); + } + else + { + Assert.Throws(() => { stream.SetLength(0); }); + } } else { @@ -616,10 +623,11 @@ protected sealed unsafe class NativeMemoryManager : MemoryManager private readonly int _length; private IntPtr _ptr; public int PinRefCount; + private readonly string _ctorStack = Environment.StackTrace; public NativeMemoryManager(int length) => _ptr = Marshal.AllocHGlobal(_length = length); - ~NativeMemoryManager() => Assert.False(true, $"{nameof(NativeMemoryManager)} being finalized"); + ~NativeMemoryManager() => Assert.False(true, $"{nameof(NativeMemoryManager)} being finalized. Created at {_ctorStack}"); public override Memory Memory => CreateMemory(_length); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/MultipartContent.cs b/src/libraries/System.Net.Http/src/System/Net/Http/MultipartContent.cs index 863d7ab9ec3dc4..e82af6762b9c8b 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/MultipartContent.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/MultipartContent.cs @@ -490,6 +490,12 @@ public override int Read(byte[] buffer, int offset, int count) } } + public override int ReadByte() + { + Span buffer = stackalloc byte[1]; + return Read(buffer) == 1 ? buffer[0] : -1; + } + public override int Read(Span buffer) { if (buffer.Length == 0) @@ -632,6 +638,8 @@ public override long Seek(long offset, SeekOrigin origin) public override long Length => _length; public override void Flush() { } + public override Task FlushAsync(CancellationToken cancellationToken) => Task.CompletedTask; + public override void SetLength(long value) { throw new NotSupportedException(); } public override void Write(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } public override void Write(ReadOnlySpan buffer) { throw new NotSupportedException(); } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/StreamContent.cs b/src/libraries/System.Net.Http/src/System/Net/Http/StreamContent.cs index 8be52a024a95b7..c5d0366690fd65 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/StreamContent.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/StreamContent.cs @@ -138,60 +138,44 @@ private void PrepareContent() private sealed class ReadOnlyStream : DelegatingStream { - public override bool CanWrite + public ReadOnlyStream(Stream innerStream) : base(innerStream) { - get { return false; } } - public override int WriteTimeout - { - get { throw new NotSupportedException(SR.net_http_content_readonly_stream); } - set { throw new NotSupportedException(SR.net_http_content_readonly_stream); } - } + public override bool CanWrite => false; - public ReadOnlyStream(Stream innerStream) - : base(innerStream) - { - } + public override void Flush() { } - public override void Flush() - { + public override Task FlushAsync(CancellationToken cancellationToken) => Task.CompletedTask; + + public override void SetLength(long value) => throw new NotSupportedException(SR.net_http_content_readonly_stream); - } - public override Task FlushAsync(CancellationToken cancellationToken) - { + public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback? callback, object? state) => throw new NotSupportedException(SR.net_http_content_readonly_stream); - } - public override void SetLength(long value) - { + public override void EndWrite(IAsyncResult asyncResult) => throw new NotSupportedException(SR.net_http_content_readonly_stream); - } - public override void Write(byte[] buffer, int offset, int count) - { + public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException(SR.net_http_content_readonly_stream); - } - public override void Write(ReadOnlySpan buffer) - { + public override void Write(ReadOnlySpan buffer) => throw new NotSupportedException(SR.net_http_content_readonly_stream); - } - public override void WriteByte(byte value) - { + public override void WriteByte(byte value) => throw new NotSupportedException(SR.net_http_content_readonly_stream); - } - public override Task WriteAsync(byte[] buffer, int offset, int count, Threading.CancellationToken cancellationToken) - { + public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) => throw new NotSupportedException(SR.net_http_content_readonly_stream); - } - public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) - { + public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) => throw new NotSupportedException(SR.net_http_content_readonly_stream); + + public override int WriteTimeout + { + get => throw new InvalidOperationException(SR.net_http_content_readonly_stream); + set => throw new InvalidOperationException(SR.net_http_content_readonly_stream); } } } diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/ReadOnlyMemoryContentTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/ReadOnlyMemoryContentTest.cs index dd6edac95f0c9e..df9b4d7c08662a 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/ReadOnlyMemoryContentTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/ReadOnlyMemoryContentTest.cs @@ -4,14 +4,20 @@ using System.Buffers; using System.Collections.Generic; using System.IO; +using System.IO.Tests; using System.Threading; using System.Threading.Tasks; using Xunit; namespace System.Net.Http.Functional.Tests { - public class ReadOnlyMemoryContentTest + public class ReadOnlyMemoryContentTest : StandaloneStreamConformanceTests { + protected override Task CreateReadOnlyStreamCore(byte[]? initialData) => new ReadOnlyMemoryContent(initialData).ReadAsStreamAsync(); + protected override Task CreateWriteOnlyStreamCore(byte[]? initialData) => Task.FromResult(null); + protected override Task CreateReadWriteStreamCore(byte[]? initialData) => Task.FromResult(null); + protected override bool CanSetLength => false; + public static IEnumerable ContentLengthsAndUseArrays() { foreach (int length in new[] { 0, 1, 4096 }) @@ -55,8 +61,8 @@ public static IEnumerable UseArraysAndReadStreamAsync() [MemberData(nameof(ContentLengthsAndUseArrays))] public void ContentLength_LengthMatchesArrayLength(int contentLength, bool useArray) { - Memory memory; - using (ReadOnlyMemoryContent content = CreateContent(contentLength, useArray, out memory, out IMemoryOwner memoryOwner)) + using (ReadOnlyMemoryContent content = CreateContent(contentLength, useArray, out _, out IMemoryOwner memoryOwner)) + using (memoryOwner) { Assert.Equal(contentLength, content.Headers.ContentLength); } @@ -67,32 +73,30 @@ public void ContentLength_LengthMatchesArrayLength(int contentLength, bool useAr public async Task ReadAsStreamAsync_TrivialMembersHaveExpectedValuesAndBehavior(bool useArray, bool readStreamAsync) { const int ContentLength = 42; - Memory memory; - - using (ReadOnlyMemoryContent content = CreateContent(ContentLength, useArray, out memory, out IMemoryOwner memoryOwner)) + + using (ReadOnlyMemoryContent content = CreateContent(ContentLength, useArray, out Memory memory, out IMemoryOwner memoryOwner)) + using (memoryOwner) + using (Stream stream = await content.ReadAsStreamAsync(readStreamAsync)) { - using (Stream stream = await content.ReadAsStreamAsync(readStreamAsync)) - { - // property values - Assert.Equal(ContentLength, stream.Length); - Assert.Equal(0, stream.Position); - Assert.True(stream.CanRead); - Assert.True(stream.CanSeek); - Assert.False(stream.CanWrite); - - // not supported - Assert.Throws(() => stream.SetLength(12345)); - Assert.Throws(() => stream.WriteByte(0)); - Assert.Throws(() => stream.Write(new byte[1], 0, 1)); - Assert.Throws(() => stream.Write(new ReadOnlySpan(new byte[1]))); - await Assert.ThrowsAsync(async () => await stream.WriteAsync(new byte[1], 0, 1)); - await Assert.ThrowsAsync(async () => await stream.WriteAsync(new ReadOnlyMemory(new byte[1]))); - - // nops - stream.Flush(); - await stream.FlushAsync(); - } + // property values + Assert.Equal(ContentLength, stream.Length); + Assert.Equal(0, stream.Position); + Assert.True(stream.CanRead); + Assert.True(stream.CanSeek); + Assert.False(stream.CanWrite); + + // not supported + Assert.Throws(() => stream.SetLength(12345)); + Assert.Throws(() => stream.WriteByte(0)); + Assert.Throws(() => stream.Write(new byte[1], 0, 1)); + Assert.Throws(() => stream.Write(new ReadOnlySpan(new byte[1]))); + await Assert.ThrowsAsync(async () => await stream.WriteAsync(new byte[1], 0, 1)); + await Assert.ThrowsAsync(async () => await stream.WriteAsync(new ReadOnlyMemory(new byte[1]))); + + // nops + stream.Flush(); + await stream.FlushAsync(); } } @@ -101,61 +105,59 @@ public async Task ReadAsStreamAsync_TrivialMembersHaveExpectedValuesAndBehavior( public async Task ReadAsStreamAsync_Seek(bool useArray, bool readStreamAsync) { const int ContentLength = 42; - Memory memory; - - using (ReadOnlyMemoryContent content = CreateContent(ContentLength, useArray, out memory, out IMemoryOwner memoryOwner)) + + using (ReadOnlyMemoryContent content = CreateContent(ContentLength, useArray, out Memory memory, out IMemoryOwner memoryOwner)) + using (memoryOwner) + using (Stream s = await content.ReadAsStreamAsync(readStreamAsync)) { - using (Stream s = await content.ReadAsStreamAsync(readStreamAsync)) + foreach (int pos in new[] { 0, ContentLength / 2, ContentLength - 1 }) { - foreach (int pos in new[] { 0, ContentLength / 2, ContentLength - 1 }) - { - s.Position = pos; - Assert.Equal(pos, s.Position); - Assert.Equal(memory.Span[pos], s.ReadByte()); - } - - foreach (int pos in new[] { 0, ContentLength / 2, ContentLength - 1 }) - { - Assert.Equal(0, s.Seek(0, SeekOrigin.Begin)); - Assert.Equal(memory.Span[0], s.ReadByte()); - } - - Assert.Equal(ContentLength, s.Seek(0, SeekOrigin.End)); - Assert.Equal(s.Position, s.Length); - Assert.Equal(-1, s.ReadByte()); + s.Position = pos; + Assert.Equal(pos, s.Position); + Assert.Equal(memory.Span[pos], s.ReadByte()); + } - Assert.Equal(0, s.Seek(-ContentLength, SeekOrigin.End)); - Assert.Equal(0, s.Position); + foreach (int pos in new[] { 0, ContentLength / 2, ContentLength - 1 }) + { + Assert.Equal(0, s.Seek(0, SeekOrigin.Begin)); Assert.Equal(memory.Span[0], s.ReadByte()); - - s.Position = 0; - Assert.Equal(0, s.Seek(0, SeekOrigin.Current)); - Assert.Equal(0, s.Position); - - Assert.Equal(1, s.Seek(1, SeekOrigin.Current)); - Assert.Equal(1, s.Position); - Assert.Equal(memory.Span[1], s.ReadByte()); - Assert.Equal(2, s.Position); - Assert.Equal(3, s.Seek(1, SeekOrigin.Current)); - Assert.Equal(1, s.Seek(-2, SeekOrigin.Current)); - - Assert.Equal(int.MaxValue, s.Seek(int.MaxValue, SeekOrigin.Begin)); - Assert.Equal(int.MaxValue, s.Position); - Assert.Equal(int.MaxValue, s.Seek(0, SeekOrigin.Current)); - Assert.Equal(int.MaxValue, s.Position); - Assert.Equal(int.MaxValue, s.Seek(int.MaxValue - ContentLength, SeekOrigin.End)); - Assert.Equal(int.MaxValue, s.Position); - Assert.Equal(-1, s.ReadByte()); - Assert.Equal(int.MaxValue, s.Position); - - Assert.Throws("value", () => s.Position = -1); - Assert.Throws(() => s.Seek(-1, SeekOrigin.Begin)); - - AssertExtensions.Throws("value", () => s.Position = (long)int.MaxValue + 1); - AssertExtensions.Throws("offset", () => s.Seek((long)int.MaxValue + 1, SeekOrigin.Begin)); - - Assert.ThrowsAny(() => s.Seek(0, (SeekOrigin)42)); } + + Assert.Equal(ContentLength, s.Seek(0, SeekOrigin.End)); + Assert.Equal(s.Position, s.Length); + Assert.Equal(-1, s.ReadByte()); + + Assert.Equal(0, s.Seek(-ContentLength, SeekOrigin.End)); + Assert.Equal(0, s.Position); + Assert.Equal(memory.Span[0], s.ReadByte()); + + s.Position = 0; + Assert.Equal(0, s.Seek(0, SeekOrigin.Current)); + Assert.Equal(0, s.Position); + + Assert.Equal(1, s.Seek(1, SeekOrigin.Current)); + Assert.Equal(1, s.Position); + Assert.Equal(memory.Span[1], s.ReadByte()); + Assert.Equal(2, s.Position); + Assert.Equal(3, s.Seek(1, SeekOrigin.Current)); + Assert.Equal(1, s.Seek(-2, SeekOrigin.Current)); + + Assert.Equal(int.MaxValue, s.Seek(int.MaxValue, SeekOrigin.Begin)); + Assert.Equal(int.MaxValue, s.Position); + Assert.Equal(int.MaxValue, s.Seek(0, SeekOrigin.Current)); + Assert.Equal(int.MaxValue, s.Position); + Assert.Equal(int.MaxValue, s.Seek(int.MaxValue - ContentLength, SeekOrigin.End)); + Assert.Equal(int.MaxValue, s.Position); + Assert.Equal(-1, s.ReadByte()); + Assert.Equal(int.MaxValue, s.Position); + + Assert.Throws("value", () => s.Position = -1); + Assert.Throws(() => s.Seek(-1, SeekOrigin.Begin)); + + AssertExtensions.Throws("value", () => s.Position = (long)int.MaxValue + 1); + AssertExtensions.Throws("offset", () => s.Seek((long)int.MaxValue + 1, SeekOrigin.Begin)); + + Assert.ThrowsAny(() => s.Seek(0, (SeekOrigin)42)); } } @@ -163,20 +165,17 @@ public async Task ReadAsStreamAsync_Seek(bool useArray, bool readStreamAsync) [MemberData(nameof(ContentLengthsAndUseArraysAndReadStreamAsync))] public async Task ReadAsStreamAsync_ReadByte_MatchesInput(int contentLength, bool useArray, bool readStreamAsync) { - Memory memory; - - using (ReadOnlyMemoryContent content = CreateContent(contentLength, useArray, out memory, out IMemoryOwner memoryOwner)) + using (ReadOnlyMemoryContent content = CreateContent(contentLength, useArray, out Memory memory, out IMemoryOwner memoryOwner)) + using (memoryOwner) + using (Stream stream = await content.ReadAsStreamAsync(readStreamAsync)) { - using (Stream stream = await content.ReadAsStreamAsync(readStreamAsync)) + for (int i = 0; i < contentLength; i++) { - for (int i = 0; i < contentLength; i++) - { - Assert.Equal(memory.Span[i], stream.ReadByte()); - Assert.Equal(i + 1, stream.Position); - } - Assert.Equal(-1, stream.ReadByte()); - Assert.Equal(stream.Length, stream.Position); + Assert.Equal(memory.Span[i], stream.ReadByte()); + Assert.Equal(i + 1, stream.Position); } + Assert.Equal(-1, stream.ReadByte()); + Assert.Equal(stream.Length, stream.Position); } } @@ -185,26 +184,24 @@ public async Task ReadAsStreamAsync_ReadByte_MatchesInput(int contentLength, boo public async Task ReadAsStreamAsync_Read_InvalidArguments(bool useArray, bool readStreamAsync) { const int ContentLength = 42; - Memory memory; - - using (ReadOnlyMemoryContent content = CreateContent(ContentLength, useArray, out memory, out IMemoryOwner memoryOwner)) + + using (ReadOnlyMemoryContent content = CreateContent(ContentLength, useArray, out Memory memory, out IMemoryOwner memoryOwner)) + using (memoryOwner) + using (Stream stream = await content.ReadAsStreamAsync(readStreamAsync)) { - using (Stream stream = await content.ReadAsStreamAsync(readStreamAsync)) - { - AssertExtensions.Throws("buffer", () => stream.Read(null, 0, 0)); - AssertExtensions.Throws("buffer", () => { stream.ReadAsync(null, 0, 0); }); + AssertExtensions.Throws("buffer", () => stream.Read(null, 0, 0)); + AssertExtensions.Throws("buffer", () => { stream.ReadAsync(null, 0, 0); }); - AssertExtensions.Throws("offset", () => stream.Read(new byte[1], -1, 1)); - AssertExtensions.Throws("offset", () => stream.Read(new byte[1], -1, 1)); + AssertExtensions.Throws("offset", () => stream.Read(new byte[1], -1, 1)); + AssertExtensions.Throws("offset", () => stream.Read(new byte[1], -1, 1)); - AssertExtensions.Throws("count", () => stream.Read(new byte[1], 0, -1)); - AssertExtensions.Throws("count", () => stream.Read(new byte[1], 0, -1)); + AssertExtensions.Throws("count", () => stream.Read(new byte[1], 0, -1)); + AssertExtensions.Throws("count", () => stream.Read(new byte[1], 0, -1)); - Assert.ThrowsAny(() => { stream.ReadAsync(new byte[1], 2, 0); }); - Assert.ThrowsAny(() => { stream.ReadAsync(new byte[1], 2, 0); }); - Assert.ThrowsAny(() => { stream.ReadAsync(new byte[1], 0, 2); }); - Assert.ThrowsAny(() => { stream.ReadAsync(new byte[1], 0, 2); }); - } + Assert.ThrowsAny(() => { stream.ReadAsync(new byte[1], 2, 0); }); + Assert.ThrowsAny(() => { stream.ReadAsync(new byte[1], 2, 0); }); + Assert.ThrowsAny(() => { stream.ReadAsync(new byte[1], 0, 2); }); + Assert.ThrowsAny(() => { stream.ReadAsync(new byte[1], 0, 2); }); } } @@ -233,8 +230,8 @@ public async Task ReadAsStreamAsync_ReadMultipleBytes_MatchesInput(int mode, boo { const int ContentLength = 1024; - Memory memory; - using (ReadOnlyMemoryContent content = CreateContent(ContentLength, useArray, out memory, out IMemoryOwner memoryOwner)) + using (ReadOnlyMemoryContent content = CreateContent(ContentLength, useArray, out Memory memory, out IMemoryOwner memoryOwner)) + using (memoryOwner) { var buffer = new byte[3]; @@ -274,8 +271,8 @@ public async Task ReadAsStreamAsync_ReadWithCancelableToken_MatchesInput(bool us { const int ContentLength = 100; - Memory memory; - using (ReadOnlyMemoryContent content = CreateContent(ContentLength, useArray, out memory, out IMemoryOwner memoryOwner)) + using (ReadOnlyMemoryContent content = CreateContent(ContentLength, useArray, out Memory memory, out IMemoryOwner memoryOwner)) + using (memoryOwner) { var buffer = new byte[1]; var cts = new CancellationTokenSource(); @@ -307,9 +304,8 @@ public async Task ReadAsStreamAsync_ReadWithCanceledToken_MatchesInput(bool useA { const int ContentLength = 2; - Memory memory; - - using (ReadOnlyMemoryContent content = CreateContent(ContentLength, useArray, out memory, out IMemoryOwner memoryOwner)) + using (ReadOnlyMemoryContent content = CreateContent(ContentLength, useArray, out Memory memory, out IMemoryOwner memoryOwner)) + using (memoryOwner) { using (Stream stream = await content.ReadAsStreamAsync(readStreamAsync)) { @@ -324,10 +320,9 @@ public async Task ReadAsStreamAsync_ReadWithCanceledToken_MatchesInput(bool useA [MemberData(nameof(ContentLengthsAndUseArrays))] public async Task CopyToAsync_AllContentCopied(int contentLength, bool useArray) { - Memory memory; - using (ReadOnlyMemoryContent content = CreateContent(contentLength, useArray, out memory, out IMemoryOwner memoryOwner)) + using (ReadOnlyMemoryContent content = CreateContent(contentLength, useArray, out Memory memory, out IMemoryOwner memoryOwner)) + using (memoryOwner) { - var destination = new MemoryStream(); await content.CopyToAsync(destination); @@ -339,10 +334,9 @@ public async Task CopyToAsync_AllContentCopied(int contentLength, bool useArray) [MemberData(nameof(ContentLengthsAndUseArraysAndReadStreamAsync))] public async Task ReadAsStreamAsync_CopyTo_AllContentCopied(int contentLength, bool useArray, bool readStreamAsync) { - Memory memory; - using (ReadOnlyMemoryContent content = CreateContent(contentLength, useArray, out memory, out IMemoryOwner memoryOwner)) + using (ReadOnlyMemoryContent content = CreateContent(contentLength, useArray, out Memory memory, out IMemoryOwner memoryOwner)) + using (memoryOwner) { - var destination = new MemoryStream(); using (Stream s = await content.ReadAsStreamAsync(readStreamAsync)) { @@ -358,8 +352,8 @@ public async Task ReadAsStreamAsync_CopyTo_AllContentCopied(int contentLength, b public async Task ReadAsStreamAsync_CopyTo_InvalidArguments(bool useArray, bool readStreamAsync) { const int ContentLength = 42; - Memory memory; - using (ReadOnlyMemoryContent content = CreateContent(ContentLength, useArray, out memory, out IMemoryOwner memoryOwner)) + using (ReadOnlyMemoryContent content = CreateContent(ContentLength, useArray, out Memory memory, out IMemoryOwner memoryOwner)) + using (memoryOwner) { using (Stream s = await content.ReadAsStreamAsync(readStreamAsync)) { @@ -384,10 +378,9 @@ public async Task ReadAsStreamAsync_CopyTo_InvalidArguments(bool useArray, bool [MemberData(nameof(ContentLengthsAndUseArraysAndReadStreamAsync))] public async Task ReadAsStreamAsync_CopyToAsync_AllContentCopied(int contentLength, bool useArray, bool readStreamAsync) { - Memory memory; - using (ReadOnlyMemoryContent content = CreateContent(contentLength, useArray, out memory, out IMemoryOwner memoryOwner)) + using (ReadOnlyMemoryContent content = CreateContent(contentLength, useArray, out Memory memory, out IMemoryOwner memoryOwner)) + using (memoryOwner) { - var destination = new MemoryStream(); using (Stream s = await content.ReadAsStreamAsync(readStreamAsync)) { diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/StreamContentTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/StreamContentTest.cs index 464378cf61228f..9d432aea93eef1 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/StreamContentTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/StreamContentTest.cs @@ -3,6 +3,7 @@ using System; using System.IO; +using System.IO.Tests; using System.Threading.Tasks; using Xunit; @@ -10,31 +11,19 @@ namespace System.Net.Http.Functional.Tests { - public class StreamContentTest + public class StreamContentTest : StandaloneStreamConformanceTests { - private readonly ITestOutputHelper _output; - - public StreamContentTest(ITestOutputHelper output) - { - _output = output; - } + protected override Task CreateReadOnlyStreamCore(byte[]? initialData) => initialData is null ? Task.FromResult(null) : new StreamContent(new MemoryStream(initialData)).ReadAsStreamAsync(); + protected override Task CreateWriteOnlyStreamCore(byte[]? initialData) => Task.FromResult(null); + protected override Task CreateReadWriteStreamCore(byte[]? initialData) => Task.FromResult(null); + protected override bool CanSetLength => false; [Fact] - public void Ctor_NullStream_ThrowsArgumentNullException() + public void Ctor_InvalidArguments_Throws() { Assert.Throws(() => new StreamContent(null)); - } - - [Fact] - public void Ctor_ZeroBufferSize_ThrowsArgumentOutOfRangeException() - { - Assert.Throws(() => new StreamContent(new MemoryStream(), 0)); - } - - [Fact] - public void Ctor_NullStreamAndZeroBufferSize_ThrowsArgumentNullException() - { Assert.Throws(() => new StreamContent(null, 0)); + Assert.Throws(() => new StreamContent(new MemoryStream(), 0)); } [Fact] @@ -207,80 +196,6 @@ public async Task ContentReadStream_GetPropertyPartiallyConsumed_ReturnOriginalS Assert.NotSame(source, stream); } - [Theory] - [InlineData(true)] - [InlineData(false)] - public async Task ContentReadStream_CheckResultProperties_ValuesRepresentReadOnlyStream(bool readStreamAsync) - { - byte[] data = new byte[10]; - for (int i = 0; i < data.Length; i++) - { - data[i] = (byte)i; - } - - var source = new MockStream(data); - - var content = new StreamContent(source); - Stream contentReadStream = await content.ReadAsStreamAsync(readStreamAsync); - - // The following checks verify that the stream returned passes all read-related properties to the - // underlying MockStream and throws when using write-related members. - - Assert.False(contentReadStream.CanWrite); - Assert.True(contentReadStream.CanRead); - Assert.Equal(source.Length, contentReadStream.Length); - - Assert.Equal(1, source.CanSeekCount); - _output.WriteLine(contentReadStream.CanSeek.ToString()); - Assert.Equal(2, source.CanSeekCount); - - contentReadStream.Position = 3; // No exception. - Assert.Equal(3, contentReadStream.Position); - - byte byteOnIndex3 = (byte)contentReadStream.ReadByte(); - Assert.Equal(data[3], byteOnIndex3); - - byte[] byteOnIndex4 = new byte[1]; - int result = await contentReadStream.ReadAsync(byteOnIndex4, 0, 1); - Assert.Equal(1, result); - - Assert.Equal(data[4], byteOnIndex4[0]); - - byte[] byteOnIndex5 = new byte[1]; - Assert.Equal(1, contentReadStream.Read(byteOnIndex5, 0, 1)); - Assert.Equal(data[5], byteOnIndex5[0]); - - byte[] byteOnIndex6 = new byte[1]; - Assert.Equal(1, contentReadStream.Read(new Span(byteOnIndex6, 0, 1))); - Assert.Equal(data[6], byteOnIndex6[0]); - - contentReadStream.ReadTimeout = 123; - Assert.Equal(123, source.ReadTimeout); - Assert.Equal(123, contentReadStream.ReadTimeout); - - Assert.Equal(0, source.CanTimeoutCount); - _output.WriteLine(contentReadStream.CanTimeout.ToString()); - Assert.Equal(1, source.CanTimeoutCount); - - Assert.Equal(0, source.SeekCount); - contentReadStream.Seek(0, SeekOrigin.Begin); - Assert.Equal(1, source.SeekCount); - - Assert.Throws(() => { contentReadStream.WriteTimeout = 5; }); - Assert.Throws(() => contentReadStream.WriteTimeout.ToString()); - Assert.Throws(() => contentReadStream.Flush()); - Assert.Throws(() => contentReadStream.SetLength(1)); - Assert.Throws(() => contentReadStream.Write(null, 0, 0)); - Assert.Throws(() => contentReadStream.Write(new Span(Array.Empty()))); - Assert.Throws(() => contentReadStream.WriteByte(1)); - - Assert.Equal(0, source.DisposeCount); - contentReadStream.Dispose(); - Assert.Equal(1, source.DisposeCount); - } - - #region Helper methods - private class MockStream : MemoryStream { private bool _canSeek; @@ -362,7 +277,5 @@ private void SetBufferSize(int count) } } } - - #endregion } } From 795a0f78e0e979777e123f988465939f9295a887 Mon Sep 17 00:00:00 2001 From: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> Date: Fri, 17 Jun 2022 01:45:33 +0300 Subject: [PATCH 173/337] Catch (more) mismatched args in `fgMorphArgs` (#70846) * Catch (more) mismatched args in "fgMorphArgs" * Add a test --- src/coreclr/jit/morph.cpp | 17 ++++++++- .../Directed/StructABI/TypeMismatchedArgs.cs | 36 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 9146eb5db1ba47..75dd52657e6dc8 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -3399,13 +3399,28 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call) makeOutArgCopy = true; } } - else if (genTypeSize(varDsc->TypeGet()) != genTypeSize(structBaseType)) + else if (genTypeSize(varDsc) != genTypeSize(structBaseType)) { // Not a promoted struct, so just swizzle the type by using GT_LCL_FLD lvaSetVarDoNotEnregister(lclNum DEBUGARG(DoNotEnregisterReason::SwizzleArg)); argObj->ChangeOper(GT_LCL_FLD); argObj->gtType = structBaseType; } + else if (varTypeUsesFloatReg(varDsc) != varTypeUsesFloatReg(structBaseType)) + { + // Here we can see int <-> float, long <-> double, long <-> simd8 mismatches, due + // to the "OBJ(ADDR(LCL))" => "LCL" folding above. The latter case is handled in + // lowering, others we will handle here via swizzling. + CLANG_FORMAT_COMMENT_ANCHOR; +#ifdef TARGET_AMD64 + if (varDsc->TypeGet() != TYP_SIMD8) +#endif // TARGET_AMD64 + { + lvaSetVarDoNotEnregister(lclNum DEBUGARG(DoNotEnregisterReason::SwizzleArg)); + argObj->ChangeOper(GT_LCL_FLD); + argObj->gtType = structBaseType; + } + } } else if (argObj->OperIs(GT_LCL_FLD, GT_IND)) { diff --git a/src/tests/JIT/Directed/StructABI/TypeMismatchedArgs.cs b/src/tests/JIT/Directed/StructABI/TypeMismatchedArgs.cs index c450040daace48..8850934b2159d5 100644 --- a/src/tests/JIT/Directed/StructABI/TypeMismatchedArgs.cs +++ b/src/tests/JIT/Directed/StructABI/TypeMismatchedArgs.cs @@ -41,6 +41,11 @@ public static int Main() return 105; } + if (ProblemWithRegFileMismatch_Win_x64(12, 13)) + { + return 106; + } + return 100; } @@ -86,6 +91,21 @@ private static bool ProblemWithVectorCallArg() return result != s_vtor128.Vtor4.X; } + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool ProblemWithRegFileMismatch_Win_x64(double dbl, float flt) + { + if (CallForDblStruct(*(DblStruct*)&dbl) != dbl) + { + return true; + } + if (CallForFltStruct(*(FltStruct*)&flt) != flt) + { + return true; + } + + return false; + } + [MethodImpl(MethodImplOptions.NoInlining)] private static float CallForVector4(Vector4 value) => value.X; @@ -97,6 +117,12 @@ private static bool ProblemWithVectorCallArg() [MethodImpl(MethodImplOptions.NoInlining)] private static long CallForSplitStructWithFourLongs(int arg0, int arg1, StructWithFourLongs splitArg) => splitArg.LongOne; + + [MethodImpl(MethodImplOptions.NoInlining)] + private static double CallForDblStruct(DblStruct value) => value.Dbl; + + [MethodImpl(MethodImplOptions.NoInlining)] + private static float CallForFltStruct(FltStruct value) => value.Flt; } [StructLayout(LayoutKind.Explicit)] @@ -170,3 +196,13 @@ struct FourDoublesHfaStruct public double ThirdDblValue; public double FourthDblValue; } + +struct DblStruct +{ + public double Dbl; +} + +struct FltStruct +{ + public float Flt; +} From 1a02f0d62481b9830ded42d514053aab8b3aca3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksey=20Kliger=20=28=CE=BBgeek=29?= Date: Thu, 16 Jun 2022 19:35:51 -0400 Subject: [PATCH 174/337] [coop] fix coop suspend timeout cue card (#70828) the BLOCKING_SUSPEND_REQUESTED state is treated as suspend in full coop mode (the thread keeps running, but by definition it's not allowed to access managed resources and it will self-suspend if it tries to enter GC Unsafe mode by calling a runtime API or managed code). It is bad in hybrid suspend mode (the thread should be preemptively suspended, but we timed out before the signal handler had a chance to run). The corresponding suspension logic in the code is: https://github.com/dotnet/runtime/blob/3fc61ebb562afc327a8fc6de5c82d76e86bf6f5d/src/mono/mono/utils/mono-threads.c#L1149-L1158 --- src/mono/mono/utils/mono-threads.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/utils/mono-threads.c b/src/mono/mono/utils/mono-threads.c index 435b7dca5a989d..8bf3e2f5bd4977 100644 --- a/src/mono/mono/utils/mono-threads.c +++ b/src/mono/mono/utils/mono-threads.c @@ -292,7 +292,7 @@ dump_threads (void) g_async_safe_printf ("\t0x6\t- blocking (BAD, unless there's no suspend initiator)\n"); g_async_safe_printf ("\t0x?07\t- blocking async suspended (GOOD)\n"); g_async_safe_printf ("\t0x?08\t- blocking self suspended (GOOD)\n"); - g_async_safe_printf ("\t0x?09\t- blocking suspend requested (BAD in coop; GOOD in hybrid)\n"); + g_async_safe_printf ("\t0x?09\t- blocking suspend requested (GOOD in coop; BAD in hybrid)\n"); FOREACH_THREAD_SAFE_ALL (info) { #ifdef TARGET_MACH From 48adb84ddc2f48ae76adae5854f66371d5e6960e Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Thu, 16 Jun 2022 17:47:08 -0700 Subject: [PATCH 175/337] Fixing the handling of Positive NaN in Math.Min for float/double (#70795) * Adding tests validating Positive NaN for Max, MaxMagnitude, Min, and MinMagnitude * Fixing the handling of Positive NaN in Math.Min for float/double * Fixing the Max/Min code comments to use greater and lesser * Adding a code comment clarifying the sign toggling behavior --- .../System.Private.CoreLib/src/System/Math.cs | 42 ++++-- .../src/System/MathF.cs | 8 +- .../tests/System/Math.cs | 140 +++++++++++++++++- .../tests/System/MathF.cs | 82 ++++++++++ 4 files changed, 251 insertions(+), 21 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.cs b/src/libraries/System.Private.CoreLib/src/System/Math.cs index c6951fbafe9c23..c8abd2bc39c680 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.cs @@ -888,8 +888,8 @@ public static double Max(double val1, double val2) // This matches the IEEE 754:2019 `maximum` function // // It propagates NaN inputs back to the caller and - // otherwise returns the larger of the inputs. It - // treats +0 as larger than -0 as per the specification. + // otherwise returns the greater of the inputs. It + // treats +0 as greater than -0 as per the specification. if (val1 != val2) { @@ -946,8 +946,8 @@ public static float Max(float val1, float val2) // This matches the IEEE 754:2019 `maximum` function // // It propagates NaN inputs back to the caller and - // otherwise returns the larger of the inputs. It - // treats +0 as larger than -0 as per the specification. + // otherwise returns the greater of the inputs. It + // treats +0 as greater than -0 as per the specification. if (val1 != val2) { @@ -999,8 +999,8 @@ public static double MaxMagnitude(double x, double y) // This matches the IEEE 754:2019 `maximumMagnitude` function // // It propagates NaN inputs back to the caller and - // otherwise returns the input with a larger magnitude. - // It treats +0 as larger than -0 as per the specification. + // otherwise returns the input with a greater magnitude. + // It treats +0 as greater than -0 as per the specification. double ax = Abs(x); double ay = Abs(y); @@ -1037,12 +1037,17 @@ public static double Min(double val1, double val2) // This matches the IEEE 754:2019 `minimum` function // // It propagates NaN inputs back to the caller and - // otherwise returns the larger of the inputs. It - // treats +0 as larger than -0 as per the specification. + // otherwise returns the lesser of the inputs. It + // treats +0 as lesser than -0 as per the specification. - if (val1 != val2 && !double.IsNaN(val1)) + if (val1 != val2) { - return val1 < val2 ? val1 : val2; + if (!double.IsNaN(val1)) + { + return val1 < val2 ? val1 : val2; + } + + return val1; } return double.IsNegative(val1) ? val1 : val2; @@ -1090,12 +1095,17 @@ public static float Min(float val1, float val2) // This matches the IEEE 754:2019 `minimum` function // // It propagates NaN inputs back to the caller and - // otherwise returns the larger of the inputs. It - // treats +0 as larger than -0 as per the specification. + // otherwise returns the lesser of the inputs. It + // treats +0 as lesser than -0 as per the specification. - if (val1 != val2 && !float.IsNaN(val1)) + if (val1 != val2) { - return val1 < val2 ? val1 : val2; + if (!float.IsNaN(val1)) + { + return val1 < val2 ? val1 : val2; + } + + return val1; } return float.IsNegative(val1) ? val1 : val2; @@ -1138,8 +1148,8 @@ public static double MinMagnitude(double x, double y) // This matches the IEEE 754:2019 `minimumMagnitude` function // // It propagates NaN inputs back to the caller and - // otherwise returns the input with a larger magnitude. - // It treats +0 as larger than -0 as per the specification. + // otherwise returns the input with a lesser magnitude. + // It treats +0 as lesser than -0 as per the specification. double ax = Abs(x); double ay = Abs(y); diff --git a/src/libraries/System.Private.CoreLib/src/System/MathF.cs b/src/libraries/System.Private.CoreLib/src/System/MathF.cs index 4da93e1ee70bbc..6b86c780a5c46e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/MathF.cs +++ b/src/libraries/System.Private.CoreLib/src/System/MathF.cs @@ -252,8 +252,8 @@ public static float MaxMagnitude(float x, float y) // This matches the IEEE 754:2019 `maximumMagnitude` function // // It propagates NaN inputs back to the caller and - // otherwise returns the input with a larger magnitude. - // It treats +0 as larger than -0 as per the specification. + // otherwise returns the input with a greater magnitude. + // It treats +0 as greater than -0 as per the specification. float ax = Abs(x); float ay = Abs(y); @@ -282,8 +282,8 @@ public static float MinMagnitude(float x, float y) // This matches the IEEE 754:2019 `minimumMagnitude` function // // It propagates NaN inputs back to the caller and - // otherwise returns the input with a larger magnitude. - // It treats +0 as larger than -0 as per the specification. + // otherwise returns the input with a lesser magnitude. + // It treats +0 as lesser than -0 as per the specification. float ax = Abs(x); float ay = Abs(y); diff --git a/src/libraries/System.Runtime.Extensions/tests/System/Math.cs b/src/libraries/System.Runtime.Extensions/tests/System/Math.cs index fc869489acb9df..86ca388b114217 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/Math.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/Math.cs @@ -796,6 +796,29 @@ public static void Max_Decimal() public static void Max_Double_NotNetFramework(double x, double y, double expectedResult) { AssertExtensions.Equal(expectedResult, Math.Max(x, y), 0.0); + + if (double.IsNaN(x)) + { + // Toggle the sign of the NaN to validate both +NaN and -NaN behave the same. + // Negate should work as well but the JIT may constant fold or do other tricks + // and normalize to a single NaN form so we do bitwise tricks to ensure we test + // the right thing. + + ulong bits = BitConverter.DoubleToUInt64Bits(x); + bits ^= BitConverter.DoubleToUInt64Bits(-0.0); + x = BitConverter.UInt64BitsToDouble(bits); + + AssertExtensions.Equal(expectedResult, Math.Max(x, y), 0.0); + } + + if (double.IsNaN(y)) + { + ulong bits = BitConverter.DoubleToUInt64Bits(y); + bits ^= BitConverter.DoubleToUInt64Bits(-0.0); + y = BitConverter.UInt64BitsToDouble(bits); + + AssertExtensions.Equal(expectedResult, Math.Max(x, y), 0.0); + } } [Fact] @@ -854,6 +877,29 @@ public static void Max_SByte() public static void Max_Single_NotNetFramework(float x, float y, float expectedResult) { AssertExtensions.Equal(expectedResult, Math.Max(x, y), 0.0f); + + if (float.IsNaN(x)) + { + // Toggle the sign of the NaN to validate both +NaN and -NaN behave the same. + // Negate should work as well but the JIT may constant fold or do other tricks + // and normalize to a single NaN form so we do bitwise tricks to ensure we test + // the right thing. + + uint bits = BitConverter.SingleToUInt32Bits(x); + bits ^= BitConverter.SingleToUInt32Bits(-0.0f); + x = BitConverter.UInt32BitsToSingle(bits); + + AssertExtensions.Equal(expectedResult, Math.Max(x, y), 0.0f); + } + + if (float.IsNaN(y)) + { + uint bits = BitConverter.SingleToUInt32Bits(y); + bits ^= BitConverter.SingleToUInt32Bits(-0.0f); + y = BitConverter.UInt32BitsToSingle(bits); + + AssertExtensions.Equal(expectedResult, Math.Max(x, y), 0.0f); + } } [Fact] @@ -919,6 +965,29 @@ public static void Min_Decimal() public static void Min_Double_NotNetFramework(double x, double y, double expectedResult) { AssertExtensions.Equal(expectedResult, Math.Min(x, y), 0.0); + + if (double.IsNaN(x)) + { + // Toggle the sign of the NaN to validate both +NaN and -NaN behave the same. + // Negate should work as well but the JIT may constant fold or do other tricks + // and normalize to a single NaN form so we do bitwise tricks to ensure we test + // the right thing. + + ulong bits = BitConverter.DoubleToUInt64Bits(x); + bits ^= BitConverter.DoubleToUInt64Bits(-0.0); + x = BitConverter.UInt64BitsToDouble(bits); + + AssertExtensions.Equal(expectedResult, Math.Min(x, y), 0.0); + } + + if (double.IsNaN(y)) + { + ulong bits = BitConverter.DoubleToUInt64Bits(y); + bits ^= BitConverter.DoubleToUInt64Bits(-0.0); + y = BitConverter.UInt64BitsToDouble(bits); + + AssertExtensions.Equal(expectedResult, Math.Min(x, y), 0.0); + } } [Fact] @@ -977,6 +1046,29 @@ public static void Min_SByte() public static void Min_Single_NotNetFramework(float x, float y, float expectedResult) { AssertExtensions.Equal(expectedResult, Math.Min(x, y), 0.0f); + + if (float.IsNaN(x)) + { + // Toggle the sign of the NaN to validate both +NaN and -NaN behave the same. + // Negate should work as well but the JIT may constant fold or do other tricks + // and normalize to a single NaN form so we do bitwise tricks to ensure we test + // the right thing. + + uint bits = BitConverter.SingleToUInt32Bits(x); + bits ^= BitConverter.SingleToUInt32Bits(-0.0f); + x = BitConverter.UInt32BitsToSingle(bits); + + AssertExtensions.Equal(expectedResult, Math.Min(x, y), 0.0f); + } + + if (float.IsNaN(y)) + { + uint bits = BitConverter.SingleToUInt32Bits(y); + bits ^= BitConverter.SingleToUInt32Bits(-0.0f); + y = BitConverter.UInt32BitsToSingle(bits); + + AssertExtensions.Equal(expectedResult, Math.Min(x, y), 0.0f); + } } [Fact] @@ -2566,6 +2658,29 @@ public static void Log2(double value, double expectedResult, double allowedVaria public static void MaxMagnitude(double x, double y, double expectedResult) { AssertExtensions.Equal(expectedResult, Math.MaxMagnitude(x, y), 0.0); + + if (double.IsNaN(x)) + { + // Toggle the sign of the NaN to validate both +NaN and -NaN behave the same. + // Negate should work as well but the JIT may constant fold or do other tricks + // and normalize to a single NaN form so we do bitwise tricks to ensure we test + // the right thing. + + ulong bits = BitConverter.DoubleToUInt64Bits(x); + bits ^= BitConverter.DoubleToUInt64Bits(-0.0); + x = BitConverter.UInt64BitsToDouble(bits); + + AssertExtensions.Equal(expectedResult, Math.MaxMagnitude(x, y), 0.0); + } + + if (double.IsNaN(y)) + { + ulong bits = BitConverter.DoubleToUInt64Bits(y); + bits ^= BitConverter.DoubleToUInt64Bits(-0.0); + y = BitConverter.UInt64BitsToDouble(bits); + + AssertExtensions.Equal(expectedResult, Math.MaxMagnitude(x, y), 0.0); + } } [Theory] @@ -2589,6 +2704,29 @@ public static void MaxMagnitude(double x, double y, double expectedResult) public static void MinMagnitude(double x, double y, double expectedResult) { AssertExtensions.Equal(expectedResult, Math.MinMagnitude(x, y), 0.0); + + if (double.IsNaN(x)) + { + // Toggle the sign of the NaN to validate both +NaN and -NaN behave the same. + // Negate should work as well but the JIT may constant fold or do other tricks + // and normalize to a single NaN form so we do bitwise tricks to ensure we test + // the right thing. + + ulong bits = BitConverter.DoubleToUInt64Bits(x); + bits ^= BitConverter.DoubleToUInt64Bits(-0.0); + x = BitConverter.UInt64BitsToDouble(bits); + + AssertExtensions.Equal(expectedResult, Math.MinMagnitude(x, y), 0.0); + } + + if (double.IsNaN(y)) + { + ulong bits = BitConverter.DoubleToUInt64Bits(y); + bits ^= BitConverter.DoubleToUInt64Bits(-0.0); + y = BitConverter.UInt64BitsToDouble(bits); + + AssertExtensions.Equal(expectedResult, Math.MinMagnitude(x, y), 0.0); + } } [Theory] @@ -2657,7 +2795,7 @@ public static void MinMagnitude(double x, double y, double expectedResult) [InlineData( 9.267056966972586, 2, 37.06822786789034, CrossPlatformMachineEpsilon * 100)] [InlineData( 0.5617597462207241, 5, 17.97631187906317, CrossPlatformMachineEpsilon * 100)] [InlineData( 0.7741522965913037, 6, 49.545746981843436, CrossPlatformMachineEpsilon * 100)] - [InlineData( -0.6787637026394024, 7, -86.88175393784351, CrossPlatformMachineEpsilon * 100)] + [InlineData( -0.6787637026394024, 7, -86.88175393784351, CrossPlatformMachineEpsilon * 100)] [InlineData( -6.531673581913484, 1, -13.063347163826968, CrossPlatformMachineEpsilon * 100)] [InlineData( 9.267056966972586, 2, 37.06822786789034, CrossPlatformMachineEpsilon * 100)] [InlineData( 0.5617597462207241, 5, 17.97631187906317, CrossPlatformMachineEpsilon * 100)] diff --git a/src/libraries/System.Runtime.Extensions/tests/System/MathF.cs b/src/libraries/System.Runtime.Extensions/tests/System/MathF.cs index ca3f5de6b0f34b..85e62a190ad777 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/MathF.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/MathF.cs @@ -1090,6 +1090,29 @@ public static void Log10(float value, float expectedResult, float allowedVarianc public static void Max(float x, float y, float expectedResult) { AssertExtensions.Equal(expectedResult, MathF.Max(x, y), 0.0f); + + if (float.IsNaN(x)) + { + // Toggle the sign of the NaN to validate both +NaN and -NaN behave the same. + // Negate should work as well but the JIT may constant fold or do other tricks + // and normalize to a single NaN form so we do bitwise tricks to ensure we test + // the right thing. + + uint bits = BitConverter.SingleToUInt32Bits(x); + bits ^= BitConverter.SingleToUInt32Bits(-0.0f); + x = BitConverter.UInt32BitsToSingle(bits); + + AssertExtensions.Equal(expectedResult, Math.Max(x, y), 0.0f); + } + + if (float.IsNaN(y)) + { + uint bits = BitConverter.SingleToUInt32Bits(y); + bits ^= BitConverter.SingleToUInt32Bits(-0.0f); + y = BitConverter.UInt32BitsToSingle(bits); + + AssertExtensions.Equal(expectedResult, Math.Max(x, y), 0.0f); + } } [Theory] @@ -1113,6 +1136,29 @@ public static void Max(float x, float y, float expectedResult) public static void MaxMagnitude(float x, float y, float expectedResult) { AssertExtensions.Equal(expectedResult, MathF.MaxMagnitude(x, y), 0.0f); + + if (float.IsNaN(x)) + { + // Toggle the sign of the NaN to validate both +NaN and -NaN behave the same. + // Negate should work as well but the JIT may constant fold or do other tricks + // and normalize to a single NaN form so we do bitwise tricks to ensure we test + // the right thing. + + uint bits = BitConverter.SingleToUInt32Bits(x); + bits ^= BitConverter.SingleToUInt32Bits(-0.0f); + x = BitConverter.UInt32BitsToSingle(bits); + + AssertExtensions.Equal(expectedResult, Math.MaxMagnitude(x, y), 0.0f); + } + + if (float.IsNaN(y)) + { + uint bits = BitConverter.SingleToUInt32Bits(y); + bits ^= BitConverter.SingleToUInt32Bits(-0.0f); + y = BitConverter.UInt32BitsToSingle(bits); + + AssertExtensions.Equal(expectedResult, Math.MaxMagnitude(x, y), 0.0f); + } } [Theory] @@ -1136,6 +1182,24 @@ public static void MaxMagnitude(float x, float y, float expectedResult) public static void Min(float x, float y, float expectedResult) { AssertExtensions.Equal(expectedResult, MathF.Min(x, y), 0.0f); + + if (float.IsNaN(x)) + { + uint bits = BitConverter.SingleToUInt32Bits(x); + bits ^= BitConverter.SingleToUInt32Bits(-0.0f); + x = BitConverter.UInt32BitsToSingle(bits); + + AssertExtensions.Equal(expectedResult, Math.Min(x, y), 0.0f); + } + + if (float.IsNaN(y)) + { + uint bits = BitConverter.SingleToUInt32Bits(y); + bits ^= BitConverter.SingleToUInt32Bits(-0.0f); + y = BitConverter.UInt32BitsToSingle(bits); + + AssertExtensions.Equal(expectedResult, Math.Min(x, y), 0.0f); + } } [Theory] @@ -1159,6 +1223,24 @@ public static void Min(float x, float y, float expectedResult) public static void MinMagnitude(float x, float y, float expectedResult) { AssertExtensions.Equal(expectedResult, MathF.MinMagnitude(x, y), 0.0f); + + if (float.IsNaN(x)) + { + uint bits = BitConverter.SingleToUInt32Bits(x); + bits ^= BitConverter.SingleToUInt32Bits(-0.0f); + x = BitConverter.UInt32BitsToSingle(bits); + + AssertExtensions.Equal(expectedResult, Math.MinMagnitude(x, y), 0.0f); + } + + if (float.IsNaN(y)) + { + uint bits = BitConverter.SingleToUInt32Bits(y); + bits ^= BitConverter.SingleToUInt32Bits(-0.0f); + y = BitConverter.UInt32BitsToSingle(bits); + + AssertExtensions.Equal(expectedResult, Math.MinMagnitude(x, y), 0.0f); + } } [Theory] From e3a209719f08cc9f660828c7af34ecb9e980df8c Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Thu, 16 Jun 2022 18:15:26 -0700 Subject: [PATCH 176/337] JIT: break loop canonicalization into two stages (#70809) For a given loop, we need to separate out the true backedge, any non-loop backedges, and any inner loop backedges so that they all target distinct blocks. Otherwise, we may violate assumptions that the loop entry dominates all blocks in the loop and that all backedges that reach top come from within the loop. This seems simplest to do with two rounds of canonicalization, one that moves the non-loop edges, and another that moves the true backedge. Fixes #70802. --- src/coreclr/jit/compiler.h | 8 + src/coreclr/jit/optimizer.cpp | 326 +++++++++++++++++++++++++--------- 2 files changed, 248 insertions(+), 86 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 39356888b99731..e8cc613d7a19a8 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -6335,6 +6335,14 @@ class Compiler // unshared with any other loop. Returns "true" iff the flowgraph has been modified bool optCanonicalizeLoop(unsigned char loopInd); + enum class LoopCanonicalizationOption + { + Outer, + Current + }; + + bool optCanonicalizeLoopCore(unsigned char loopInd, LoopCanonicalizationOption option); + // Requires "l1" to be a valid loop table index, and not "BasicBlock::NOT_IN_LOOP". // Requires "l2" to be a valid loop table index, or else "BasicBlock::NOT_IN_LOOP". // Returns true iff "l2" is not NOT_IN_LOOP, and "l1" contains "l2". diff --git a/src/coreclr/jit/optimizer.cpp b/src/coreclr/jit/optimizer.cpp index de2459c862e9a3..211bd9466be42d 100644 --- a/src/coreclr/jit/optimizer.cpp +++ b/src/coreclr/jit/optimizer.cpp @@ -1725,9 +1725,13 @@ class LoopSearch // Thus, we have to be very careful and after entry discovery check that it is indeed // the only place we enter the loop (especially for non-reducible flow graphs). + JITDUMP("FindLoop: checking head:" FMT_BB " top:" FMT_BB " bottom:" FMT_BB "\n", head->bbNum, top->bbNum, + bottom->bbNum); + if (top->bbNum > bottom->bbNum) // is this a backward edge? (from BOTTOM to TOP) { // Edge from BOTTOM to TOP is not a backward edge + JITDUMP(" " FMT_BB "->" FMT_BB " is not a backedge\n", bottom->bbNum, top->bbNum); return false; } @@ -1735,11 +1739,13 @@ class LoopSearch { // Not a true back-edge; bottom is a block added to reconnect fall-through during // loop processing, so its block number does not reflect its position. + JITDUMP(" " FMT_BB "->" FMT_BB " is not a true backedge\n", bottom->bbNum, top->bbNum); return false; } if (bottom->KindIs(BBJ_EHFINALLYRET, BBJ_EHFILTERRET, BBJ_EHCATCHRET, BBJ_CALLFINALLY, BBJ_SWITCH)) { + JITDUMP(" bottom odd jump kind\n"); // BBJ_EHFINALLYRET, BBJ_EHFILTERRET, BBJ_EHCATCHRET, and BBJ_CALLFINALLY can never form a loop. // BBJ_SWITCH that has a backward jump appears only for labeled break. return false; @@ -1759,6 +1765,7 @@ class LoopSearch if (entry == nullptr) { // For now, we only recognize loops where HEAD has some successor ENTRY in the loop. + JITDUMP(" can't find entry\n"); return false; } @@ -1773,12 +1780,14 @@ class LoopSearch if (!HasSingleEntryCycle()) { // There isn't actually a loop between TOP and BOTTOM + JITDUMP(" not single entry cycle\n"); return false; } if (!loopBlocks.IsMember(top->bbNum)) { // The "back-edge" we identified isn't actually part of the flow cycle containing ENTRY + JITDUMP(" top not in loop\n"); return false; } @@ -1828,6 +1837,7 @@ class LoopSearch if (!MakeCompactAndFindExits()) { // Unable to preserve well-formed loop during compaction. + JITDUMP(" can't compact\n"); return false; } @@ -1928,6 +1938,7 @@ class LoopSearch } else if (!comp->fgDominate(entry, block)) { + JITDUMP(" (find cycle) entry:" FMT_BB " does not dominate " FMT_BB "\n", entry->bbNum, block->bbNum); return false; } @@ -1960,6 +1971,8 @@ class LoopSearch } // There are multiple entries to this loop, don't consider it. + + JITDUMP(" (find cycle) multiple entry:" FMT_BB "\n", block->bbNum); return false; } @@ -1967,6 +1980,7 @@ class LoopSearch if (predBlock == entry) { // We have indeed found a cycle in the flow graph. + JITDUMP(" (find cycle) found cycle\n"); isFirstVisit = !foundCycle; foundCycle = true; assert(loopBlocks.IsMember(predBlock->bbNum)); @@ -2885,14 +2899,18 @@ bool Compiler::optIsLoopEntry(BasicBlock* block) const // // Notes: // For loopInd and all contained loops, ensures each loop top's back edges -// do not come from nested loops. +// only come from this loop. // // Will split top blocks and redirect edges if needed. // bool Compiler::optCanonicalizeLoopNest(unsigned char loopInd) { + // First canonicalize the loop. + // bool modified = optCanonicalizeLoop(loopInd); + // Then any children. + // for (unsigned char child = optLoopTable[loopInd].lpChild; // child != BasicBlock::NOT_IN_LOOP; // child = optLoopTable[child].lpSibling) @@ -2904,8 +2922,8 @@ bool Compiler::optCanonicalizeLoopNest(unsigned char loopInd) } //----------------------------------------------------------------------------- -// optCanonicalizeLoop: ensure that each loop top's back edges do not come -// from nested loops. +// optCanonicalizeLoop: ensure that each loop top's back edges come only from +// blocks in the same loop. // // Arguments: // loopInd - index of the loop to consider @@ -2913,21 +2931,108 @@ bool Compiler::optCanonicalizeLoopNest(unsigned char loopInd) // Returns: // true if flow changes were made // +// Notes: +// +// Back edges incident on loop top fall into one three groups: +// +// (1) Outer non-loop backedges (preds dominated by entry where pred is not in loop) +// (2) The canonical backedge (pred == bottom) +// (3) Nested loop backedges or nested non-loop backedges +// (preds dominated by entry, where pred is in loop, pred != bottom) +// +// We assume dominance has already been established by loop recognition (that is, +// anything classified as a loop will have all backedges dominated by loop entry, +// so the only possible non-backedge predecessor of top will be head). +// +// We cannot check dominance here as the flow graph is being modified. +// +// If either set (1) or (3) is non-empty the loop is not canonical. +// +// This method will split the loop top into two or three blocks depending on +// whether (1) or (3) is non-empty, and redirect the edges accordingly. +// +// Loops are canoncalized outer to inner, so inner loops should never see outer loop +// non-backedges, as the parent loop canonicalization should have handled them. +// bool Compiler::optCanonicalizeLoop(unsigned char loopInd) { - // Is the top uniquely part of the current loop? - BasicBlock* const t = optLoopTable[loopInd].lpTop; + bool modified = false; + BasicBlock* const b = optLoopTable[loopInd].lpBottom; + BasicBlock* const t = optLoopTable[loopInd].lpTop; + BasicBlock* const h = optLoopTable[loopInd].lpHead; + BasicBlock* const e = optLoopTable[loopInd].lpEntry; - if (t->bbNatLoopNum == loopInd) + // Look for case (1) + // + bool doOuterCanon = false; + + for (BasicBlock* const topPredBlock : t->PredBlocks()) { - return false; + const bool predIsInLoop = (t->bbNum <= topPredBlock->bbNum) && (topPredBlock->bbNum <= b->bbNum); + if (predIsInLoop || (topPredBlock == h)) + { + // no action needed + } + else + { + JITDUMP("in optCanonicalizeLoop: " FMT_LP " top " FMT_BB " (entry " FMT_BB " bottom " FMT_BB + ") %shas a non-loop backedge from " FMT_BB "%s\n", + loopInd, t->bbNum, e->bbNum, b->bbNum, doOuterCanon ? "also " : "", topPredBlock->bbNum, + doOuterCanon ? "" : ": need to canonicalize non-loop backedges"); + doOuterCanon = true; + } + } + + if (doOuterCanon) + { + const bool didCanon = optCanonicalizeLoopCore(loopInd, LoopCanonicalizationOption::Outer); + assert(didCanon); + modified |= didCanon; + } + + // Look for case (3) + // + // Outer canon should not update loop top. + // + assert(t == optLoopTable[loopInd].lpTop); + if (t->bbNatLoopNum != loopInd) + { + JITDUMP("in optCanonicalizeLoop: " FMT_LP " has top " FMT_BB " (entry " FMT_BB " bottom " FMT_BB + ") with natural loop number " FMT_LP ": need to canonicalize nested inner loop backedges\n", + loopInd, t->bbNum, e->bbNum, b->bbNum, t->bbNatLoopNum); + + const bool didCanon = optCanonicalizeLoopCore(loopInd, LoopCanonicalizationOption::Current); + assert(didCanon); + modified |= didCanon; + } + + if (modified) + { + JITDUMP("Done canonicalizing " FMT_LP "\n\n", loopInd); } - JITDUMP("in optCanonicalizeLoop: " FMT_LP " has top " FMT_BB " (bottom " FMT_BB ") with natural loop number " FMT_LP - ": need to canonicalize\n", - loopInd, t->bbNum, optLoopTable[loopInd].lpBottom->bbNum, t->bbNatLoopNum); + return modified; +} - // Otherwise, the top of this loop is also part of a nested loop. +//----------------------------------------------------------------------------- +// optCanonicalizeLoopCore: ensure that each loop top's back edges come do not +// come from outer/inner loops. +// +// Arguments: +// loopInd - index of the loop to consider +// option - which set of edges to move when canonicalizing +// +// Returns: +// true if flow changes were made +// +// Notes: +// option ::Outer retargets all backedges that do not come from loops in the block. +// option ::Current retargets the canonical backedge (from bottom) +// +bool Compiler::optCanonicalizeLoopCore(unsigned char loopInd, LoopCanonicalizationOption option) +{ + // Otherwise, the top of this loop is also part of a nested loop or has + // non-loop backedges. // // Insert a new unique top for this loop. We must be careful to put this new // block in the correct EH region. Note that t->bbPrev might be in a different @@ -3003,9 +3108,10 @@ bool Compiler::optCanonicalizeLoop(unsigned char loopInd) // want to copy the EH region of the back edge, since that would create a block // outside of and disjoint with the "try" region of the back edge. However, to // simplify things, we disqualify this type of loop, so we should never see this here. - - BasicBlock* const h = optLoopTable[loopInd].lpHead; + // BasicBlock* const b = optLoopTable[loopInd].lpBottom; + BasicBlock* const t = optLoopTable[loopInd].lpTop; + BasicBlock* const h = optLoopTable[loopInd].lpHead; // The loop must be entirely contained within a single handler region. assert(BasicBlock::sameHndRegion(t, b)); @@ -3028,8 +3134,15 @@ bool Compiler::optCanonicalizeLoop(unsigned char loopInd) // If the bottom block is in the same "try" region, then we extend the EH // region. Otherwise, we add the new block outside the "try" region. - const bool extendRegion = BasicBlock::sameTryRegion(t, b); - BasicBlock* newT = fgNewBBbefore(BBJ_NONE, t, extendRegion); + // + const bool extendRegion = BasicBlock::sameTryRegion(t, b); + BasicBlock* const newT = fgNewBBbefore(BBJ_NONE, t, extendRegion); + + // Initially give newT the same weight as t; we will subtract from + // this for each edge that does not move from t to newT. + // + newT->inheritWeight(t); + if (!extendRegion) { // We need to set the EH region manually. Set it to be the same @@ -3037,73 +3150,95 @@ bool Compiler::optCanonicalizeLoop(unsigned char loopInd) newT->copyEHRegion(b); } + // NewT will be the target for the outer/current loop's backedge(s). + // + BlockToBlockMap* const blockMap = new (getAllocator(CMK_LoopOpt)) BlockToBlockMap(getAllocator(CMK_LoopOpt)); + blockMap->Set(t, newT); + // The new block can reach the same set of blocks as the old one, but don't try to reflect // that in its reachability set here -- creating the new block may have changed the BlockSet // representation from short to long, and canonicalizing loops is immediately followed by // a call to fgUpdateChangedFlowGraph which will recompute the reachability sets anyway. - // Redirect the "bottom" of the current loop to "newT". - BlockToBlockMap* const blockMap = new (getAllocator(CMK_LoopOpt)) BlockToBlockMap(getAllocator(CMK_LoopOpt)); - blockMap->Set(t, newT); - optRedirectBlock(b, blockMap); - JITDUMP("in optCanonicalizeLoop: redirecting bottom->top backedge " FMT_BB " -> " FMT_BB " to " FMT_BB " -> " FMT_BB - "\n", - b->bbNum, t->bbNum, b->bbNum, newT->bbNum); - - // Redirect non-loop preds of "t" to also go to "newT". Inner loops that also branch to "t" should continue - // to do so. However, there maybe be other predecessors from outside the loop nest that need to be updated - // to point to "newT". This normally wouldn't happen, since they too would be part of the loop nest. However, - // they might have been prevented from participating in the loop nest due to different EH nesting, or some - // other reason. - // - // Note that optRedirectBlock doesn't update the predecessors list. So, if the same 't' block is processed - // multiple times while canonicalizing multiple loop nests, we'll attempt to redirect a predecessor multiple times. - // This is ok, because after the first redirection, the topPredBlock branch target will no longer match the source - // edge of the blockMap, so nothing will happen. bool firstPred = true; for (BasicBlock* const topPredBlock : t->PredBlocks()) { - // Skip if topPredBlock is in the loop. - // Note that this uses block number to detect membership in the loop. We are adding blocks during - // canonicalization, and those block numbers will be new, and larger than previous blocks. However, we work - // outside-in, so we shouldn't encounter the new blocks at the loop boundaries, or in the predecessor lists. - if (t->bbNum <= topPredBlock->bbNum && topPredBlock->bbNum <= b->bbNum) + // We set profile weight of newT assuming all edges would + // be redirected there. So, if we don't redirect this edge, + // this is how much we'll have to adjust newT's weight. + // + weight_t weightAdjust = BB_ZERO_WEIGHT; + + if (option == LoopCanonicalizationOption::Current) { - // Note we've already redirected b->t above. + // Redirect the (one and only) true backedge of this loop. // - if (topPredBlock->bbNum != b->bbNum) + if (topPredBlock != b) { - JITDUMP("in optCanonicalizeLoop: in-loop 'top' predecessor " FMT_BB " is in the range of " FMT_LP - " (" FMT_BB ".." FMT_BB "); not redirecting its bottom edge\n", - topPredBlock->bbNum, loopInd, t->bbNum, b->bbNum); + if ((topPredBlock != h) && topPredBlock->hasProfileWeight()) + { + // Note this may overstate the adjustment, if topPredBlock is BBJ_COND. + // + weightAdjust = topPredBlock->bbWeight; + } + } + else + { + JITDUMP("in optCanonicalizeLoop (current): redirect bottom->top backedge " FMT_BB " -> " FMT_BB + " to " FMT_BB " -> " FMT_BB "\n", + topPredBlock->bbNum, t->bbNum, topPredBlock->bbNum, newT->bbNum); + optRedirectBlock(b, blockMap); } - continue; } - - JITDUMP("in optCanonicalizeLoop: redirect top predecessor " FMT_BB " to " FMT_BB "\n", topPredBlock->bbNum, - newT->bbNum); - optRedirectBlock(topPredBlock, blockMap); - - // When we have profile data then the 'newT' block will inherit topPredBlock profile weight - if (topPredBlock->hasProfileWeight()) + else if (option == LoopCanonicalizationOption::Outer) { - // This corrects an issue when the topPredBlock has a profile based weight + // Redirect non-loop preds of "t" to go to "newT". Inner loops that also branch to "t" should continue + // to do so. However, there maybe be other predecessors from outside the loop nest that need to be updated + // to point to "newT". This normally wouldn't happen, since they too would be part of the loop nest. + // However, + // they might have been prevented from participating in the loop nest due to different EH nesting, or some + // other reason. + // + // Skip if topPredBlock is in the loop. + // Note that this uses block number to detect membership in the loop. We are adding blocks during + // canonicalization, and those block numbers will be new, and larger than previous blocks. However, we work + // outside-in, so we shouldn't encounter the new blocks at the loop boundaries, or in the predecessor lists. // - if (firstPred) + if ((t->bbNum <= topPredBlock->bbNum) && (topPredBlock->bbNum <= b->bbNum)) { - JITDUMP("in optCanonicalizeLoop: block " FMT_BB " will inheritWeight from " FMT_BB "\n", newT->bbNum, - topPredBlock->bbNum); - - newT->inheritWeight(topPredBlock); - firstPred = false; + if (topPredBlock->hasProfileWeight()) + { + // Note this may overstate the adjustment, if topPredBlock is BBJ_COND. + // + weightAdjust = topPredBlock->bbWeight; + } } else { - JITDUMP("in optCanonicalizeLoop: block " FMT_BB " will also contribute to the weight of " FMT_BB "\n", - newT->bbNum, topPredBlock->bbNum); + JITDUMP("in optCanonicalizeLoop (outer): redirect %s->top %sedge " FMT_BB " -> " FMT_BB " to " FMT_BB + " -> " FMT_BB "\n", + topPredBlock == h ? "head" : "nonloop", topPredBlock == h ? "" : "back", topPredBlock->bbNum, + t->bbNum, topPredBlock->bbNum, newT->bbNum); + optRedirectBlock(topPredBlock, blockMap); + } + } + else + { + unreached(); + } + + if (weightAdjust > BB_ZERO_WEIGHT) + { + JITDUMP("in optCanonicalizeLoop: removing block " FMT_BB " weight " FMT_WT " from " FMT_BB "\n", + topPredBlock->bbNum, weightAdjust, newT->bbNum); - weight_t newWeight = newT->getBBWeight(this) + topPredBlock->getBBWeight(this); - newT->setBBProfileWeight(newWeight); + if (newT->bbWeight >= weightAdjust) + { + newT->setBBProfileWeight(newT->bbWeight - weightAdjust); + } + else if (newT->bbWeight > BB_ZERO_WEIGHT) + { + newT->setBBProfileWeight(BB_ZERO_WEIGHT); } } } @@ -3111,39 +3246,58 @@ bool Compiler::optCanonicalizeLoop(unsigned char loopInd) assert(h->bbNext == newT); assert(newT->bbNext == t); - // If loopInd is a do-while loop (top == entry), update entry as well. + // With the Option::Current we are changing which block is loop top. + // Make suitable updates. // - BasicBlock* const origE = optLoopTable[loopInd].lpEntry; - if (optLoopTable[loopInd].lpTop == origE) + if (option == LoopCanonicalizationOption::Current) { - optLoopTable[loopInd].lpEntry = newT; - } - optLoopTable[loopInd].lpTop = newT; + JITDUMP("in optCanonicalizeLoop (current): " FMT_BB " is now the top of loop " FMT_LP "\n", newT->bbNum, + loopInd); - newT->bbNatLoopNum = loopInd; + optLoopTable[loopInd].lpTop = newT; + newT->bbNatLoopNum = loopInd; - JITDUMP("in optCanonicalizeLoop: made new block " FMT_BB " [%p] the new unique top of loop %d.\n", newT->bbNum, - dspPtr(newT), loopInd); + // If loopInd was a do-while loop (top == entry), update entry, as well. + // + BasicBlock* const origE = optLoopTable[loopInd].lpEntry; + if (origE == t) + { + JITDUMP("updating entry of " FMT_LP " to " FMT_BB "\n", loopInd, newT->bbNum); + optLoopTable[loopInd].lpEntry = newT; + } - // If any loops nested in "loopInd" have the same head and entry as "loopInd", - // it must be the case that they were also do-while's (since "h" fell through to the entry). - // The new node "newT" becomes the head of such loops. - // - for (unsigned char childLoop = optLoopTable[loopInd].lpChild; // - childLoop != BasicBlock::NOT_IN_LOOP; // - childLoop = optLoopTable[childLoop].lpSibling) - { - if (optLoopTable[childLoop].lpEntry == origE && optLoopTable[childLoop].lpHead == h && - newT->bbJumpKind == BBJ_NONE && newT->bbNext == origE) + // If any loops nested in "loopInd" have the same head and entry as "loopInd", + // it must be the case that they were do-while's (since "h" fell through to the entry). + // The new node "newT" becomes the head of such loops. + for (unsigned char childLoop = optLoopTable[loopInd].lpChild; // + childLoop != BasicBlock::NOT_IN_LOOP; // + childLoop = optLoopTable[childLoop].lpSibling) { - optUpdateLoopHead(childLoop, h, newT); + if ((optLoopTable[childLoop].lpEntry == origE) && (optLoopTable[childLoop].lpHead == h) && + (newT->bbJumpKind == BBJ_NONE) && (newT->bbNext == origE)) + { + optUpdateLoopHead(childLoop, h, newT); - // Fix pred list here, so when we walk preds of child loop tops - // we see the right blocks. - // - fgReplacePred(optLoopTable[childLoop].lpTop, h, newT); + // Fix pred list here, so when we walk preds of child loop tops + // we see the right blocks. + // + fgReplacePred(optLoopTable[childLoop].lpTop, h, newT); + } } } + else if (option == LoopCanonicalizationOption::Outer) + { + JITDUMP("in optCanonicalizeLoop (outer): " FMT_BB " is outside of loop " FMT_LP "\n", newT->bbNum, loopInd); + + // If we are lifting outer backeges, then newT belongs to our parent loop + // + newT->bbNatLoopNum = optLoopTable[loopInd].lpParent; + + // newT is now the header of this loop + // + optUpdateLoopHead(loopInd, h, newT); + } + return true; } From 6154792f02370048dd12d15b2bf24157a58a0579 Mon Sep 17 00:00:00 2001 From: Theodore Tsirpanis Date: Fri, 17 Jun 2022 04:46:59 +0300 Subject: [PATCH 177/337] Use `Array.Empty()` in `System.Reflection.Metadata`. (#70862) It is now available in all frameworks it targets. --- .../src/System.Reflection.Metadata.csproj | 1 - .../Reflection/Internal/Utilities/BlobUtilities.cs | 2 +- .../Reflection/Internal/Utilities/EmptyArray.cs | 12 ------------ .../System/Reflection/Metadata/Internal/BlobHeap.cs | 2 +- 4 files changed, 2 insertions(+), 15 deletions(-) delete mode 100644 src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/EmptyArray.cs diff --git a/src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj b/src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj index 78b858d6274499..cdd0d0a097cc13 100644 --- a/src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj +++ b/src/libraries/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj @@ -109,7 +109,6 @@ System.Reflection.PortableExecutable.ManagedPEBuilder - diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BlobUtilities.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BlobUtilities.cs index dd990afe48b5b8..ed3e2b07625b2a 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BlobUtilities.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BlobUtilities.cs @@ -16,7 +16,7 @@ public static byte[] ReadBytes(byte* buffer, int byteCount) { if (byteCount == 0) { - return EmptyArray.Instance; + return Array.Empty(); } byte[] result = new byte[byteCount]; diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/EmptyArray.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/EmptyArray.cs deleted file mode 100644 index 7435587d99d546..00000000000000 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/EmptyArray.cs +++ /dev/null @@ -1,12 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Reflection.Internal -{ - internal static class EmptyArray - { -#pragma warning disable CA1825 // Array.Empty() doesn't exist in all configurations - internal static readonly T[] Instance = new T[0]; -#pragma warning restore CA1825 - } -} diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Internal/BlobHeap.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Internal/BlobHeap.cs index efa817e70240ec..00bac867344a61 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Internal/BlobHeap.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/Internal/BlobHeap.cs @@ -98,7 +98,7 @@ internal byte[] GetBytes(BlobHandle handle) int numberOfBytes = Block.PeekCompressedInteger(offset, out bytesRead); if (numberOfBytes == BlobReader.InvalidCompressedInteger) { - return EmptyArray.Instance; + return Array.Empty(); } return Block.PeekBytes(offset + bytesRead, numberOfBytes); From eca86deef0f485bec5f3c8230ef4f7f3ad157559 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Thu, 16 Jun 2022 18:51:54 -0700 Subject: [PATCH 178/337] Delete StaticallyLinked property from Microsoft.NETCore.Native.Unix.props (#70854) This option has many issues. Anybody trying to experiment with static linking can add `` into the local file. --- .../BuildIntegration/Microsoft.NETCore.Native.Unix.props | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.props b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.props index b150bf6392cb2e..c8ef6487bd504d 100644 --- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.props +++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.props @@ -89,7 +89,6 @@ The .NET Foundation licenses this file to you under the MIT license. - From b6e2e1c815bdb9e442fda515521945d3c07da371 Mon Sep 17 00:00:00 2001 From: Carlos Sanchez <1175054+carlossanlop@users.noreply.github.com> Date: Thu, 16 Jun 2022 18:57:07 -0700 Subject: [PATCH 179/337] Restore ArchivingUtils.AttemptSetLastWriteTime (#70617) --- src/libraries/Common/src/System/IO/Archiving.Utils.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Common/src/System/IO/Archiving.Utils.cs b/src/libraries/Common/src/System/IO/Archiving.Utils.cs index 9a46774c430b99..8335dbd26edbc3 100644 --- a/src/libraries/Common/src/System/IO/Archiving.Utils.cs +++ b/src/libraries/Common/src/System/IO/Archiving.Utils.cs @@ -83,7 +83,7 @@ public static void AttemptSetLastWriteTime(string destinationFileName, DateTimeO { File.SetLastWriteTime(destinationFileName, lastWriteTime.DateTime); } - catch (UnauthorizedAccessException) + catch { // Some OSes like Android (#35374) might not support setting the last write time, the extraction should not fail because of that } From d940a01a962cd19c01bb7fe627af2467f0d485bf Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Thu, 16 Jun 2022 19:02:09 -0700 Subject: [PATCH 180/337] Fix GC stress failure in LoaderAllocator::CompareExchangeValueInHandle (#70832) InterlockedCompareExchangeT has to be called on a raw Object* to make the GC stress infrastructure happy. --- src/coreclr/vm/loaderallocator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/loaderallocator.cpp b/src/coreclr/vm/loaderallocator.cpp index 43311f87c97eb5..b816bf716d0801 100644 --- a/src/coreclr/vm/loaderallocator.cpp +++ b/src/coreclr/vm/loaderallocator.cpp @@ -920,7 +920,7 @@ OBJECTREF LoaderAllocator::CompareExchangeValueInHandle(LOADERHANDLE handle, OBJ { OBJECTREF *ptr = (OBJECTREF *)(((UINT_PTR)handle) - 1); - gc.previous = InterlockedCompareExchangeT(ptr, gc.value, gc.compare); + gc.previous = ObjectToOBJECTREF(InterlockedCompareExchangeT((Object **)ptr, OBJECTREFToObject(gc.value), OBJECTREFToObject(gc.compare))); if (gc.previous == gc.compare) { ErectWriteBarrier(ptr, gc.value); From 3b1a36e5c5d6ba0a7452e70be9d5aad5f7515dc1 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Thu, 16 Jun 2022 23:07:11 -0400 Subject: [PATCH 181/337] Small performance cleanups in S.S.Cryptography --- .../X509Certificates/ManagedX509ExtensionProcessor.cs | 2 +- .../Cryptography/X509Certificates/OpenSslPkcs12Reader.cs | 1 + .../X509Certificates/RSAPkcs1X509SignatureGenerator.cs | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ManagedX509ExtensionProcessor.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ManagedX509ExtensionProcessor.cs index 1749598a6f5472..888638dc24fc44 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ManagedX509ExtensionProcessor.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ManagedX509ExtensionProcessor.cs @@ -31,7 +31,7 @@ public virtual void DecodeX509KeyUsageExtension(byte[] encoded, out X509KeyUsage try { - AsnReader reader = new AsnReader(encoded, AsnEncodingRules.BER); + AsnValueReader reader = new AsnValueReader(encoded, AsnEncodingRules.BER); keyUsagesAsn = reader.ReadNamedBitListValue(); reader.ThrowIfNotEmpty(); } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslPkcs12Reader.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslPkcs12Reader.cs index 79b7aed738772c..7ce3eb5f319734 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslPkcs12Reader.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslPkcs12Reader.cs @@ -57,6 +57,7 @@ protected override AsymmetricAlgorithm LoadKey(ReadOnlyMemory pkcs8) if (bytesRead != pkcs8.Length) { + key.Dispose(); throw new CryptographicException(SR.Cryptography_Der_Invalid_Encoding); } diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPkcs1X509SignatureGenerator.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPkcs1X509SignatureGenerator.cs index f49eb588eabecd..bcde068cb8cfdd 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPkcs1X509SignatureGenerator.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/RSAPkcs1X509SignatureGenerator.cs @@ -30,6 +30,7 @@ protected override PublicKey BuildPublicKey() internal static PublicKey BuildPublicKey(RSA rsa) { Oid oid = Oids.RsaOid; + ReadOnlySpan asnNull = new byte[] { 0x05, 0x00 }; // The OID is being passed to everything here because that's what // X509Certificate2.PublicKey does. @@ -39,7 +40,7 @@ internal static PublicKey BuildPublicKey(RSA rsa) // // This is due to one version of the ASN.1 not including OPTIONAL, and that was // the version that got predominately implemented for RSA. Now it's convention. - new AsnEncodedData(oid, stackalloc byte[] { 0x05, 0x00 }), + new AsnEncodedData(oid, asnNull), new AsnEncodedData(oid, rsa.ExportRSAPublicKey())); } From 3b2883b097a773715ca84056885e0ca1488da36e Mon Sep 17 00:00:00 2001 From: Will Smith Date: Thu, 16 Jun 2022 20:57:37 -0700 Subject: [PATCH 182/337] ARM64 - Optimize `i % 2` (#70599) --- src/coreclr/jit/codegenarm64.cpp | 31 +++++++---- src/coreclr/jit/codegenarmarch.cpp | 1 + src/coreclr/jit/gentree.cpp | 5 +- src/coreclr/jit/gtlist.h | 1 + src/coreclr/jit/lowerarmarch.cpp | 84 +++++++++++++++++++----------- 5 files changed, 81 insertions(+), 41 deletions(-) diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index 9bf45ab0ffad7f..5c34b845b0961a 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -10282,18 +10282,34 @@ void CodeGen::genCodeForAddEx(GenTreeOp* tree) // void CodeGen::genCodeForCond(GenTreeOp* tree) { - assert(tree->OperIs(GT_CSNEG_MI)); + assert(tree->OperIs(GT_CSNEG_MI, GT_CNEG_LT)); assert(!(tree->gtFlags & GTF_SET_FLAGS)); genConsumeOperands(tree); - instruction ins; - insCond cond; switch (tree->OperGet()) { case GT_CSNEG_MI: { - ins = INS_csneg; - cond = INS_COND_MI; + instruction ins = INS_csneg; + insCond cond = INS_COND_MI; + + regNumber dstReg = tree->GetRegNum(); + regNumber op1Reg = tree->gtGetOp1()->GetRegNum(); + regNumber op2Reg = tree->gtGetOp2()->GetRegNum(); + + GetEmitter()->emitIns_R_R_R_COND(ins, emitActualTypeSize(tree), dstReg, op1Reg, op2Reg, cond); + break; + } + + case GT_CNEG_LT: + { + instruction ins = INS_cneg; + insCond cond = INS_COND_LT; + + regNumber dstReg = tree->GetRegNum(); + regNumber op1Reg = tree->gtGetOp1()->GetRegNum(); + + GetEmitter()->emitIns_R_R_COND(ins, emitActualTypeSize(tree), dstReg, op1Reg, cond); break; } @@ -10301,11 +10317,6 @@ void CodeGen::genCodeForCond(GenTreeOp* tree) unreached(); } - regNumber dstReg = tree->GetRegNum(); - regNumber op1Reg = tree->gtGetOp1()->GetRegNum(); - regNumber op2Reg = tree->gtGetOp2()->GetRegNum(); - - GetEmitter()->emitIns_R_R_R_COND(ins, emitActualTypeSize(tree), dstReg, op1Reg, op2Reg, cond); genProduceReg(tree); } diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index 0f87d506b2091d..92b3442781664a 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -324,6 +324,7 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode) break; case GT_CSNEG_MI: + case GT_CNEG_LT: genCodeForCond(treeNode->AsOp()); break; #endif // TARGET_ARM64 diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 9e56b90be61a43..0f749b1a7100bc 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -9161,7 +9161,10 @@ GenTreeUseEdgeIterator::GenTreeUseEdgeIterator(GenTree* node) m_state = -1; return; - // Standard unary operators +// Standard unary operators +#ifdef TARGET_ARM64 + case GT_CNEG_LT: +#endif // TARGET_ARM64 case GT_STORE_LCL_VAR: case GT_STORE_LCL_FLD: case GT_NOT: diff --git a/src/coreclr/jit/gtlist.h b/src/coreclr/jit/gtlist.h index a089124825ff93..53a3618100b9e0 100644 --- a/src/coreclr/jit/gtlist.h +++ b/src/coreclr/jit/gtlist.h @@ -219,6 +219,7 @@ GTNODE(AND_NOT , GenTreeOp ,0,GTK_BINOP|DBK_NOTHIR) GTNODE(ADDEX, GenTreeOp ,0,GTK_BINOP|DBK_NOTHIR) // Add with sign/zero extension. GTNODE(BFIZ , GenTreeOp ,0,GTK_BINOP|DBK_NOTHIR) // Bitfield Insert in Zero. GTNODE(CSNEG_MI , GenTreeOp ,0,GTK_BINOP|DBK_NOTHIR) // Conditional select, negate, minus result +GTNODE(CNEG_LT , GenTreeOp ,0,GTK_UNOP|DBK_NOTHIR) // Conditional, negate, signed less than result #endif //----------------------------------------------------------------------------- diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp index 8598efb8adbec9..ed77d2a954f175 100644 --- a/src/coreclr/jit/lowerarmarch.cpp +++ b/src/coreclr/jit/lowerarmarch.cpp @@ -104,6 +104,7 @@ bool Lowering::IsContainableImmed(GenTree* parentNode, GenTree* childNode) const case GT_LE: case GT_GE: case GT_GT: + case GT_CMP: case GT_BOUNDS_CHECK: return emitter::emitIns_valid_imm_for_cmp(immVal, size); case GT_AND: @@ -699,19 +700,7 @@ void Lowering::LowerRotate(GenTree* tree) // Arguments: // tree - the node to lower // -// Return Value: -// A new tree node if it changed. -// // Notes: -// {expr} % {cns} -// Logically turns into: -// let a = {expr} -// if a > 0 then (a & ({cns} - 1)) else -(-a & ({cns} - 1)) -// which then turns into: -// and reg1, reg0, #({cns} - 1) -// negs reg0, reg0 -// and reg0, reg0, #({cns} - 1) -// csneg reg0, reg1, reg0, mi // TODO: We could do this optimization in morph but we do not have // a conditional select op in HIR. At some point, we may // introduce such an op. @@ -722,12 +711,15 @@ void Lowering::LowerModPow2(GenTree* node) GenTree* dividend = mod->gtGetOp1(); GenTree* divisor = mod->gtGetOp2(); + JITDUMP("Lower: optimize X MOD POW2"); + assert(divisor->IsIntegralConstPow2()); const var_types type = mod->TypeGet(); assert((type == TYP_INT) || (type == TYP_LONG)); - ssize_t cnsValue = static_cast(divisor->AsIntConCommon()->IntegralValue()) - 1; + ssize_t divisorCnsValue = static_cast(divisor->AsIntConCommon()->IntegralValue()); + ssize_t divisorCnsValueMinusOne = divisorCnsValue - 1; BlockRange().Remove(divisor); @@ -739,30 +731,62 @@ void Lowering::LowerModPow2(GenTree* node) GenTree* dividend2 = comp->gtClone(dividend); BlockRange().InsertAfter(dividend, dividend2); - GenTreeIntCon* cns = comp->gtNewIconNode(cnsValue, type); + GenTreeIntCon* cns = comp->gtNewIconNode(divisorCnsValueMinusOne, type); BlockRange().InsertAfter(dividend2, cns); GenTree* const trueExpr = comp->gtNewOperNode(GT_AND, type, dividend, cns); BlockRange().InsertAfter(cns, trueExpr); LowerNode(trueExpr); - GenTree* const neg = comp->gtNewOperNode(GT_NEG, type, dividend2); - neg->gtFlags |= GTF_SET_FLAGS; - BlockRange().InsertAfter(trueExpr, neg); - - GenTreeIntCon* cns2 = comp->gtNewIconNode(cnsValue, type); - BlockRange().InsertAfter(neg, cns2); - - GenTree* const falseExpr = comp->gtNewOperNode(GT_AND, type, neg, cns2); - BlockRange().InsertAfter(cns2, falseExpr); - LowerNode(falseExpr); - - mod->ChangeOper(GT_CSNEG_MI); - mod->gtOp1 = trueExpr; - mod->gtOp2 = falseExpr; + if (divisorCnsValue == 2) + { + // {expr} % 2 + // Logically turns into: + // let a = {expr} + // if a < 0 then -(a & 1) else (a & 1) + // which then turns into: + // and reg1, reg0, #1 + // cmp reg0, #0 + // cneg reg0, reg1, lt + + GenTreeIntCon* cnsZero = comp->gtNewIconNode(0, type); + BlockRange().InsertAfter(trueExpr, cnsZero); + + GenTree* const cmp = comp->gtNewOperNode(GT_CMP, type, dividend2, cnsZero); + cmp->gtFlags |= GTF_SET_FLAGS; + BlockRange().InsertAfter(cnsZero, cmp); + LowerNode(cmp); - JITDUMP("Lower: optimize X MOD POW2"); - DISPNODE(mod); + mod->ChangeOper(GT_CNEG_LT); + mod->gtOp1 = trueExpr; + } + else + { + // {expr} % {cns} + // Logically turns into: + // let a = {expr} + // if a > 0 then (a & ({cns} - 1)) else -(-a & ({cns} - 1)) + // which then turns into: + // and reg1, reg0, #({cns} - 1) + // negs reg0, reg0 + // and reg0, reg0, #({cns} - 1) + // csneg reg0, reg1, reg0, mi + + GenTree* const neg = comp->gtNewOperNode(GT_NEG, type, dividend2); + neg->gtFlags |= GTF_SET_FLAGS; + BlockRange().InsertAfter(trueExpr, neg); + + GenTreeIntCon* cns2 = comp->gtNewIconNode(divisorCnsValueMinusOne, type); + BlockRange().InsertAfter(neg, cns2); + + GenTree* const falseExpr = comp->gtNewOperNode(GT_AND, type, neg, cns2); + BlockRange().InsertAfter(cns2, falseExpr); + LowerNode(falseExpr); + + mod->ChangeOper(GT_CSNEG_MI); + mod->gtOp1 = trueExpr; + mod->gtOp2 = falseExpr; + } ContainCheckNode(mod); } From 30379b718d5f8a366a69364ef341f85d100afc29 Mon Sep 17 00:00:00 2001 From: SingleAccretion <62474226+SingleAccretion@users.noreply.github.com> Date: Fri, 17 Jun 2022 12:23:08 +0300 Subject: [PATCH 183/337] Assign proper VNs to "shared constant" CSE defs (#70852) * Assign proper VNs to shared CSE defs They must be those of the original expression, not the "base" constant CSE creates. * Add a test --- src/coreclr/jit/optcse.cpp | 14 +++---- .../JitBlue/Runtime_70790/Runtime_70790.cs | 40 +++++++++++++++++++ .../Runtime_70790/Runtime_70790.csproj | 18 +++++++++ 3 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_70790/Runtime_70790.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_70790/Runtime_70790.csproj diff --git a/src/coreclr/jit/optcse.cpp b/src/coreclr/jit/optcse.cpp index 6bbb6fcb3e0cfa..7b6347e9628eec 100644 --- a/src/coreclr/jit/optcse.cpp +++ b/src/coreclr/jit/optcse.cpp @@ -2962,9 +2962,9 @@ class CSE_Heuristic do { /* Process the next node in the list */ - GenTree* exp = lst->tslTree; - Statement* stmt = lst->tslStmt; - BasicBlock* blk = lst->tslBlock; + GenTree* const exp = lst->tslTree; + Statement* const stmt = lst->tslStmt; + BasicBlock* const blk = lst->tslBlock; /* Advance to the next node in the list */ lst = lst->tslNext; @@ -3212,9 +3212,9 @@ class CSE_Heuristic noway_assert(asg->AsOp()->gtOp2 == val); } - // assign the proper Value Numbers - asg->gtVNPair.SetBoth(ValueNumStore::VNForVoid()); // The GT_ASG node itself is $VN.Void - asg->AsOp()->gtOp1->gtVNPair = val->gtVNPair; // The dest op is the same as 'val' + // Assign the proper Value Numbers. + asg->gtVNPair = ValueNumStore::VNPForVoid(); // The GT_ASG node itself is $VN.Void. + asg->AsOp()->gtOp1->gtVNPair = ValueNumStore::VNPForVoid(); // As is the LHS. noway_assert(asg->AsOp()->gtOp1->gtOper == GT_LCL_VAR); @@ -3263,7 +3263,7 @@ class CSE_Heuristic cseUse->SetDoNotCSE(); } } - cseUse->gtVNPair = val->gtVNPair; // The 'cseUse' is equal to 'val' + cseUse->gtVNPair = exp->gtVNPair; // The 'cseUse' is equal to the original expression. /* Create a comma node for the CSE assignment */ cse = m_pCompiler->gtNewOperNode(GT_COMMA, expTyp, origAsg, cseUse); diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_70790/Runtime_70790.cs b/src/tests/JIT/Regression/JitBlue/Runtime_70790/Runtime_70790.cs new file mode 100644 index 00000000000000..79c2ee29dea431 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_70790/Runtime_70790.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; + +public class Runtime_70790 +{ + private static readonly nint s_intType = typeof(int).TypeHandle.Value; + + public static int Main() + { + RuntimeHelpers.RunClassConstructor(typeof(Runtime_70790).TypeHandle); + + object a = 1u; + object b = 2u; + if (Problem(a, b)) + { + return 101; + } + + return 100; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool Problem(object a, object b) + { + if (a.GetType() == typeof(int)) + { + return true; + } + + JitUse(b.GetType() == typeof(int)); + JitUse(s_intType - 300); + + return false; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + public static void JitUse(T arg) { } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_70790/Runtime_70790.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_70790/Runtime_70790.csproj new file mode 100644 index 00000000000000..c355dd0a2fba61 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_70790/Runtime_70790.csproj @@ -0,0 +1,18 @@ + + + Exe + True + + + + + + + + \ No newline at end of file From a796755292722cbef6e586ce1a2547cf2d49e831 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Fri, 17 Jun 2022 05:26:03 -0400 Subject: [PATCH 184/337] Enable IDE0054 (Use compound assignment) (#70564) * Enable IDE0054 (Use compound assignment) * Update src/libraries/System.Data.Common/src/System/Data/Common/StringStorage.cs Co-authored-by: Tanner Gooding Co-authored-by: Tanner Gooding --- eng/CodeAnalysis.src.globalconfig | 2 +- .../src/System/Runtime/ThunkPool.cs | 2 +- .../src/System/Array.NativeAot.cs | 2 +- ...imeAssembly.GetTypeCore.CaseInsensitive.cs | 2 +- .../ClassConstructorRunner.cs | 2 +- .../MissingMetadataExceptionCreator.cs | 4 +-- .../Runtime/TypeLoader/EETypeCreator.cs | 2 +- ...peLoaderEnvironment.LdTokenResultLookup.cs | 8 ++--- .../TypeLoaderEnvironment.Metadata.cs | 2 +- .../Internal/Runtime/EETypeBuilderHelpers.cs | 2 +- .../Common/ExplicitLayoutValidator.cs | 2 +- .../Common/TypeHashingAlgorithms.cs | 2 +- .../Bundle/Manifest.cs | 2 +- .../Interop.OpenSsl.cs | 2 +- .../Windows/Advapi32/Interop.LsaLookupSids.cs | 2 +- .../Common/src/System/IO/RowConfigReader.cs | 2 +- .../aspnetcore/Http2/Hpack/IntegerDecoder.cs | 4 +-- .../aspnetcore/Http2/Hpack/IntegerEncoder.cs | 4 +-- .../RuntimeBinder/Semantics/Operators.cs | 28 ++++++++--------- .../CSharp/RuntimeBinder/SymbolTable.cs | 2 +- .../Diagnostics/Tracing/StubEnvironment.cs | 2 +- .../src/ServiceProvider.cs | 2 +- .../PatternContexts/PatternContextLinear.cs | 2 +- .../src/OptionsManager.cs | 2 +- .../src/OptionsMonitor.cs | 2 +- .../src/Sgen.cs | 2 +- .../Collections/Concurrent/ConcurrentBag.cs | 4 +-- .../Immutable/ImmutableArray_1.Builder.cs | 4 +-- .../Collections/Immutable/ImmutableArray_1.cs | 4 +-- .../Immutable/ImmutableList_1.Node.cs | 6 ++-- .../Composition/ContractNameServices.cs | 2 +- .../ComposablePartCatalogCollection.cs | 2 +- .../Composition/ReflectionModel/ImportType.cs | 2 +- .../Hosting/Core/CompositionContract.cs | 4 +-- .../Composition/TypedParts/ContractHelpers.cs | 6 ++-- .../TypedParts/Discovery/TypeInspector.cs | 2 +- .../StringAttributeCollection.cs | 2 +- .../src/System/Data/Common/ByteStorage.cs | 2 +- .../System/Data/Common/DataRecordInternal.cs | 4 +-- .../src/System/Data/Common/DecimalStorage.cs | 2 +- .../src/System/Data/Common/DoubleStorage.cs | 2 +- .../src/System/Data/Common/Int16Storage.cs | 2 +- .../src/System/Data/Common/Int32Storage.cs | 2 +- .../src/System/Data/Common/Int64Storage.cs | 2 +- .../src/System/Data/Common/SByteStorage.cs | 2 +- .../Data/Common/SQLTypes/SQLByteStorage.cs | 2 +- .../Data/Common/SQLTypes/SQLDecimalStorage.cs | 2 +- .../Data/Common/SQLTypes/SQLDoubleStorage.cs | 2 +- .../Data/Common/SQLTypes/SQLInt16Storage.cs | 2 +- .../Data/Common/SQLTypes/SQLInt32Storage.cs | 2 +- .../Data/Common/SQLTypes/SQLInt64Storage.cs | 2 +- .../Data/Common/SQLTypes/SQLMoneyStorage.cs | 2 +- .../Data/Common/SQLTypes/SQLSingleStorage.cs | 2 +- .../Data/Common/SQLTypes/SQLStringStorage.cs | 4 +-- .../src/System/Data/Common/SingleStorage.cs | 2 +- .../src/System/Data/Common/StringStorage.cs | 4 +-- .../src/System/Data/Common/UInt16Storage.cs | 2 +- .../src/System/Data/Common/UInt32Storage.cs | 2 +- .../src/System/Data/Common/UInt64Storage.cs | 2 +- .../src/System/Data/SQLTypes/SQLDecimal.cs | 2 +- .../src/System/Data/SQLTypes/SQLMoney.cs | 2 +- .../src/System/Data/XMLSchema.cs | 6 ++-- .../src/System/Data/xmlsaver.cs | 2 +- .../src/System/Data/Odbc/OdbcConnection.cs | 2 +- .../System/Data/Odbc/OdbcMetaDataFactory.cs | 8 ++--- .../Diagnostics/Reader/EventLogReader.cs | 2 +- .../Diagnostics/Reader/EventMetadata.cs | 2 +- .../Diagnostics/SharedPerformanceCounter.cs | 4 +-- .../src/System/Diagnostics/Process.NonUap.cs | 2 +- .../AccountManagement/AD/RangeRetriever.cs | 2 +- .../AccountManagement/AD/SDSUtils.cs | 2 +- .../ActiveDirectorySiteLinkCollection.cs | 2 +- .../ActiveDirectory/Locator.cs | 2 +- .../src/System/Drawing/ClientUtils.cs | 4 +-- .../Compression/DeflateManaged/InputBuffer.cs | 2 +- .../System/IO/Ports/SerialStream.Windows.cs | 4 +-- .../Expressions/Interpreter/LightCompiler.cs | 2 +- .../Partitioning/PartitionedDataSource.cs | 2 +- .../QueryOperators/Unary/SortQueryOperator.cs | 2 +- .../src/System/Linq/ParallelEnumerable.cs | 4 +-- .../System/Management/ManagementDateTime.cs | 30 +++++++++---------- .../src/System/Management/ManagementPath.cs | 2 +- .../src/System/Management/ManagementQuery.cs | 4 +-- .../src/System/Management/PropertySet.cs | 4 +-- .../src/System/Management/QualifierSet.cs | 8 ++--- .../src/System/Management/WMIGenerator.cs | 18 +++++------ .../Http/Headers/AuthenticationHeaderValue.cs | 18 +++++------ .../Net/Http/Headers/BaseHeaderParser.cs | 2 +- .../Http/Headers/CacheControlHeaderValue.cs | 8 ++--- .../Headers/ContentDispositionHeaderValue.cs | 2 +- .../Http/Headers/ContentRangeHeaderValue.cs | 20 ++++++------- .../Net/Http/Headers/EntityTagHeaderValue.cs | 6 ++-- .../Net/Http/Headers/HeaderUtilities.cs | 4 +-- .../Net/Http/Headers/MediaTypeHeaderValue.cs | 6 ++-- .../Net/Http/Headers/NameValueHeaderValue.cs | 18 +++++------ .../NameValueWithParametersHeaderValue.cs | 2 +- .../Net/Http/Headers/ProductHeaderValue.cs | 10 +++---- .../Http/Headers/ProductInfoHeaderParser.cs | 2 +- .../Http/Headers/ProductInfoHeaderValue.cs | 6 ++-- .../Http/Headers/RangeConditionHeaderValue.cs | 2 +- .../Net/Http/Headers/RangeHeaderValue.cs | 8 ++--- .../Net/Http/Headers/RangeItemHeaderValue.cs | 12 ++++---- .../Http/Headers/RetryConditionHeaderValue.cs | 4 +-- .../Headers/StringWithQualityHeaderValue.cs | 14 ++++----- .../Http/Headers/TransferCodingHeaderValue.cs | 2 +- .../System/Net/Http/Headers/ViaHeaderValue.cs | 20 ++++++------- .../Net/Http/Headers/WarningHeaderValue.cs | 16 +++++----- .../src/System/Net/Http/HttpRuleParser.cs | 2 +- .../Net/Windows/HttpResponseStream.Windows.cs | 2 +- .../src/System/Net/Mail/MailPriority.cs | 2 +- .../src/System/Net/FtpControlStream.cs | 3 +- .../System/Net/WebSockets/ManagedWebSocket.cs | 2 +- .../src/System/IO/DirectoryInfo.cs | 2 +- .../src/System/IO/FileInfo.cs | 2 +- .../src/System/Text/ASCIIUtility.cs | 4 +-- .../Serialization/ExtensionDataReader.cs | 2 +- .../Serialization/Json/JsonWriterDelegator.cs | 2 +- .../XmlObjectSerializerReadContext.cs | 4 +-- .../src/System/Xml/ArrayHelper.cs | 5 ++-- .../src/System/Xml/XmlBaseReader.cs | 2 +- .../src/System/Xml/XmlBinaryWriter.cs | 8 ++--- .../src/System/Xml/XmlDictionaryReader.cs | 2 +- .../src/System/Xml/XmlDictionaryWriter.cs | 2 +- .../System.Private.Uri/src/System/UriExt.cs | 8 ++--- .../src/System/Xml/BinaryXml/SqlUtils.cs | 4 +-- .../System/Xml/BinaryXml/XmlBinaryReader.cs | 18 +++++------ .../src/System/Xml/Core/XmlTextReaderImpl.cs | 2 +- .../System/Xml/Core/XmlTextReaderImplAsync.cs | 2 +- .../System/Xml/Dom/DocumentSchemaValidator.cs | 2 +- .../src/System/Xml/Schema/ContentValidator.cs | 2 +- .../src/System/Xml/Schema/FacetChecker.cs | 4 +-- .../Serialization/XmlReflectionImporter.cs | 2 +- .../Xml/Serialization/XmlSchemaImporter.cs | 2 +- .../Serialization/XmlSerializationWriter.cs | 2 +- .../src/System/Xml/Xsl/XPathConvert.cs | 2 +- .../Internal/Utilities/BitArithmetic.cs | 4 +-- .../PEReader.EmbeddedPortablePdb.cs | 2 +- .../Reflection/PortableExecutable/PEReader.cs | 4 +-- .../Runtime/Caching/CacheMemoryMonitor.cs | 2 +- .../Numerics/BigIntegerCalculator.DivRem.cs | 6 ++-- .../Numerics/BigIntegerCalculator.PowMod.cs | 16 +++++----- .../Formatters/Binary/BinaryObjectReader.cs | 2 +- .../Formatters/Binary/BinaryParser.cs | 2 +- .../Cryptography/Pkcs/EnvelopedCms.cs | 2 +- .../Security/Cryptography/Xml/SignedXml.cs | 2 +- ...inPal.Windows.GetChainStatusInformation.cs | 4 +-- .../X509Certificates/StorePal.iOS.cs | 2 +- .../Syndication/Atom10FeedFormatter.cs | 6 ++-- .../Syndication/Rss20FeedFormatter.cs | 2 +- .../src/System/ServiceProcess/ServiceBase.cs | 2 +- .../Synthesis/AudioFormatConverter.cs | 2 +- .../src/Internal/Synthesis/SSmlParser.cs | 2 +- .../SrgsGrammar/SrgsElementFactory.cs | 2 +- .../Recognition/SrgsGrammar/SrgsGrammar.cs | 2 +- .../src/System/Text/EUCJPEncoding.cs | 12 ++++---- .../src/System/Text/ISO2022Encoding.cs | 12 ++++---- .../src/System/Text/Json/BitStack.cs | 2 +- .../src/System/Threading/Barrier.cs | 2 +- .../Reflection/Emit/FieldBuilder.Mono.cs | 2 +- .../System/Reflection/Emit/MonoArrayMethod.cs | 4 +-- .../src/System/String.Mono.cs | 4 +-- src/mono/wasm/host/Options.cs | 4 +-- 162 files changed, 344 insertions(+), 346 deletions(-) diff --git a/eng/CodeAnalysis.src.globalconfig b/eng/CodeAnalysis.src.globalconfig index 24427d2df83ba3..ef23d84e18ff26 100644 --- a/eng/CodeAnalysis.src.globalconfig +++ b/eng/CodeAnalysis.src.globalconfig @@ -1458,7 +1458,7 @@ dotnet_diagnostic.IDE0052.severity = suggestion dotnet_diagnostic.IDE0053.severity = silent # IDE0054: Use compound assignment -dotnet_diagnostic.IDE0054.severity = suggestion +dotnet_diagnostic.IDE0054.severity = warning # IDE0055: Fix formatting dotnet_diagnostic.IDE0055.severity = suggestion diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ThunkPool.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ThunkPool.cs index 76234dde14e4d7..62c26ccd305efd 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ThunkPool.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/ThunkPool.cs @@ -217,7 +217,7 @@ public unsafe IntPtr AllocateThunk() int thunkIndex = (int)(((nuint)(nint)nextAvailableThunkPtr) - ((nuint)(nint)nextAvailableThunkPtr & ~Constants.PageSizeMask)); Debug.Assert((thunkIndex % Constants.ThunkDataSize) == 0); - thunkIndex = thunkIndex / Constants.ThunkDataSize; + thunkIndex /= Constants.ThunkDataSize; IntPtr thunkAddress = InternalCalls.RhpGetThunkStubsBlockAddress(nextAvailableThunkPtr) + thunkIndex * Constants.ThunkCodeSize; diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs index 69b2f50c74f530..08725d57447742 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs @@ -897,7 +897,7 @@ internal static unsafe Array NewMultiDimArray(EETypePtr eeType, int* pLengths, i throw new OverflowException(); if (length > MaxLength) maxArrayDimensionLengthOverflow = true; - totalLength = totalLength * (ulong)length; + totalLength *= (ulong)length; if (totalLength > int.MaxValue) throw new OutOfMemoryException(); // "Array dimensions exceeded supported range." } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.GetTypeCore.CaseInsensitive.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.GetTypeCore.CaseInsensitive.cs index d9f9c5f7148e25..48a2198d49bfe9 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.GetTypeCore.CaseInsensitive.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/Runtime/Assemblies/NativeFormat/NativeFormatRuntimeAssembly.GetTypeCore.CaseInsensitive.cs @@ -90,7 +90,7 @@ private LowLevelDictionary CreateCaseInsensitiveTypeDictionary( { string ns = namespaceHandle.ToNamespaceName(reader); if (ns.Length != 0) - ns = ns + "."; + ns += "."; ns = ns.ToLowerInvariant(); NamespaceDefinition namespaceDefinition = namespaceHandle.GetNamespaceDefinition(reader); diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/ClassConstructorRunner.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/ClassConstructorRunner.cs index a3847253fa3f07..6db9cb646f91a0 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/ClassConstructorRunner.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/ClassConstructorRunner.cs @@ -540,7 +540,7 @@ public static unsafe string ToHexStringUnsignedLong(ulong u, bool zeroPrepad, in for (; i >= 0; i--) { chars[i] = GetHexChar((uint)(u % 16)); - u = u / 16; + u /= 16; if ((i == 0) || (!zeroPrepad && (u == 0))) break; diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/PayForPlayExperience/MissingMetadataExceptionCreator.cs b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/PayForPlayExperience/MissingMetadataExceptionCreator.cs index 8b25905240d7bd..818ba99f82a950 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/PayForPlayExperience/MissingMetadataExceptionCreator.cs +++ b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/PayForPlayExperience/MissingMetadataExceptionCreator.cs @@ -249,7 +249,7 @@ internal static string ToDisplayStringIfAvailable(this Type type, List gene { genericParameterOffsets.Add(s.Length); if (genericArgCount > 0) - s = s + ","; + s += ","; } s += "]"; } @@ -283,7 +283,7 @@ private static string CreateConstructedGenericTypeStringIfAvailable(Type generic // Similarly, if we found too few, add them at the end. while (genericTypeArguments.Length > genericParameterOffsets.Count) { - genericTypeDefinitionString = genericTypeDefinitionString + ","; + genericTypeDefinitionString += ","; genericParameterOffsets.Add(genericTypeDefinitionString.Length); } diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/EETypeCreator.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/EETypeCreator.cs index f5bdf03faa20ad..c16a125c3474e4 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/EETypeCreator.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/EETypeCreator.cs @@ -941,7 +941,7 @@ private static unsafe int CreateGCDesc(LowLevelList bitfield, int size, bo } else { - seriesSize = seriesSize - size; + seriesSize -= size; *ptr-- = (void*)seriesOffset; *ptr-- = (void*)seriesSize; } diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.LdTokenResultLookup.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.LdTokenResultLookup.cs index 1c1da35553b880..fd332cf1b751de 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.LdTokenResultLookup.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.LdTokenResultLookup.cs @@ -209,7 +209,7 @@ public unsafe RuntimeFieldHandle GetRuntimeFieldHandleForComponents(RuntimeTypeH fieldData->FieldName = fieldName; // Special flag (lowest bit set) in the handle value to indicate it was dynamically allocated - runtimeFieldHandleValue = runtimeFieldHandleValue + 1; + runtimeFieldHandleValue++; runtimeFieldHandle = *(RuntimeFieldHandle*)&runtimeFieldHandleValue; _runtimeFieldHandles.Add(key, runtimeFieldHandle); @@ -232,7 +232,7 @@ private unsafe bool TryGetDynamicRuntimeFieldHandleComponents(RuntimeFieldHandle // Special flag in the handle value to indicate it was dynamically allocated Debug.Assert((runtimeFieldHandleValue.ToInt64() & 0x1) == 0x1); - runtimeFieldHandleValue = runtimeFieldHandleValue - 1; + runtimeFieldHandleValue--; DynamicFieldHandleInfo* fieldData = (DynamicFieldHandleInfo*)runtimeFieldHandleValue.ToPointer(); declaringTypeHandle = *(RuntimeTypeHandle*)&(fieldData->DeclaringType); @@ -317,7 +317,7 @@ public unsafe RuntimeMethodHandle GetRuntimeMethodHandleForComponents(RuntimeTyp } // Special flag in the handle value to indicate it was dynamically allocated, and doesn't point into the InvokeMap blob - runtimeMethodHandleValue = runtimeMethodHandleValue + 1; + runtimeMethodHandleValue++; runtimeMethodHandle = * (RuntimeMethodHandle*)&runtimeMethodHandleValue; _runtimeMethodHandles.Add(key, runtimeMethodHandle); @@ -344,7 +344,7 @@ private unsafe bool TryGetDynamicRuntimeMethodHandleComponents(RuntimeMethodHand Debug.Assert((runtimeMethodHandleValue.ToInt64() & 0x1) == 0x1); // Special flag in the handle value to indicate it was dynamically allocated, and doesn't point into the InvokeMap blob - runtimeMethodHandleValue = runtimeMethodHandleValue - 1; + runtimeMethodHandleValue--; DynamicMethodHandleInfo* methodData = (DynamicMethodHandleInfo*)runtimeMethodHandleValue.ToPointer(); declaringTypeHandle = *(RuntimeTypeHandle*)&(methodData->DeclaringType); diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.Metadata.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.Metadata.cs index a0c3379a3efb08..7c619907610f79 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.Metadata.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.Metadata.cs @@ -417,7 +417,7 @@ public static unsafe IntPtr TryGetStaticClassConstructionContext(RuntimeTypeHand // what we have now is the base address of the non-gc statics of the type // what we need is the cctor context, which is just before that - ptr = ptr - sizeof(System.Runtime.CompilerServices.StaticClassConstructionContext); + ptr -= sizeof(System.Runtime.CompilerServices.StaticClassConstructionContext); return (IntPtr)ptr; } diff --git a/src/coreclr/tools/Common/Internal/Runtime/EETypeBuilderHelpers.cs b/src/coreclr/tools/Common/Internal/Runtime/EETypeBuilderHelpers.cs index dd34d85aaa5697..a225665dcee12b 100644 --- a/src/coreclr/tools/Common/Internal/Runtime/EETypeBuilderHelpers.cs +++ b/src/coreclr/tools/Common/Internal/Runtime/EETypeBuilderHelpers.cs @@ -121,7 +121,7 @@ internal static uint ComputeValueTypeFieldPaddingFieldValue(uint padding, uint a while ((alignment & 1) == 0) { alignmentLog2++; - alignment = alignment >> 1; + alignment >>= 1; } Debug.Assert(alignment == 1); diff --git a/src/coreclr/tools/Common/TypeSystem/Common/ExplicitLayoutValidator.cs b/src/coreclr/tools/Common/TypeSystem/Common/ExplicitLayoutValidator.cs index c537f6ea4571e2..838dd7038d33b5 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/ExplicitLayoutValidator.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/ExplicitLayoutValidator.cs @@ -233,7 +233,7 @@ private void SetFieldLayout(List fieldLayoutInterval, int o previousInterval.EndSentinel = newInterval.EndSentinel; fieldLayoutInterval[newIntervalLocation - 1] = previousInterval; - newIntervalLocation = newIntervalLocation - 1; + newIntervalLocation--; } else { diff --git a/src/coreclr/tools/Common/TypeSystem/Common/TypeHashingAlgorithms.cs b/src/coreclr/tools/Common/TypeSystem/Common/TypeHashingAlgorithms.cs index 6b3d37851cee66..5904397c4a0152 100644 --- a/src/coreclr/tools/Common/TypeSystem/Common/TypeHashingAlgorithms.cs +++ b/src/coreclr/tools/Common/TypeSystem/Common/TypeHashingAlgorithms.cs @@ -125,7 +125,7 @@ private static string IntToString(int arg) while (arg != 0) { sb.Append((char)('0' + (arg % 10))); - arg = arg / 10; + arg /= 10; } // Reverse the string diff --git a/src/installer/managed/Microsoft.NET.HostModel/Bundle/Manifest.cs b/src/installer/managed/Microsoft.NET.HostModel/Bundle/Manifest.cs index 5d58732cb7594c..cfc68b0cf9b6ec 100644 --- a/src/installer/managed/Microsoft.NET.HostModel/Bundle/Manifest.cs +++ b/src/installer/managed/Microsoft.NET.HostModel/Bundle/Manifest.cs @@ -139,7 +139,7 @@ private string GenerateDeterministicId() public long Write(BinaryWriter writer) { - BundleID = BundleID ?? GenerateDeterministicId(); + BundleID ??= GenerateDeterministicId(); long startOffset = writer.BaseStream.Position; diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs index a72275a75900fc..298b250b5ecbab 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs @@ -111,7 +111,7 @@ private static SslProtocols CalculateEffectiveProtocols(SslAuthenticationOptions if (protocols != SslProtocols.None && CipherSuitesPolicyPal.WantsTls13(protocols)) { - protocols = protocols & (~SslProtocols.Tls13); + protocols &= ~SslProtocols.Tls13; } } else if (CipherSuitesPolicyPal.WantsTls13(protocols) && diff --git a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.LsaLookupSids.cs b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.LsaLookupSids.cs index ce84a734d480b1..24abe5323e5bd4 100644 --- a/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.LsaLookupSids.cs +++ b/src/libraries/Common/src/Interop/Windows/Advapi32/Interop.LsaLookupSids.cs @@ -41,7 +41,7 @@ public static unsafe void InitializeReferencedDomainsList(this SafeLsaMemoryHand if (domainList.Domains != IntPtr.Zero) { Interop.LSA_TRUST_INFORMATION* pTrustInformation = (Interop.LSA_TRUST_INFORMATION*)domainList.Domains; - pTrustInformation = pTrustInformation + domainList.Entries; + pTrustInformation += domainList.Entries; long bufferSize = (byte*)pTrustInformation - pRdl; System.Diagnostics.Debug.Assert(bufferSize > 0, "bufferSize > 0"); diff --git a/src/libraries/Common/src/System/IO/RowConfigReader.cs b/src/libraries/Common/src/System/IO/RowConfigReader.cs index 571aa9afd9e8a3..b9b78f30a433f0 100644 --- a/src/libraries/Common/src/System/IO/RowConfigReader.cs +++ b/src/libraries/Common/src/System/IO/RowConfigReader.cs @@ -141,7 +141,7 @@ private bool TryFindNextKeyOccurrence(string key, int startIndex, out int keyInd } } - startIndex = startIndex + key.Length; + startIndex += key.Length; } } diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/IntegerDecoder.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/IntegerDecoder.cs index 34ab1d294ec900..b717b3d4d83d33 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/IntegerDecoder.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/IntegerDecoder.cs @@ -73,7 +73,7 @@ public bool TryDecode(byte b, out int result) throw new HPackDecodingException(SR.net_http_hpack_bad_integer); } - _i = _i + ((b & 0x7f) << _m); + _i += ((b & 0x7f) << _m); // If the addition overflowed, the result will be negative. if (_i < 0) @@ -81,7 +81,7 @@ public bool TryDecode(byte b, out int result) throw new HPackDecodingException(SR.net_http_hpack_bad_integer); } - _m = _m + 7; + _m += 7; if ((b & 128) == 0) { diff --git a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/IntegerEncoder.cs b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/IntegerEncoder.cs index b25b218522bab7..22719673ffc2c8 100644 --- a/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/IntegerEncoder.cs +++ b/src/libraries/Common/src/System/Net/Http/aspnetcore/Http2/Hpack/IntegerEncoder.cs @@ -50,7 +50,7 @@ public static bool Encode(int value, int numBits, Span destination, out in return false; } - value = value - ((1 << numBits) - 1); + value -= ((1 << numBits) - 1); int i = 1; while (value >= 128) @@ -63,7 +63,7 @@ public static bool Encode(int value, int numBits, Span destination, out in return false; } - value = value / 128; + value /= 128; } destination[i++] = (byte)value; diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Operators.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Operators.cs index d11df5adba186c..f730892b1b70f7 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Operators.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Semantics/Operators.cs @@ -245,11 +245,11 @@ private bool GetStandardAndLiftedBinopSignatures(List rgbofs, BinO switch (GetConvKind(info.ptRaw1, bos.pt1)) { default: - grflt = grflt | LiftFlags.Convert1; + grflt |= LiftFlags.Convert1; break; case ConvKind.Implicit: case ConvKind.Identity: - grflt = grflt | LiftFlags.Lift1; + grflt |= LiftFlags.Lift1; break; } break; @@ -272,11 +272,11 @@ private bool GetStandardAndLiftedBinopSignatures(List rgbofs, BinO switch (GetConvKind(info.ptRaw1, bos.pt1)) { default: - grflt = grflt | LiftFlags.Convert1; + grflt |= LiftFlags.Convert1; break; case ConvKind.Implicit: case ConvKind.Identity: - grflt = grflt | LiftFlags.Lift1; + grflt |= LiftFlags.Lift1; break; } break; @@ -330,11 +330,11 @@ private bool GetStandardAndLiftedBinopSignatures(List rgbofs, BinO switch (GetConvKind(info.ptRaw2, bos.pt2)) { default: - grflt = grflt | LiftFlags.Convert2; + grflt |= LiftFlags.Convert2; break; case ConvKind.Implicit: case ConvKind.Identity: - grflt = grflt | LiftFlags.Lift2; + grflt |= LiftFlags.Lift2; break; } break; @@ -357,11 +357,11 @@ private bool GetStandardAndLiftedBinopSignatures(List rgbofs, BinO switch (GetConvKind(info.ptRaw2, bos.pt2)) { default: - grflt = grflt | LiftFlags.Convert2; + grflt |= LiftFlags.Convert2; break; case ConvKind.Implicit: case ConvKind.Identity: - grflt = grflt | LiftFlags.Lift2; + grflt |= LiftFlags.Lift2; break; } break; @@ -750,7 +750,7 @@ private bool CanConvertArg1(BinOpArgInfo info, CType typeDst, out LiftFlags pgrf if (info.type2 is NullableType) { - pgrflt = pgrflt | LiftFlags.Lift2; + pgrflt |= LiftFlags.Lift2; ptypeSig2 = TypeManager.GetNullable(info.typeRaw2); } else @@ -785,7 +785,7 @@ private bool CanConvertArg2(BinOpArgInfo info, CType typeDst, out LiftFlags pgrf if (info.type1 is NullableType) { - pgrflt = pgrflt | LiftFlags.Lift1; + pgrflt |= LiftFlags.Lift1; ptypeSig1 = TypeManager.GetNullable(info.typeRaw1); } else @@ -809,7 +809,7 @@ private static void RecordBinOpSigFromArgs(List prgbofs, BinOpArgI if (info.type1 != info.typeRaw1) { Debug.Assert(info.type1 is NullableType); - grflt = grflt | LiftFlags.Lift1; + grflt |= LiftFlags.Lift1; typeSig1 = TypeManager.GetNullable(info.typeRaw1); } else @@ -820,7 +820,7 @@ private static void RecordBinOpSigFromArgs(List prgbofs, BinOpArgI if (info.type2 != info.typeRaw2) { Debug.Assert(info.type2 is NullableType); - grflt = grflt | LiftFlags.Lift2; + grflt |= LiftFlags.Lift2; typeSig2 = TypeManager.GetNullable(info.typeRaw2); } else @@ -1482,11 +1482,11 @@ private bool FindApplicableSignatures( switch (GetConvKind(ptRaw, uos.pt)) { default: - grflt = grflt | LiftFlags.Convert1; + grflt |= LiftFlags.Convert1; break; case ConvKind.Implicit: case ConvKind.Identity: - grflt = grflt | LiftFlags.Lift1; + grflt |= LiftFlags.Lift1; break; } diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/SymbolTable.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/SymbolTable.cs index c2056e5b0d2c32..b2f31a5eaf56dd 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/SymbolTable.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/SymbolTable.cs @@ -213,7 +213,7 @@ private static void AddNamesInInheritanceHierarchy(string name, List inher else if (member is EventInfo e) { // Store events until after all fields - (events = events ?? new List()).Add(e); + (events ??= new List()).Add(e); } } while (memberEn.MoveNext()); diff --git a/src/libraries/Microsoft.Diagnostics.Tracing.EventSource.Redist/src/Microsoft/Diagnostics/Tracing/StubEnvironment.cs b/src/libraries/Microsoft.Diagnostics.Tracing.EventSource.Redist/src/Microsoft/Diagnostics/Tracing/StubEnvironment.cs index 11bb615d361fdc..7e1a49cff5c084 100644 --- a/src/libraries/Microsoft.Diagnostics.Tracing.EventSource.Redist/src/Microsoft/Diagnostics/Tracing/StubEnvironment.cs +++ b/src/libraries/Microsoft.Diagnostics.Tracing.EventSource.Redist/src/Microsoft/Diagnostics/Tracing/StubEnvironment.cs @@ -37,7 +37,7 @@ public static int PopCount(uint value) const uint c3 = 0x_0F0F0F0Fu; const uint c4 = 0x_01010101u; - value = value - ((value >> 1) & c1); + value -= (value >> 1) & c1; value = (value & c2) + ((value >> 2) & c2); value = (((value + (value >> 4)) & c3) * c4) >> 24; diff --git a/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceProvider.cs b/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceProvider.cs index 1b22c432235196..f058108744c602 100644 --- a/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceProvider.cs +++ b/src/libraries/Microsoft.Extensions.DependencyInjection/src/ServiceProvider.cs @@ -64,7 +64,7 @@ internal ServiceProvider(ICollection serviceDescriptors, Serv } catch (Exception e) { - exceptions = exceptions ?? new List(); + exceptions ??= new List(); exceptions.Add(e); } } diff --git a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PatternContexts/PatternContextLinear.cs b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PatternContexts/PatternContextLinear.cs index 070ed6cac80be3..29a53d0e7d0f8a 100644 --- a/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PatternContexts/PatternContextLinear.cs +++ b/src/libraries/Microsoft.Extensions.FileSystemGlobbing/src/Internal/PatternContexts/PatternContextLinear.cs @@ -58,7 +58,7 @@ public override void PushDirectory(DirectoryInfoBase directory) } // directory matches segment, advance position in pattern - frame.SegmentIndex = frame.SegmentIndex + 1; + frame.SegmentIndex++; } PushDataFrame(frame); diff --git a/src/libraries/Microsoft.Extensions.Options/src/OptionsManager.cs b/src/libraries/Microsoft.Extensions.Options/src/OptionsManager.cs index f5a74423c2f533..f6e4294b549310 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/OptionsManager.cs +++ b/src/libraries/Microsoft.Extensions.Options/src/OptionsManager.cs @@ -36,7 +36,7 @@ public OptionsManager(IOptionsFactory factory) /// public virtual TOptions Get(string? name) { - name = name ?? Options.DefaultName; + name ??= Options.DefaultName; if (!_cache.TryGetValue(name, out TOptions? options)) { diff --git a/src/libraries/Microsoft.Extensions.Options/src/OptionsMonitor.cs b/src/libraries/Microsoft.Extensions.Options/src/OptionsMonitor.cs index 3f1c02900f6296..39301d8816e858 100644 --- a/src/libraries/Microsoft.Extensions.Options/src/OptionsMonitor.cs +++ b/src/libraries/Microsoft.Extensions.Options/src/OptionsMonitor.cs @@ -63,7 +63,7 @@ void RegisterSource(IOptionsChangeTokenSource source) private void InvokeChanged(string? name) { - name = name ?? Options.DefaultName; + name ??= Options.DefaultName; _cache.TryRemove(name); TOptions options = Get(name); if (_onChange != null) diff --git a/src/libraries/Microsoft.XmlSerializer.Generator/src/Sgen.cs b/src/libraries/Microsoft.XmlSerializer.Generator/src/Sgen.cs index dc33ea08edceb5..da545994e8e76b 100644 --- a/src/libraries/Microsoft.XmlSerializer.Generator/src/Sgen.cs +++ b/src/libraries/Microsoft.XmlSerializer.Generator/src/Sgen.cs @@ -319,7 +319,7 @@ private static void GenerateFile(List typeNames, string defaultNamespace var allMappings = mappings.ToArray(); bool gac = assembly.GlobalAssemblyCache; - outputDirectory = outputDirectory ?? (gac ? Environment.CurrentDirectory : Path.GetDirectoryName(assembly.Location)); + outputDirectory ??= (gac ? Environment.CurrentDirectory : Path.GetDirectoryName(assembly.Location)); if (!Directory.Exists(outputDirectory)) { diff --git a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentBag.cs b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentBag.cs index 38dd19d79ada51..966cdc5cff0979 100644 --- a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentBag.cs +++ b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentBag.cs @@ -749,8 +749,8 @@ internal void LocalPush(T item, ref long emptyToNonEmptyListTransitionCount) // the bit-masking, because we only do this if tail == int.MaxValue, meaning that all // bits are set, so all of the bits we're keeping will also be set. Thus it's impossible // for the head to end up > than the tail, since you can't set any more bits than all of them. - _headIndex = _headIndex & _mask; - _tailIndex = tail = tail & _mask; + _headIndex &= _mask; + _tailIndex = tail &= _mask; Debug.Assert(_headIndex - _tailIndex <= 0); Interlocked.Exchange(ref _currentOp, (int)Operation.Add); // ensure subsequent reads aren't reordered before this diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Builder.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Builder.cs index 601acadd2181d8..4ab4c163f74d8e 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Builder.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Builder.cs @@ -770,7 +770,7 @@ public int IndexOf(T item, int startIndex, int count, IEqualityComparer? equa Requires.Range(startIndex >= 0 && startIndex < this.Count, nameof(startIndex)); Requires.Range(count >= 0 && startIndex + count <= this.Count, nameof(count)); - equalityComparer = equalityComparer ?? EqualityComparer.Default; + equalityComparer ??= EqualityComparer.Default; if (equalityComparer == EqualityComparer.Default) { return Array.IndexOf(_elements, item, startIndex, count); @@ -867,7 +867,7 @@ public int LastIndexOf(T item, int startIndex, int count, IEqualityComparer? Requires.Range(startIndex >= 0 && startIndex < this.Count, nameof(startIndex)); Requires.Range(count >= 0 && startIndex - count + 1 >= 0, nameof(count)); - equalityComparer = equalityComparer ?? EqualityComparer.Default; + equalityComparer ??= EqualityComparer.Default; if (equalityComparer == EqualityComparer.Default) { return Array.LastIndexOf(_elements, item, startIndex, count); diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.cs index d539592686eadc..e1d6e003b1cb70 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.cs @@ -166,7 +166,7 @@ public int IndexOf(T item, int startIndex, int count, IEqualityComparer? equa Requires.Range(startIndex >= 0 && startIndex < self.Length, nameof(startIndex)); Requires.Range(count >= 0 && startIndex + count <= self.Length, nameof(count)); - equalityComparer = equalityComparer ?? EqualityComparer.Default; + equalityComparer ??= EqualityComparer.Default; if (equalityComparer == EqualityComparer.Default) { return Array.IndexOf(self.array!, item, startIndex, count); @@ -251,7 +251,7 @@ public int LastIndexOf(T item, int startIndex, int count, IEqualityComparer? Requires.Range(startIndex >= 0 && startIndex < self.Length, nameof(startIndex)); Requires.Range(count >= 0 && startIndex - count + 1 >= 0, nameof(count)); - equalityComparer = equalityComparer ?? EqualityComparer.Default; + equalityComparer ??= EqualityComparer.Default; if (equalityComparer == EqualityComparer.Default) { return Array.LastIndexOf(self.array!, item, startIndex, count); diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.Node.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.Node.cs index 061e5cd06fbdb2..bc64c46c910cba 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.Node.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableList_1.Node.cs @@ -636,7 +636,7 @@ internal int BinarySearch(int index, int count, T item, IComparer? comparer) { Requires.Range(index >= 0, nameof(index)); Requires.Range(count >= 0, nameof(count)); - comparer = comparer ?? Comparer.Default; + comparer ??= Comparer.Default; if (this.IsEmpty || count <= 0) { @@ -748,7 +748,7 @@ internal int IndexOf(T item, int index, int count, IEqualityComparer? equalit Requires.Range(count <= this.Count, nameof(count)); Requires.Range(index + count <= this.Count, nameof(count)); - equalityComparer = equalityComparer ?? EqualityComparer.Default; + equalityComparer ??= EqualityComparer.Default; using (var enumerator = new Enumerator(this, startIndex: index, count: count)) { while (enumerator.MoveNext()) @@ -789,7 +789,7 @@ internal int LastIndexOf(T item, int index, int count, IEqualityComparer? equ Requires.Range(count >= 0 && count <= this.Count, nameof(count)); Requires.Argument(index - count + 1 >= 0); - equalityComparer = equalityComparer ?? EqualityComparer.Default; + equalityComparer ??= EqualityComparer.Default; using (var enumerator = new Enumerator(this, startIndex: index, count: count, reversed: true)) { while (enumerator.MoveNext()) diff --git a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/ContractNameServices.cs b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/ContractNameServices.cs index e6c4d6187dc341..d19b5da90618b3 100644 --- a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/ContractNameServices.cs +++ b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/ContractNameServices.cs @@ -32,7 +32,7 @@ private static Dictionary TypeIdentityCache { get { - return typeIdentityCache = typeIdentityCache ?? new Dictionary(); + return typeIdentityCache ??= new Dictionary(); } } diff --git a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/ComposablePartCatalogCollection.cs b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/ComposablePartCatalogCollection.cs index 58007738a8ed4d..810834261e25c0 100644 --- a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/ComposablePartCatalogCollection.cs +++ b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/Hosting/ComposablePartCatalogCollection.cs @@ -32,7 +32,7 @@ public ComposablePartCatalogCollection( Action? onChanged, Action? onChanging) { - catalogs = catalogs ?? Enumerable.Empty(); + catalogs ??= Enumerable.Empty(); _catalogs = new List(catalogs); _onChanged = onChanged; _onChanging = onChanging; diff --git a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/ReflectionModel/ImportType.cs b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/ReflectionModel/ImportType.cs index 94927096b3f98e..6614acd0a6326e 100644 --- a/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/ReflectionModel/ImportType.cs +++ b/src/libraries/System.ComponentModel.Composition/src/System/ComponentModel/Composition/ReflectionModel/ImportType.cs @@ -28,7 +28,7 @@ private static Dictionary?> CastSingleValueCache { get { - return _castSingleValueCache = _castSingleValueCache ?? new Dictionary?>(); + return _castSingleValueCache ??= new Dictionary?>(); } } diff --git a/src/libraries/System.Composition.Runtime/src/System/Composition/Hosting/Core/CompositionContract.cs b/src/libraries/System.Composition.Runtime/src/System/Composition/Hosting/Core/CompositionContract.cs index ebb14362686ecc..641dde6524a5ea 100644 --- a/src/libraries/System.Composition.Runtime/src/System/Composition/Hosting/Core/CompositionContract.cs +++ b/src/libraries/System.Composition.Runtime/src/System/Composition/Hosting/Core/CompositionContract.cs @@ -90,9 +90,9 @@ public override int GetHashCode() { var hc = _contractType.GetHashCode(); if (_contractName != null) - hc = hc ^ _contractName.GetHashCode(); + hc ^= _contractName.GetHashCode(); if (_metadataConstraints != null) - hc = hc ^ ConstraintHashCode(_metadataConstraints); + hc ^= ConstraintHashCode(_metadataConstraints); return hc; } diff --git a/src/libraries/System.Composition.TypedParts/src/System/Composition/TypedParts/ContractHelpers.cs b/src/libraries/System.Composition.TypedParts/src/System/Composition/TypedParts/ContractHelpers.cs index 3794657f438698..338c6ee039b43c 100644 --- a/src/libraries/System.Composition.TypedParts/src/System/Composition/TypedParts/ContractHelpers.cs +++ b/src/libraries/System.Composition.TypedParts/src/System/Composition/TypedParts/ContractHelpers.cs @@ -47,7 +47,7 @@ public static ImportInfo GetImportInfo(Type memberType, object[] attributes, obj var ima = attr as ImportManyAttribute; if (ima != null) { - importMetadata = importMetadata ?? new Dictionary(); + importMetadata ??= new Dictionary(); importMetadata.Add(ImportManyImportMetadataConstraintName, true); importedContract = new CompositionContract(memberType, ima.ContractName); explicitImportsApplied++; @@ -57,7 +57,7 @@ public static ImportInfo GetImportInfo(Type memberType, object[] attributes, obj var imca = attr as ImportMetadataConstraintAttribute; if (imca != null) { - importMetadata = importMetadata ?? new Dictionary(); + importMetadata ??= new Dictionary(); importMetadata.Add(imca.Name, imca.Value); } } @@ -72,7 +72,7 @@ public static ImportInfo GetImportInfo(Type memberType, object[] attributes, obj .GetRuntimeProperties() .Where(p => p.GetMethod.IsPublic && p.DeclaringType == attrType && p.CanRead)) { - importMetadata = importMetadata ?? new Dictionary(); + importMetadata ??= new Dictionary(); importMetadata.Add(prop.Name, prop.GetValue(attr, null)); } } diff --git a/src/libraries/System.Composition.TypedParts/src/System/Composition/TypedParts/Discovery/TypeInspector.cs b/src/libraries/System.Composition.TypedParts/src/System/Composition/TypedParts/Discovery/TypeInspector.cs index 4175cd37dfc8c7..322220c0fd8428 100644 --- a/src/libraries/System.Composition.TypedParts/src/System/Composition/TypedParts/Discovery/TypeInspector.cs +++ b/src/libraries/System.Composition.TypedParts/src/System/Composition/TypedParts/Discovery/TypeInspector.cs @@ -33,7 +33,7 @@ public bool InspectTypeForPart(TypeInfo type, out DiscoveredPart part) foreach (var export in DiscoverExports(type)) { - part = part ?? new DiscoveredPart(type, _attributeContext, _activationFeatures); + part ??= new DiscoveredPart(type, _attributeContext, _activationFeatures); part.AddDiscoveredExport(export); } diff --git a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/StringAttributeCollection.cs b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/StringAttributeCollection.cs index b91713cc7ad18f..68b28f95daa007 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/StringAttributeCollection.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/src/System/Configuration/StringAttributeCollection.cs @@ -66,7 +66,7 @@ public override string ToString() sb.Append(','); } - if (sb.Length > 0) sb.Length = sb.Length - 1; + if (sb.Length > 0) sb.Length--; return sb.Length == 0 ? null : sb.ToString(); } diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/ByteStorage.cs b/src/libraries/System.Data.Common/src/System/Data/Common/ByteStorage.cs index c8a777db67b6ba..8d894f40a2d5d5 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/ByteStorage.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/ByteStorage.cs @@ -88,7 +88,7 @@ public override object Aggregate(int[] records, AggregateType kind) if ((prec < 1e-15) || (var < 0)) var = 0; else - var = var / (count * (count - 1)); + var /= (count * (count - 1)); if (kind == AggregateType.StDev) { diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/DataRecordInternal.cs b/src/libraries/System.Data.Common/src/System/Data/Common/DataRecordInternal.cs index 046366210dc550..4f2a9cee00d623 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/DataRecordInternal.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/DataRecordInternal.cs @@ -131,7 +131,7 @@ public override long GetBytes(int i, long dataIndex, byte[]? buffer, int bufferI { // help the user out in the case where there's less data than requested if ((ndataIndex + length) > cbytes) - cbytes = cbytes - ndataIndex; + cbytes -= ndataIndex; else cbytes = length; } @@ -205,7 +205,7 @@ public override long GetChars(int i, long dataIndex, char[]? buffer, int bufferI // help the user out in the case where there's less data than requested if ((ndataIndex + length) > cchars) { - cchars = cchars - ndataIndex; + cchars -= ndataIndex; } else { diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/DecimalStorage.cs b/src/libraries/System.Data.Common/src/System/Data/Common/DecimalStorage.cs index 5c145272abb937..6e38415ca1aaa7 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/DecimalStorage.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/DecimalStorage.cs @@ -91,7 +91,7 @@ public override object Aggregate(int[] records, AggregateType kind) if ((prec < 1e-15) || (var < 0)) var = 0; else - var = var / (count * (count - 1)); + var /= (count * (count - 1)); if (kind == AggregateType.StDev) { diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/DoubleStorage.cs b/src/libraries/System.Data.Common/src/System/Data/Common/DoubleStorage.cs index 73f17e241e96f5..71d54b9b68f9bc 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/DoubleStorage.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/DoubleStorage.cs @@ -88,7 +88,7 @@ public override object Aggregate(int[] records, AggregateType kind) if ((prec < 1e-15) || (var < 0)) var = 0; else - var = var / (count * (count - 1)); + var /= (count * (count - 1)); if (kind == AggregateType.StDev) { diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/Int16Storage.cs b/src/libraries/System.Data.Common/src/System/Data/Common/Int16Storage.cs index ceac9585cb3831..a8d050ecf70f9f 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/Int16Storage.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/Int16Storage.cs @@ -91,7 +91,7 @@ public override object Aggregate(int[] records, AggregateType kind) if ((prec < 1e-15) || (var < 0)) var = 0; else - var = var / (count * (count - 1)); + var /= (count * (count - 1)); if (kind == AggregateType.StDev) { diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/Int32Storage.cs b/src/libraries/System.Data.Common/src/System/Data/Common/Int32Storage.cs index 11da865400b636..20239c6e2879f5 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/Int32Storage.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/Int32Storage.cs @@ -91,7 +91,7 @@ public override object Aggregate(int[] records, AggregateType kind) if ((prec < 1e-15) || (var < 0)) var = 0; else - var = var / (count * (count - 1)); + var /= (count * (count - 1)); if (kind == AggregateType.StDev) { diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/Int64Storage.cs b/src/libraries/System.Data.Common/src/System/Data/Common/Int64Storage.cs index bb0f519ada080a..831f579bf17ab1 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/Int64Storage.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/Int64Storage.cs @@ -91,7 +91,7 @@ public override object Aggregate(int[] records, AggregateType kind) if ((prec < 1e-15) || (var < 0)) var = 0; else - var = var / (count * (count - 1)); + var /= (count * (count - 1)); if (kind == AggregateType.StDev) { diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/SByteStorage.cs b/src/libraries/System.Data.Common/src/System/Data/Common/SByteStorage.cs index dc58d20033c06b..a2534dc7671c56 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/SByteStorage.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/SByteStorage.cs @@ -88,7 +88,7 @@ public override object Aggregate(int[] records, AggregateType kind) if ((prec < 1e-15) || (var < 0)) var = 0; else - var = var / (count * (count - 1)); + var /= (count * (count - 1)); if (kind == AggregateType.StDev) { diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLByteStorage.cs b/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLByteStorage.cs index 85b4ea53891fa5..d5294635702d06 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLByteStorage.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLByteStorage.cs @@ -90,7 +90,7 @@ public override object Aggregate(int[] records, AggregateType kind) if ((prec < 1e-15) || (var < 0)) var = 0; else - var = var / (count * (count - 1)); + var /= (count * (count - 1)); if (kind == AggregateType.StDev) { diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLDecimalStorage.cs b/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLDecimalStorage.cs index fb2e0b30c8771b..c52cec0cc0046e 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLDecimalStorage.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLDecimalStorage.cs @@ -90,7 +90,7 @@ public override object Aggregate(int[] records, AggregateType kind) if ((prec < 1e-15) || (var < 0)) var = 0; else - var = var / (count * (count - 1)); + var /= (count * (count - 1)); if (kind == AggregateType.StDev) { diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLDoubleStorage.cs b/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLDoubleStorage.cs index a9e78552afe9f1..3653467086d35d 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLDoubleStorage.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLDoubleStorage.cs @@ -90,7 +90,7 @@ public override object Aggregate(int[] records, AggregateType kind) if ((prec < 1e-15) || (var < 0)) var = 0; else - var = var / (count * (count - 1)); + var /= (count * (count - 1)); if (kind == AggregateType.StDev) { diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLInt16Storage.cs b/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLInt16Storage.cs index e210830f4bc90f..4b7f61643ff025 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLInt16Storage.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLInt16Storage.cs @@ -90,7 +90,7 @@ public override object Aggregate(int[] records, AggregateType kind) if ((prec < 1e-15) || (var < 0)) var = 0; else - var = var / (count * (count - 1)); + var /= (count * (count - 1)); if (kind == AggregateType.StDev) { diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLInt32Storage.cs b/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLInt32Storage.cs index d2a1b8118f702d..1f0852fed5d8c0 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLInt32Storage.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLInt32Storage.cs @@ -90,7 +90,7 @@ public override object Aggregate(int[] records, AggregateType kind) if ((prec < 1e-15) || (var < 0)) var = 0; else - var = var / (count * (count - 1)); + var /= (count * (count - 1)); if (kind == AggregateType.StDev) { diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLInt64Storage.cs b/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLInt64Storage.cs index 83d7e548f084cc..fa23bd6e441e50 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLInt64Storage.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLInt64Storage.cs @@ -90,7 +90,7 @@ public override object Aggregate(int[] records, AggregateType kind) if ((prec < 1e-15) || (var < 0)) var = 0; else - var = var / (count * (count - 1)); + var /= (count * (count - 1)); if (kind == AggregateType.StDev) { diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLMoneyStorage.cs b/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLMoneyStorage.cs index f220e760f4ebbb..c2bd8eb9086ebc 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLMoneyStorage.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLMoneyStorage.cs @@ -90,7 +90,7 @@ public override object Aggregate(int[] records, AggregateType kind) if ((prec < 1e-15) || (var < 0)) var = 0; else - var = var / (count * (count - 1)); + var /= (count * (count - 1)); if (kind == AggregateType.StDev) { diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLSingleStorage.cs b/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLSingleStorage.cs index 1250ed55ec495c..f3357fe0b53a0a 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLSingleStorage.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLSingleStorage.cs @@ -90,7 +90,7 @@ public override object Aggregate(int[] records, AggregateType kind) if ((prec < 1e-15) || (var < 0)) var = 0; else - var = var / (count * (count - 1)); + var /= (count * (count - 1)); if (kind == AggregateType.StDev) { diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLStringStorage.cs b/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLStringStorage.cs index d9413cd0e357d2..57767ef64a5e9e 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLStringStorage.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/SQLTypes/SQLStringStorage.cs @@ -38,7 +38,7 @@ public override object Aggregate(int[] recordNos, AggregateType kind) } if (min >= 0) { - for (i = i + 1; i < recordNos.Length; i++) + for (i++; i < recordNos.Length; i++) { if (IsNull(recordNos[i])) continue; @@ -63,7 +63,7 @@ public override object Aggregate(int[] recordNos, AggregateType kind) } if (max >= 0) { - for (i = i + 1; i < recordNos.Length; i++) + for (i++; i < recordNos.Length; i++) { if (Compare(max, recordNos[i]) < 0) { diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/SingleStorage.cs b/src/libraries/System.Data.Common/src/System/Data/Common/SingleStorage.cs index d7f0f5884b67cf..99240898fa4f3a 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/SingleStorage.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/SingleStorage.cs @@ -88,7 +88,7 @@ public override object Aggregate(int[] records, AggregateType kind) if ((prec < 1e-15) || (var < 0)) var = 0; else - var = var / (count * (count - 1)); + var /= (count * (count - 1)); if (kind == AggregateType.StDev) { diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/StringStorage.cs b/src/libraries/System.Data.Common/src/System/Data/Common/StringStorage.cs index db06db53dcd332..f3e457b8569c38 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/StringStorage.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/StringStorage.cs @@ -33,7 +33,7 @@ public override object Aggregate(int[] recordNos, AggregateType kind) } if (min >= 0) { - for (i = i + 1; i < recordNos.Length; i++) + for (i++; i < recordNos.Length; i++) { if (IsNull(recordNos[i])) continue; @@ -57,7 +57,7 @@ public override object Aggregate(int[] recordNos, AggregateType kind) } if (max >= 0) { - for (i = i + 1; i < recordNos.Length; i++) + for (i++; i < recordNos.Length; i++) { if (Compare(max, recordNos[i]) < 0) { diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/UInt16Storage.cs b/src/libraries/System.Data.Common/src/System/Data/Common/UInt16Storage.cs index a8a75051ef01c3..dfbf07c8da5da1 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/UInt16Storage.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/UInt16Storage.cs @@ -91,7 +91,7 @@ public override object Aggregate(int[] records, AggregateType kind) if ((prec < 1e-15) || (var < 0)) var = 0; else - var = var / (count * (count - 1)); + var /= (count * (count - 1)); if (kind == AggregateType.StDev) { diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/UInt32Storage.cs b/src/libraries/System.Data.Common/src/System/Data/Common/UInt32Storage.cs index 53a815a262a86e..d893058e84b33b 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/UInt32Storage.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/UInt32Storage.cs @@ -91,7 +91,7 @@ public override object Aggregate(int[] records, AggregateType kind) if ((prec < 1e-15) || (var < 0)) var = 0; else - var = var / (count * (count - 1)); + var /= (count * (count - 1)); if (kind == AggregateType.StDev) { diff --git a/src/libraries/System.Data.Common/src/System/Data/Common/UInt64Storage.cs b/src/libraries/System.Data.Common/src/System/Data/Common/UInt64Storage.cs index fa18cdee966a6f..9feaa5e4ff7241 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Common/UInt64Storage.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Common/UInt64Storage.cs @@ -91,7 +91,7 @@ public override object Aggregate(int[] records, AggregateType kind) if ((prec < 1e-15) || (var < 0)) var = 0; else - var = var / (count * (count - 1)); + var /= (count * (count - 1)); if (kind == AggregateType.StDev) { diff --git a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLDecimal.cs b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLDecimal.cs index e3af9a2cfcb896..83ad2822fd1c29 100644 --- a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLDecimal.cs +++ b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLDecimal.cs @@ -2225,7 +2225,7 @@ private uint DivByULong(uint iDivisor) ulQuotientCur = (uint)(dwlAccum / dwlDivisor); rguiData[iData - 1] = ulQuotientCur; //Remainder to be carried to the next lower significant byte. - dwlAccum = dwlAccum % dwlDivisor; + dwlAccum %= dwlDivisor; // While current part of quotient still 0, reduce length if (fAllZero && (ulQuotientCur == 0)) diff --git a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLMoney.cs b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLMoney.cs index 64c0d168631c86..24f6a1432f0e1c 100644 --- a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLMoney.cs +++ b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLMoney.cs @@ -150,7 +150,7 @@ public long ToInt64() long ret = _value / (s_lTickBase / 10); bool fPositive = (ret >= 0); long remainder = ret % 10; - ret = ret / 10; + ret /= 10; if (remainder >= 5) { diff --git a/src/libraries/System.Data.Common/src/System/Data/XMLSchema.cs b/src/libraries/System.Data.Common/src/System/Data/XMLSchema.cs index 164b3731bdccba..0304f2522d24b3 100644 --- a/src/libraries/System.Data.Common/src/System/Data/XMLSchema.cs +++ b/src/libraries/System.Data.Common/src/System/Data/XMLSchema.cs @@ -1493,7 +1493,7 @@ internal DataTable InstantiateSimpleTable(XmlSchemaElement node) int i = 0; colName = typeName + "_Text"; while (table.Columns[colName] != null) - colName = colName + i++; + colName += i++; } else { @@ -2003,7 +2003,7 @@ internal void HandleSimpleTypeSimpleContentColumn(XmlSchemaSimpleType typeNode, colName = table.TableName + "_Text"; while (table.Columns[colName] != null) { - colName = colName + i++; + colName += i++; } } else @@ -2115,7 +2115,7 @@ internal void HandleSimpleContentColumn(string strType, DataTable table, bool is colName = table.TableName + "_Text"; while (table.Columns[colName] != null) { - colName = colName + i++; + colName += i++; } } else diff --git a/src/libraries/System.Data.Common/src/System/Data/xmlsaver.cs b/src/libraries/System.Data.Common/src/System/Data/xmlsaver.cs index 32f72f51f01b15..c8d9513cf0361f 100644 --- a/src/libraries/System.Data.Common/src/System/Data/xmlsaver.cs +++ b/src/libraries/System.Data.Common/src/System/Data/xmlsaver.cs @@ -1093,7 +1093,7 @@ internal void SetPath(XmlWriter xw) _fileName = Path.GetFileNameWithoutExtension(fs.Name); _fileExt = Path.GetExtension(fs.Name); if (!string.IsNullOrEmpty(_filePath)) - _filePath = _filePath + "\\"; + _filePath += "\\"; } [RequiresUnreferencedCode(DataSet.RequiresUnreferencedCodeMessage)] diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnection.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnection.cs index 6e95445410917e..69329e3e4a3a03 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnection.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcConnection.cs @@ -844,7 +844,7 @@ internal bool TestTypeSupport(ODBC32.SQL_TYPE sqltype) int flags; flags = GetInfoInt32Unhandled((ODBC32.SQL_INFO)sqlconvert); - flags = flags & (int)sqlcvt; + flags &= (int)sqlcvt; ProviderInfo.TestedSQLTypes |= (int)sqlcvt; ProviderInfo.SupportedSQLTypes |= flags; diff --git a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcMetaDataFactory.cs b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcMetaDataFactory.cs index 78ffdf1dc16140..4f373a5ceac367 100644 --- a/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcMetaDataFactory.cs +++ b/src/libraries/System.Data.Odbc/src/System/Data/Odbc/OdbcMetaDataFactory.cs @@ -636,19 +636,19 @@ private DataTable GetDataSourceInformationCollection(string?[]? restrictions, Common.SupportedJoinOperators supportedJoinOperators = Common.SupportedJoinOperators.None; if ((int32Value & (int)ODBC32.SQL_OJ_CAPABILITIES.LEFT) != 0) { - supportedJoinOperators = supportedJoinOperators | Common.SupportedJoinOperators.LeftOuter; + supportedJoinOperators |= Common.SupportedJoinOperators.LeftOuter; } if ((int32Value & (int)ODBC32.SQL_OJ_CAPABILITIES.RIGHT) != 0) { - supportedJoinOperators = supportedJoinOperators | Common.SupportedJoinOperators.RightOuter; + supportedJoinOperators |= Common.SupportedJoinOperators.RightOuter; } if ((int32Value & (int)ODBC32.SQL_OJ_CAPABILITIES.FULL) != 0) { - supportedJoinOperators = supportedJoinOperators | Common.SupportedJoinOperators.FullOuter; + supportedJoinOperators |= Common.SupportedJoinOperators.FullOuter; } if ((int32Value & (int)ODBC32.SQL_OJ_CAPABILITIES.INNER) != 0) { - supportedJoinOperators = supportedJoinOperators | Common.SupportedJoinOperators.Inner; + supportedJoinOperators |= Common.SupportedJoinOperators.Inner; } dataSourceInformation[DbMetaDataColumnNames.SupportedJoinOperators] = supportedJoinOperators; diff --git a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/EventLogReader.cs b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/EventLogReader.cs index c7a0b6b8ed1adf..4645d3024b182b 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/EventLogReader.cs +++ b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/EventLogReader.cs @@ -218,7 +218,7 @@ internal void SeekCommon(long offset) // fact that we've already read some events in our buffer that the user // hasn't seen yet. // - offset = offset - (_eventCount - _currentIndex); + offset -= (_eventCount - _currentIndex); SeekReset(); diff --git a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/EventMetadata.cs b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/EventMetadata.cs index 2b3f74a261b96a..4e2d2128b6ff79 100644 --- a/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/EventMetadata.cs +++ b/src/libraries/System.Diagnostics.EventLog/src/System/Diagnostics/Reader/EventMetadata.cs @@ -100,7 +100,7 @@ public IEnumerable Keywords // theKeywords = theKeywords - mask; } // Modify the mask to check next bit. - mask = mask >> 1; + mask >>= 1; } return list; diff --git a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/SharedPerformanceCounter.cs b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/SharedPerformanceCounter.cs index 7ef3659bbd3e4f..99e1f3395c14f8 100644 --- a/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/SharedPerformanceCounter.cs +++ b/src/libraries/System.Diagnostics.PerformanceCounter/src/System/Diagnostics/SharedPerformanceCounter.cs @@ -193,7 +193,7 @@ private int CalculateMemoryNoBoundsCheck(int oldOffset, int totalSize, out int a // make sure the start address is 8 byte aligned int startAddressMod8 = (int)(_baseAddress + oldOffset) & 0x7; alignmentAdjustment = (8 - startAddressMod8) & 0x7; - currentTotalSize = currentTotalSize + alignmentAdjustment; + currentTotalSize += alignmentAdjustment; int newOffset = oldOffset + currentTotalSize; @@ -670,7 +670,7 @@ private unsafe CategoryData GetCategoryData() { fileMappingSize = GetFileMappingSizeFromConfig(); if (data.UseUniqueSharedMemory) - fileMappingSize = fileMappingSize >> 2; // if we have a custom filemapping, only make it 25% as large. + fileMappingSize >>= 2; // if we have a custom filemapping, only make it 25% as large. } // now read the counter names diff --git a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.NonUap.cs b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.NonUap.cs index b97658c52fc8ba..cd4269d5373afc 100644 --- a/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.NonUap.cs +++ b/src/libraries/System.Diagnostics.Process/src/System/Diagnostics/Process.NonUap.cs @@ -72,7 +72,7 @@ private bool IsSelfOrDescendantOf(Process processOfInterest) private List GetChildProcesses(Process[]? processes = null) { bool internallyInitializedProcesses = processes == null; - processes = processes ?? GetProcesses(); + processes ??= GetProcesses(); List childProcesses = new List(); diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/RangeRetriever.cs b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/RangeRetriever.cs index 0be16009b54b85..3e0fee4f1b0976 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/RangeRetriever.cs +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/RangeRetriever.cs @@ -192,7 +192,7 @@ private IEnumerator GetNextChunk() } else { - _lowRange = _lowRange + pvc.Count; + _lowRange += pvc.Count; GlobalDebug.WriteLineIf(GlobalDebug.Info, "RangeRetriever", diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/SDSUtils.cs b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/SDSUtils.cs index d747da6bfe3d37..6f6f5bee242ba6 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/SDSUtils.cs +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/AD/SDSUtils.cs @@ -669,7 +669,7 @@ internal static void AccountControlToDirectoryEntry( if (!isSAM && de.Properties["msDS-User-Account-Control-Computed"].Count > 0) { Debug.Assert(de.Properties["msDS-User-Account-Control-Computed"].Count == 1); - uacValue = uacValue | (int)de.Properties["msDS-User-Account-Control-Computed"][0]; + uacValue |= (int)de.Properties["msDS-User-Account-Control-Computed"][0]; } } else diff --git a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySiteLinkCollection.cs b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySiteLinkCollection.cs index 46e914c5efc6e2..c19cb532cc5e10 100644 --- a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySiteLinkCollection.cs +++ b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/ActiveDirectorySiteLinkCollection.cs @@ -53,7 +53,7 @@ public void AddRange(ActiveDirectorySiteLink[] links) if (links == null) throw new ArgumentNullException(nameof(links)); - for (int i = 0; i < links.Length; i = i + 1) + for (int i = 0; i < links.Length; i++) this.Add(links[i]); } diff --git a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/Locator.cs b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/Locator.cs index d055b21f0343b5..2909c7d44b7b98 100644 --- a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/Locator.cs +++ b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/ActiveDirectory/Locator.cs @@ -224,7 +224,7 @@ private static Hashtable DnsQueryWrapper(string domainName, string siteName, lon } // now add the domainName - recordName = recordName + domainName; + recordName += domainName; // set the BYPASS CACHE option is specified if (((long)dcFlags & (long)LocatorOptions.ForceRediscovery) != 0) diff --git a/src/libraries/System.Drawing.Common/src/System/Drawing/ClientUtils.cs b/src/libraries/System.Drawing.Common/src/System/Drawing/ClientUtils.cs index ec595b11cc034e..a4ce3387b3ec37 100644 --- a/src/libraries/System.Drawing.Common/src/System/Drawing/ClientUtils.cs +++ b/src/libraries/System.Drawing.Common/src/System/Drawing/ClientUtils.cs @@ -143,8 +143,8 @@ private static void Copy(WeakRefCollection sourceList, int sourceIndex, WeakRefC // We need to copy from the back forward to prevent overwrite if source and // destination lists are the same, so we need to flip the source/dest indices // to point at the end of the spans to be copied. - sourceIndex = sourceIndex + length; - destinationIndex = destinationIndex + length; + sourceIndex += length; + destinationIndex += length; for (; length > 0; length--) { destinationList.InnerList[--destinationIndex] = sourceList.InnerList[--sourceIndex]; diff --git a/src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateManaged/InputBuffer.cs b/src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateManaged/InputBuffer.cs index 0fde03f8492a8c..a8c592533a73f8 100644 --- a/src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateManaged/InputBuffer.cs +++ b/src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateManaged/InputBuffer.cs @@ -219,7 +219,7 @@ public void SkipBits(int n) public void SkipToByteBoundary() { _bitBuffer >>= (_bitsInBuffer % 8); - _bitsInBuffer = _bitsInBuffer - (_bitsInBuffer % 8); + _bitsInBuffer -= (_bitsInBuffer % 8); } } } diff --git a/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Windows.cs b/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Windows.cs index 230daee5f67443..08f63807b22896 100644 --- a/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Windows.cs +++ b/src/libraries/System.IO.Ports/src/System/IO/Ports/SerialStream.Windows.cs @@ -1280,7 +1280,7 @@ internal int GetDcbFlag(int whichFlag) internal void SetDcbFlag(int whichFlag, int setting) { uint mask; - setting = setting << whichFlag; + setting <<= whichFlag; Debug.Assert(whichFlag >= Interop.Kernel32.DCBFlags.FBINARY && whichFlag <= Interop.Kernel32.DCBFlags.FDUMMY2, "SetDcbFlag needs to fit into enum!"); @@ -1705,7 +1705,7 @@ private void CallEvents(int nativeEvents) return; } - errors = errors & ErrorEvents; + errors &= ErrorEvents; // TODO: what about CE_BREAK? Is this the same as EV_BREAK? EV_BREAK happens as one of the pin events, // but CE_BREAK is returned from ClreaCommError. // TODO: what about other error conditions not covered by the enum? Should those produce some other error? diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/LightCompiler.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/LightCompiler.cs index 2c9edb8c4a321d..a560068a6255d0 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/LightCompiler.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/LightCompiler.cs @@ -241,7 +241,7 @@ int IComparer.Compare(DebugInfo? d1, DebugInfo? d2) return null; } //return the last one that is smaller - i = i - 1; + i--; } return debugInfos[i]; diff --git a/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Partitioning/PartitionedDataSource.cs b/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Partitioning/PartitionedDataSource.cs index 1d43e57759141f..be2778b054ca7d 100644 --- a/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Partitioning/PartitionedDataSource.cs +++ b/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/Partitioning/PartitionedDataSource.cs @@ -703,7 +703,7 @@ internal override bool MoveNext([MaybeNullWhen(false), AllowNull] ref T currentE { if ((mutables._chunkCounter++ & chunksPerChunkSize) == chunksPerChunkSize) { - mutables._nextChunkMaxSize = mutables._nextChunkMaxSize * 2; + mutables._nextChunkMaxSize *= 2; if (mutables._nextChunkMaxSize > chunkBuffer.Length) { mutables._nextChunkMaxSize = chunkBuffer.Length; diff --git a/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/QueryOperators/Unary/SortQueryOperator.cs b/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/QueryOperators/Unary/SortQueryOperator.cs index be679efe9d760c..7fb10e115a487c 100644 --- a/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/QueryOperators/Unary/SortQueryOperator.cs +++ b/src/libraries/System.Linq.Parallel/src/System/Linq/Parallel/QueryOperators/Unary/SortQueryOperator.cs @@ -62,7 +62,7 @@ internal SortQueryOperator(IEnumerable source, Func IOrderedEnumerable.CreateOrderedEnumerable( Func key2Selector, IComparer? key2Comparer, bool descending) { - key2Comparer = key2Comparer ?? Util.GetDefaultComparer(); + key2Comparer ??= Util.GetDefaultComparer(); if (descending) { diff --git a/src/libraries/System.Linq.Parallel/src/System/Linq/ParallelEnumerable.cs b/src/libraries/System.Linq.Parallel/src/System/Linq/ParallelEnumerable.cs index 96e7aa1a6b47e9..81de50225cbd8b 100644 --- a/src/libraries/System.Linq.Parallel/src/System/Linq/ParallelEnumerable.cs +++ b/src/libraries/System.Linq.Parallel/src/System/Linq/ParallelEnumerable.cs @@ -5139,7 +5139,7 @@ public static ILookup ToLookup( ArgumentNullException.ThrowIfNull(keySelector); // comparer may be null, in which case we use the default comparer. - comparer = comparer ?? EqualityComparer.Default; + comparer ??= EqualityComparer.Default; ParallelQuery> groupings = source.GroupBy(keySelector, comparer); @@ -5226,7 +5226,7 @@ public static ILookup ToLookup( ArgumentNullException.ThrowIfNull(elementSelector); // comparer may be null, in which case we use the default comparer. - comparer = comparer ?? EqualityComparer.Default; + comparer ??= EqualityComparer.Default; ParallelQuery> groupings = source.GroupBy(keySelector, elementSelector, comparer); diff --git a/src/libraries/System.Management/src/System/Management/ManagementDateTime.cs b/src/libraries/System.Management/src/System/Management/ManagementDateTime.cs index 5b29f245f39867..41cc474d38df1a 100644 --- a/src/libraries/System.Management/src/System/Management/ManagementDateTime.cs +++ b/src/libraries/System.Management/src/System/Management/ManagementDateTime.cs @@ -260,12 +260,12 @@ public static string ToDmtfDateTime(DateTime date) string dmtfDateTime = date.Year.ToString(frmInt32).PadLeft(4, '0'); - dmtfDateTime = (dmtfDateTime + date.Month.ToString(frmInt32).PadLeft(2, '0')); - dmtfDateTime = (dmtfDateTime + date.Day.ToString(frmInt32).PadLeft(2, '0')); - dmtfDateTime = (dmtfDateTime + date.Hour.ToString(frmInt32).PadLeft(2, '0')); - dmtfDateTime = (dmtfDateTime + date.Minute.ToString(frmInt32).PadLeft(2, '0')); - dmtfDateTime = (dmtfDateTime + date.Second.ToString(frmInt32).PadLeft(2, '0')); - dmtfDateTime = (dmtfDateTime + "."); + dmtfDateTime += date.Month.ToString(frmInt32).PadLeft(2, '0'); + dmtfDateTime += date.Day.ToString(frmInt32).PadLeft(2, '0'); + dmtfDateTime += date.Hour.ToString(frmInt32).PadLeft(2, '0'); + dmtfDateTime += date.Minute.ToString(frmInt32).PadLeft(2, '0'); + dmtfDateTime += date.Second.ToString(frmInt32).PadLeft(2, '0'); + dmtfDateTime += "."; // Construct a DateTime with the precision to Second as same as the passed DateTime and so get // the ticks difference so that the microseconds can be calculated @@ -278,9 +278,9 @@ public static string ToDmtfDateTime(DateTime date) { strMicrosec = strMicrosec.Substring(0, 6); } - dmtfDateTime = dmtfDateTime + strMicrosec.PadLeft(6, '0'); + dmtfDateTime += strMicrosec.PadLeft(6, '0'); // adding the UTC offset - dmtfDateTime = dmtfDateTime + UtcString; + dmtfDateTime += UtcString; return dmtfDateTime; } @@ -370,7 +370,7 @@ public static TimeSpan ToTimeSpan(string dmtfTimespan) // Get a timepan for the additional ticks obtained for the microsecond part of DMTF time interval // and then add it to the original timespan TimeSpan tsTemp = System.TimeSpan.FromTicks(ticks); - timespan = timespan + tsTemp; + timespan += tsTemp; return timespan; } @@ -417,10 +417,10 @@ public static string ToDmtfTimeInterval(TimeSpan timespan) throw new System.ArgumentOutOfRangeException(nameof(timespan)); } - dmtftimespan = (dmtftimespan + timespan.Hours.ToString(frmInt32).PadLeft(2, '0')); - dmtftimespan = (dmtftimespan + timespan.Minutes.ToString(frmInt32).PadLeft(2, '0')); - dmtftimespan = (dmtftimespan + timespan.Seconds.ToString(frmInt32).PadLeft(2, '0')); - dmtftimespan = (dmtftimespan + "."); + dmtftimespan += timespan.Hours.ToString(frmInt32).PadLeft(2, '0'); + dmtftimespan += timespan.Minutes.ToString(frmInt32).PadLeft(2, '0'); + dmtftimespan += timespan.Seconds.ToString(frmInt32).PadLeft(2, '0'); + dmtftimespan += "."; // Construct a DateTime with the precision to Second as same as the passed DateTime and so get // the ticks difference so that the microseconds can be calculated @@ -433,9 +433,9 @@ public static string ToDmtfTimeInterval(TimeSpan timespan) { strMicrosec = strMicrosec.Substring(0, 6); } - dmtftimespan = dmtftimespan + strMicrosec.PadLeft(6, '0'); + dmtftimespan += strMicrosec.PadLeft(6, '0'); - dmtftimespan = dmtftimespan + ":000"; + dmtftimespan += ":000"; return dmtftimespan; } diff --git a/src/libraries/System.Management/src/System/Management/ManagementPath.cs b/src/libraries/System.Management/src/System/Management/ManagementPath.cs index 7dd7af05b81a86..633b3064122cfb 100644 --- a/src/libraries/System.Management/src/System/Management/ManagementPath.cs +++ b/src/libraries/System.Management/src/System/Management/ManagementPath.cs @@ -271,7 +271,7 @@ private static void SetWbemPath(IWbemPath wbemPath, string path) // this is because in the case of "root", the path parser cannot tell whether // this is a namespace name or a class name if (string.Equals(path, "root", StringComparison.OrdinalIgnoreCase)) - flags = flags | (uint)tag_WBEM_PATH_CREATE_FLAG.WBEMPATH_TREAT_SINGLE_IDENT_AS_NS; + flags |= (uint)tag_WBEM_PATH_CREATE_FLAG.WBEMPATH_TREAT_SINGLE_IDENT_AS_NS; int status = wbemPath.SetText_(flags, path); diff --git a/src/libraries/System.Management/src/System/Management/ManagementQuery.cs b/src/libraries/System.Management/src/System/Management/ManagementQuery.cs index e9e0fe736317c4..64816f8c3a0cd6 100644 --- a/src/libraries/System.Management/src/System/Management/ManagementQuery.cs +++ b/src/libraries/System.Management/src/System/Management/ManagementQuery.cs @@ -932,7 +932,7 @@ protected internal void BuildQuery() s = s + selectedProperties[i] + ((i == (count - 1)) ? " " : ","); } else - s = s + "* "; + s += "* "; //From clause s = s + "from " + className; @@ -2993,7 +2993,7 @@ protected internal void BuildQuery() if ((null != groupByPropertyList) && (0 < groupByPropertyList.Count)) { int count = groupByPropertyList.Count; - s = s + " by "; + s += " by "; for (int i = 0; i < count; i++) s = s + groupByPropertyList[i] + (i == (count - 1) ? "" : ","); diff --git a/src/libraries/System.Management/src/System/Management/PropertySet.cs b/src/libraries/System.Management/src/System/Management/PropertySet.cs index 8e748bfcf913ad..390b718cc8b790 100644 --- a/src/libraries/System.Management/src/System/Management/PropertySet.cs +++ b/src/libraries/System.Management/src/System/Management/PropertySet.cs @@ -461,7 +461,7 @@ public void Add(string propertyName, object propertyValue, CimType propertyType) if ((null != propertyValue) && propertyValue.GetType().IsArray) { isArray = true; - wmiCimType = (wmiCimType | (int)tag_CIMTYPE_ENUMERATION.CIM_FLAG_ARRAY); + wmiCimType |= (int)tag_CIMTYPE_ENUMERATION.CIM_FLAG_ARRAY; } object wmiValue = PropertyData.MapValueToWmiValue(propertyValue, propertyType, isArray); @@ -500,7 +500,7 @@ public void Add(string propertyName, CimType propertyType, bool isArray) int wmiCimType = (int)propertyType; if (isArray) - wmiCimType = (wmiCimType | (int)tag_CIMTYPE_ENUMERATION.CIM_FLAG_ARRAY); + wmiCimType |= (int)tag_CIMTYPE_ENUMERATION.CIM_FLAG_ARRAY; object dummyObj = System.DBNull.Value; diff --git a/src/libraries/System.Management/src/System/Management/QualifierSet.cs b/src/libraries/System.Management/src/System/Management/QualifierSet.cs index 528f244a8c1a92..a25f73559c3a79 100644 --- a/src/libraries/System.Management/src/System/Management/QualifierSet.cs +++ b/src/libraries/System.Management/src/System/Management/QualifierSet.cs @@ -464,12 +464,12 @@ public virtual void Add(string qualifierName, object qualifierValue, bool isAmen //Build the flavors bitmask and call the internal Add that takes a bitmask int qualFlavor = 0; - if (isAmended) qualFlavor = (qualFlavor | (int)tag_WBEM_FLAVOR_TYPE.WBEM_FLAVOR_AMENDED); - if (propagatesToInstance) qualFlavor = (qualFlavor | (int)tag_WBEM_FLAVOR_TYPE.WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE); - if (propagatesToSubclass) qualFlavor = (qualFlavor | (int)tag_WBEM_FLAVOR_TYPE.WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS); + if (isAmended) qualFlavor |= (int)tag_WBEM_FLAVOR_TYPE.WBEM_FLAVOR_AMENDED; + if (propagatesToInstance) qualFlavor |= (int)tag_WBEM_FLAVOR_TYPE.WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE; + if (propagatesToSubclass) qualFlavor |= (int)tag_WBEM_FLAVOR_TYPE.WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS; // Note we use the NOT condition here since WBEM_FLAVOR_OVERRIDABLE == 0 - if (!isOverridable) qualFlavor = (qualFlavor | (int)tag_WBEM_FLAVOR_TYPE.WBEM_FLAVOR_NOT_OVERRIDABLE); + if (!isOverridable) qualFlavor |= (int)tag_WBEM_FLAVOR_TYPE.WBEM_FLAVOR_NOT_OVERRIDABLE; //Try to add the qualifier to the WMI object int status = GetTypeQualifierSet().Put_(qualifierName, ref qualifierValue, qualFlavor); diff --git a/src/libraries/System.Management/src/System/Management/WMIGenerator.cs b/src/libraries/System.Management/src/System/Management/WMIGenerator.cs index 1c43875350a9c3..f20286a94f090b 100644 --- a/src/libraries/System.Management/src/System/Management/WMIGenerator.cs +++ b/src/libraries/System.Management/src/System/Management/WMIGenerator.cs @@ -563,7 +563,7 @@ private void InitializeClassObject() { if (bStart == true) { - OriginalNamespace = OriginalNamespace + arrString[i]; + OriginalNamespace += arrString[i]; } else if (arrString[i] == '\\') @@ -816,7 +816,7 @@ private string ResolveCollision(string inString, bool bCheckthisFirst) } catch (OverflowException) { - strToAdd = strToAdd + "_"; + strToAdd += "_"; k = 0; } strTemp = inString + strToAdd + k.ToString((IFormatProvider)CultureInfo.InvariantCulture.GetFormat(typeof(int))); @@ -972,7 +972,7 @@ private void GeneratePublicProperty(string propName, string propType, CodeExpres if (isStatic) { - cmp.Attributes = cmp.Attributes | MemberAttributes.Static; + cmp.Attributes |= MemberAttributes.Static; } caa = new CodeAttributeArgument(); @@ -1951,7 +1951,7 @@ private bool GeneratePropertyHelperEnums(PropertyData prop, string strPropertyNa // Now shift 1 more bit so that we can put it for the // next element in the enum - bitValue = bitValue << 1; + bitValue <<= 1; } if (bZeroFieldInEnum == false) @@ -1984,11 +1984,11 @@ private bool GeneratePropertyHelperEnums(PropertyData prop, string strPropertyNa cmf.Name = "NULL_ENUM_VALUE"; if (BitValues.Count > 30) { - maxBitValue = maxBitValue + 1; + maxBitValue++; } else { - maxBitValue = maxBitValue << 1; + maxBitValue <<= 1; } cmf.InitExpression = new CodePrimitiveExpression((int)(maxBitValue)); EnumObj.Members.Add(cmf); @@ -2048,7 +2048,7 @@ private void GenerateConstructPath() string strPath = OriginalNamespace + ":" + OriginalClassName; if (bSingletonClass == true) { - strPath = strPath + "=@"; + strPath += "=@"; cmm.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(strPath))); } else @@ -3701,7 +3701,7 @@ private void GeneratePrivateMember(string memberName, string MemberType, CodeExp cf.Attributes = MemberAttributes.Private | MemberAttributes.Final; if (isStatic == true) { - cf.Attributes = cf.Attributes | MemberAttributes.Static; + cf.Attributes |= MemberAttributes.Static; } cf.Type = new CodeTypeReference(MemberType); if (initExpression != null && isStatic == true) @@ -5012,7 +5012,7 @@ private static int ConvertBitMapValueToInt32(string bitMap) int Len = bitMap.Length; for (int i = 2; i < Len; i++) { - strTemp = strTemp + arrString[i]; + strTemp += arrString[i]; } ret = System.Convert.ToInt32(strTemp, (IFormatProvider)CultureInfo.InvariantCulture.GetFormat(typeof(int))); } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/AuthenticationHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/AuthenticationHeaderValue.cs index 3ab1b980970209..35b070e3fe1eae 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/AuthenticationHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/AuthenticationHeaderValue.cs @@ -87,7 +87,7 @@ public override int GetHashCode() if (!string.IsNullOrEmpty(_parameter)) { - result = result ^ _parameter.GetHashCode(); + result ^= _parameter.GetHashCode(); } return result; @@ -148,7 +148,7 @@ internal static int GetAuthenticationLength(string? input, int startIndex, out o int current = startIndex + schemeLength; int whitespaceLength = HttpRuleParser.GetWhitespaceLength(input, current); - current = current + whitespaceLength; + current += whitespaceLength; if ((current == input.Length) || (input[current] == ',')) { @@ -206,7 +206,7 @@ private static bool TrySkipFirstBlob(string input, ref int current, ref int para // We have a quote but an invalid quoted-string. return false; } - current = current + quotedStringLength; + current += quotedStringLength; parameterEndIndex = current - 1; // -1 because 'current' points to the char after the final '"' } else @@ -223,7 +223,7 @@ private static bool TrySkipFirstBlob(string input, ref int current, ref int para } else { - current = current + whitespaceLength; + current += whitespaceLength; } } } @@ -256,8 +256,8 @@ private static bool TryGetParametersEndIndex(string input, ref int parseEndIndex return false; } - current = current + tokenLength; - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += tokenLength; + current += HttpRuleParser.GetWhitespaceLength(input, current); // If we reached the end of the string or the token is followed by anything but '=', then the parsed // token is another scheme name. The string representing parameters ends before the token (e.g. @@ -268,7 +268,7 @@ private static bool TryGetParametersEndIndex(string input, ref int parseEndIndex } current++; // skip '=' delimiter - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); int valueLength = NameValueHeaderValue.GetValueLength(input, current); // After '=' we expect a valid (either token or quoted string) @@ -279,9 +279,9 @@ private static bool TryGetParametersEndIndex(string input, ref int parseEndIndex // Update parameter end index, since we just parsed a valid = pair that is part of the // parameters string. - current = current + valueLength; + current += valueLength; parameterEndIndex = current - 1; // -1 because 'current' already points to the char after - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); parseEndIndex = current; // this essentially points to parameterEndIndex + whitespace + next char } while ((current < input.Length) && (input[current] == ',')); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/BaseHeaderParser.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/BaseHeaderParser.cs index 1c8df35e50be83..0c9d6f72ae2b5c 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/BaseHeaderParser.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/BaseHeaderParser.cs @@ -66,7 +66,7 @@ public sealed override bool TryParseValue(string? value, object? storeValue, ref return false; } - current = current + length; + current += length; current = HeaderUtilities.GetNextNonEmptyOrWhitespaceIndex(value, current, SupportsMultipleValues, out separatorFound); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/CacheControlHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/CacheControlHeaderValue.cs index a40b6b9d089e02..fdba34a3fd4a41 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/CacheControlHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/CacheControlHeaderValue.cs @@ -338,7 +338,7 @@ public override int GetHashCode() { foreach (var noCacheHeader in _noCacheHeaders) { - result = result ^ StringComparer.OrdinalIgnoreCase.GetHashCode(noCacheHeader); + result ^= StringComparer.OrdinalIgnoreCase.GetHashCode(noCacheHeader); } } @@ -346,7 +346,7 @@ public override int GetHashCode() { foreach (var privateHeader in _privateHeaders) { - result = result ^ StringComparer.OrdinalIgnoreCase.GetHashCode(privateHeader); + result ^= StringComparer.OrdinalIgnoreCase.GetHashCode(privateHeader); } } @@ -354,7 +354,7 @@ public override int GetHashCode() { foreach (var extension in _extensions) { - result = result ^ extension.GetHashCode(); + result ^= extension.GetHashCode(); } } @@ -568,7 +568,7 @@ private static bool TrySetOptionalTokenList(NameValueHeaderValue nameValue, ref destination ??= new TokenObjectCollection(); destination.Add(valueString.Substring(current, tokenLength)); - current = current + tokenLength; + current += tokenLength; } // After parsing a valid token list, we expect to have at least one value diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ContentDispositionHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ContentDispositionHeaderValue.cs index 6b282f0193aef5..94d50128c5d330 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ContentDispositionHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ContentDispositionHeaderValue.cs @@ -225,7 +225,7 @@ internal static int GetDispositionTypeLength(string? input, int startIndex, out } int current = startIndex + dispositionTypeLength; - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); ContentDispositionHeaderValue contentDispositionHeader = new ContentDispositionHeaderValue(); contentDispositionHeader._dispositionType = dispositionType!; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ContentRangeHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ContentRangeHeaderValue.cs index 7321ea27dcabc2..f74d5015b5fcde 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ContentRangeHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ContentRangeHeaderValue.cs @@ -143,7 +143,7 @@ public override int GetHashCode() if (HasLength) { - result = result ^ _length.GetHashCode(); + result ^= _length.GetHashCode(); } return result; @@ -227,7 +227,7 @@ internal static int GetContentRangeLength(string? input, int startIndex, out obj return 0; } - current = current + separatorLength; + current += separatorLength; if (current == input.Length) { @@ -251,7 +251,7 @@ internal static int GetContentRangeLength(string? input, int startIndex, out obj } current++; // Skip '/' separator - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); if (current == input.Length) { @@ -293,10 +293,10 @@ private static bool TryGetLengthLength(string input, ref int current, out int le return false; } - current = current + lengthLength; + current += lengthLength; } - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); return true; } @@ -323,8 +323,8 @@ private static bool TryGetRangeLength(string input, ref int current, out int fro return false; } - current = current + fromLength; - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += fromLength; + current += HttpRuleParser.GetWhitespaceLength(input, current); // After the first value, the '-' character must follow. if ((current == input.Length) || (input[current] != '-')) @@ -334,7 +334,7 @@ private static bool TryGetRangeLength(string input, ref int current, out int fro } current++; // skip the '-' character - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); if (current == input.Length) { @@ -350,10 +350,10 @@ private static bool TryGetRangeLength(string input, ref int current, out int fro return false; } - current = current + toLength; + current += toLength; } - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); return true; } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/EntityTagHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/EntityTagHeaderValue.cs index f3c1f07e1021f1..2a7c7e39e61734 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/EntityTagHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/EntityTagHeaderValue.cs @@ -143,7 +143,7 @@ internal static int GetEntityTagLength(string? input, int startIndex, out Entity } isWeak = true; current++; // we have a weak-entity tag. - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); } int tagStartIndex = current; @@ -165,9 +165,9 @@ internal static int GetEntityTagLength(string? input, int startIndex, out Entity parsedValue = new EntityTagHeaderValue(input.Substring(tagStartIndex, tagLength), isWeak); } - current = current + tagLength; + current += tagLength; } - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); return current - startIndex; } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderUtilities.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderUtilities.cs index 7975f3fc42b367..14b1075ec1f775 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderUtilities.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HeaderUtilities.cs @@ -267,14 +267,14 @@ internal static int GetNextNonEmptyOrWhitespaceIndex(string input, int startInde // empty values, continue until the current character is neither a separator nor a whitespace. separatorFound = true; current++; // skip delimiter. - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); if (skipEmptyValues) { while ((current < input.Length) && (input[current] == ',')) { current++; // skip delimiter. - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/MediaTypeHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/MediaTypeHeaderValue.cs index 47855527860dca..3cceffb67a43e6 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/MediaTypeHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/MediaTypeHeaderValue.cs @@ -168,7 +168,7 @@ internal static int GetMediaTypeLength(string? input, int startIndex, } int current = startIndex + mediaTypeLength; - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); MediaTypeHeaderValue mediaTypeHeader; // If we're not done and we have a parameter delimiter, then we have a list of parameters. @@ -213,7 +213,7 @@ private static int GetMediaTypeExpressionLength(string input, int startIndex, ou } int current = startIndex + typeLength; - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); // Parse the separator between type and subtype if ((current >= input.Length) || (input[current] != '/')) @@ -221,7 +221,7 @@ private static int GetMediaTypeExpressionLength(string input, int startIndex, ou return 0; } current++; // skip delimiter. - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); // Parse the subtype, i.e. in media type string "/; param1=value1; param2=value2" int subtypeLength = HttpRuleParser.GetTokenLength(input, current); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/NameValueHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/NameValueHeaderValue.cs index 9084597b1f90cd..5160733432ca81 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/NameValueHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/NameValueHeaderValue.cs @@ -193,7 +193,7 @@ internal static int GetHashCode(UnvalidatedObjectCollection in name/value string "=" int valueLength = GetValueLength(input, current); @@ -255,8 +255,8 @@ internal static int GetNameValueLength(string input, int startIndex, parsedValue = nameValueCreator(); parsedValue._name = name; parsedValue._value = input.Substring(current, valueLength); - current = current + valueLength; - current = current + HttpRuleParser.GetWhitespaceLength(input, current); // skip whitespace + current += valueLength; + current += HttpRuleParser.GetWhitespaceLength(input, current); // skip whitespace return current - startIndex; } @@ -286,8 +286,8 @@ internal static int GetNameValueListLength(string? input, int startIndex, char d } nameValueCollection.Add(parameter!); - current = current + nameValueLength; - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += nameValueLength; + current += HttpRuleParser.GetWhitespaceLength(input, current); if ((current == input.Length) || (input[current] != delimiter)) { @@ -297,7 +297,7 @@ internal static int GetNameValueListLength(string? input, int startIndex, char d // input[current] is 'delimiter'. Skip the delimiter and whitespace and try to parse again. current++; // skip delimiter. - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/NameValueWithParametersHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/NameValueWithParametersHeaderValue.cs index f02ffc3d8da7db..0f7bba3d3ce777 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/NameValueWithParametersHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/NameValueWithParametersHeaderValue.cs @@ -114,7 +114,7 @@ internal static int GetNameValueWithParametersLength(string? input, int startInd } int current = startIndex + nameValueLength; - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); NameValueWithParametersHeaderValue? nameValueWithParameters = nameValue as NameValueWithParametersHeaderValue; Debug.Assert(nameValueWithParameters != null); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductHeaderValue.cs index 555b1eb1a73c06..a6013b8616fcd4 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductHeaderValue.cs @@ -76,7 +76,7 @@ public override int GetHashCode() if (!string.IsNullOrEmpty(_version)) { - result = result ^ StringComparer.OrdinalIgnoreCase.GetHashCode(_version); + result ^= StringComparer.OrdinalIgnoreCase.GetHashCode(_version); } return result; @@ -122,7 +122,7 @@ internal static int GetProductLength(string input, int startIndex, out ProductHe string name = input.Substring(startIndex, nameLength); int current = startIndex + nameLength; - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); if ((current == input.Length) || (input[current] != '/')) { @@ -131,7 +131,7 @@ internal static int GetProductLength(string input, int startIndex, out ProductHe } current++; // Skip '/' delimiter. - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); // Parse the name string: in '/'. int versionLength = HttpRuleParser.GetTokenLength(input, current); @@ -143,8 +143,8 @@ internal static int GetProductLength(string input, int startIndex, out ProductHe string version = input.Substring(current, versionLength); - current = current + versionLength; - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += versionLength; + current += HttpRuleParser.GetWhitespaceLength(input, current); parsedValue = new ProductHeaderValue(name, version); return current - startIndex; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductInfoHeaderParser.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductInfoHeaderParser.cs index f224eeb10481db..47ff3bfdbdd7be 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductInfoHeaderParser.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductInfoHeaderParser.cs @@ -46,7 +46,7 @@ public override bool TryParseValue([NotNullWhen(true)] string? value, object? st } // GetProductInfoLength() already skipped trailing whitespace. No need to do it here again. - current = current + length; + current += length; // If we have more values, make sure we saw a whitespace before. Values like "product/1.0(comment)" are // invalid since there must be a whitespace between the product and the comment value. diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductInfoHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductInfoHeaderValue.cs index 2e52dbd7f1911d..40a6b474e6450a 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductInfoHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ProductInfoHeaderValue.cs @@ -144,8 +144,8 @@ internal static int GetProductInfoLength(string? input, int startIndex, out Prod comment = input.Substring(current, commentLength); - current = current + commentLength; - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += commentLength; + current += HttpRuleParser.GetWhitespaceLength(input, current); parsedValue = new ProductInfoHeaderValue(comment); } @@ -159,7 +159,7 @@ internal static int GetProductInfoLength(string? input, int startIndex, out Prod return 0; } - current = current + productLength; + current += productLength; parsedValue = new ProductInfoHeaderValue(product!); } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RangeConditionHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RangeConditionHeaderValue.cs index a445cc597b7c56..e85de153f92349 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RangeConditionHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RangeConditionHeaderValue.cs @@ -139,7 +139,7 @@ internal static int GetRangeConditionLength(string? input, int startIndex, out o return 0; } - current = current + entityTagLength; + current += entityTagLength; // RangeConditionHeaderValue only allows 1 value. There must be no delimiter/other chars after an // entity tag. diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RangeHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RangeHeaderValue.cs index 0f81df89293fa6..28f64786ec502c 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RangeHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RangeHeaderValue.cs @@ -102,7 +102,7 @@ public override int GetHashCode() { foreach (RangeItemHeaderValue range in _ranges) { - result = result ^ range.GetHashCode(); + result ^= range.GetHashCode(); } } @@ -150,7 +150,7 @@ internal static int GetRangeLength(string? input, int startIndex, out object? pa RangeHeaderValue result = new RangeHeaderValue(); result._unit = input.Substring(startIndex, unitLength); int current = startIndex + unitLength; - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); if ((current == input.Length) || (input[current] != '=')) { @@ -158,7 +158,7 @@ internal static int GetRangeLength(string? input, int startIndex, out object? pa } current++; // skip '=' separator - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); int rangesLength = RangeItemHeaderValue.GetRangeItemListLength(input, current, result.Ranges); @@ -167,7 +167,7 @@ internal static int GetRangeLength(string? input, int startIndex, out object? pa return 0; } - current = current + rangesLength; + current += rangesLength; Debug.Assert(current == input.Length, "GetRangeItemListLength() should consume the whole string or fail."); parsedValue = result; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RangeItemHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RangeItemHeaderValue.cs index 8c14da848b1d08..f257b7d860d7e9 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RangeItemHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RangeItemHeaderValue.cs @@ -130,7 +130,7 @@ internal static int GetRangeItemListLength(string? input, int startIndex, rangeCollection.Add(range!); - current = current + rangeLength; + current += rangeLength; current = HeaderUtilities.GetNextNonEmptyOrWhitespaceIndex(input, current, true, out bool separatorFound); // If the string is not consumed, we must have a delimiter, otherwise the string is not a valid @@ -172,8 +172,8 @@ internal static int GetRangeItemLength(string? input, int startIndex, out RangeI return 0; } - current = current + fromLength; - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += fromLength; + current += HttpRuleParser.GetWhitespaceLength(input, current); // After the first value, the '-' character must follow. if ((current == input.Length) || (input[current] != '-')) @@ -183,7 +183,7 @@ internal static int GetRangeItemLength(string? input, int startIndex, out RangeI } current++; // skip the '-' character - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); int toStartIndex = current; int toLength = 0; @@ -198,8 +198,8 @@ internal static int GetRangeItemLength(string? input, int startIndex, out RangeI return 0; } - current = current + toLength; - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += toLength; + current += HttpRuleParser.GetWhitespaceLength(input, current); } if ((fromLength == 0) && (toLength == 0)) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RetryConditionHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RetryConditionHeaderValue.cs index 84bb302c6f9ab9..3e8bbe62e516e9 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RetryConditionHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/RetryConditionHeaderValue.cs @@ -138,8 +138,8 @@ internal static int GetRetryConditionLength(string? input, int startIndex, out o return 0; } - current = current + deltaLength; - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += deltaLength; + current += HttpRuleParser.GetWhitespaceLength(input, current); // RetryConditionHeaderValue only allows 1 value. There must be no delimiter/other chars after 'delta' if (current != input.Length) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/StringWithQualityHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/StringWithQualityHeaderValue.cs index 377a2113dfa888..6059f7b7642c43 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/StringWithQualityHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/StringWithQualityHeaderValue.cs @@ -93,7 +93,7 @@ public override int GetHashCode() if (_quality.HasValue) { - result = result ^ _quality.Value.GetHashCode(); + result ^= _quality.Value.GetHashCode(); } return result; @@ -141,7 +141,7 @@ internal static int GetStringWithQualityLength(string? input, int startIndex, ou string value = input.Substring(startIndex, valueLength); int current = startIndex + valueLength; - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); if ((current == input.Length) || (input[current] != ';')) { @@ -150,7 +150,7 @@ internal static int GetStringWithQualityLength(string? input, int startIndex, ou } current++; // skip ';' separator - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); // If we found a ';' separator, it must be followed by a quality information if (!TryReadQuality(input, out double quality, ref current)) @@ -174,7 +174,7 @@ private static bool TryReadQuality(string input, out double quality, ref int ind } current++; // skip 'q' identifier - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); // If we found "q" it must be followed by "=" if ((current == input.Length) || (input[current] != '=')) @@ -183,7 +183,7 @@ private static bool TryReadQuality(string input, out double quality, ref int ind } current++; // skip '=' separator - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); if (current == input.Length) { @@ -208,8 +208,8 @@ private static bool TryReadQuality(string input, out double quality, ref int ind return false; } - current = current + qualityLength; - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += qualityLength; + current += HttpRuleParser.GetWhitespaceLength(input, current); index = current; return true; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/TransferCodingHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/TransferCodingHeaderValue.cs index 74e2aa30f53969..592560997e0b81 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/TransferCodingHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/TransferCodingHeaderValue.cs @@ -80,7 +80,7 @@ internal static int GetTransferCodingLength(string input, int startIndex, string value = input.Substring(startIndex, valueLength); int current = startIndex + valueLength; - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); TransferCodingHeaderValue transferCodingHeader; // If we're not done and we have a parameter delimiter, then we have a list of parameters. diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ViaHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ViaHeaderValue.cs index a2afd99c3bc8d6..98012dafa7edca 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ViaHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/ViaHeaderValue.cs @@ -123,12 +123,12 @@ public override int GetHashCode() if (!string.IsNullOrEmpty(_protocolName)) { - result = result ^ StringComparer.OrdinalIgnoreCase.GetHashCode(_protocolName); + result ^= StringComparer.OrdinalIgnoreCase.GetHashCode(_protocolName); } if (!string.IsNullOrEmpty(_comment)) { - result = result ^ _comment.GetHashCode(); + result ^= _comment.GetHashCode(); } return result; @@ -183,9 +183,9 @@ internal static int GetViaLength(string? input, int startIndex, out object? pars } string receivedBy = input.Substring(current, receivedByLength); - current = current + receivedByLength; + current += receivedByLength; - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); string? comment = null; if ((current < input.Length) && (input[current] == '(')) @@ -199,8 +199,8 @@ internal static int GetViaLength(string? input, int startIndex, out object? pars comment = input.Substring(current, commentLength); - current = current + commentLength; - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += commentLength; + current += HttpRuleParser.GetWhitespaceLength(input, current); } parsedValue = new ViaHeaderValue(protocolVersion, receivedBy!, protocolName, comment); @@ -227,7 +227,7 @@ private static int GetProtocolEndIndex(string input, int startIndex, out string? current = startIndex + protocolVersionOrNameLength; int whitespaceLength = HttpRuleParser.GetWhitespaceLength(input, current); - current = current + whitespaceLength; + current += whitespaceLength; if (current == input.Length) { @@ -240,7 +240,7 @@ private static int GetProtocolEndIndex(string input, int startIndex, out string? protocolName = input.Substring(startIndex, protocolVersionOrNameLength); current++; // skip the '/' delimiter - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); protocolVersionOrNameLength = HttpRuleParser.GetTokenLength(input, current); @@ -251,9 +251,9 @@ private static int GetProtocolEndIndex(string input, int startIndex, out string? protocolVersion = input.Substring(current, protocolVersionOrNameLength); - current = current + protocolVersionOrNameLength; + current += protocolVersionOrNameLength; whitespaceLength = HttpRuleParser.GetWhitespaceLength(input, current); - current = current + whitespaceLength; + current += whitespaceLength; } else { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/WarningHeaderValue.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/WarningHeaderValue.cs index d70b666d3c1cda..8c0757e08df35b 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/WarningHeaderValue.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/WarningHeaderValue.cs @@ -126,7 +126,7 @@ public override int GetHashCode() if (_date.HasValue) { - result = result ^ _date.Value.GetHashCode(); + result ^= _date.Value.GetHashCode(); } return result; @@ -187,7 +187,7 @@ internal static int GetWarningLength(string? input, int startIndex, out object? string text = input.Substring(textStartIndex, textLength); - current = current + textLength; + current += textLength; // Read in ' [""]' DateTimeOffset? date; @@ -214,10 +214,10 @@ private static bool TryReadAgent(string input, ref int current, [NotNullWhen(tru } agent = input.Substring(current, agentLength); - current = current + agentLength; + current += agentLength; int whitespaceLength = HttpRuleParser.GetWhitespaceLength(input, current); - current = current + whitespaceLength; + current += whitespaceLength; // At least one whitespace required after . Also make sure we have characters left for if ((whitespaceLength == 0) || (current == input.Length)) @@ -246,10 +246,10 @@ private static bool TryReadCode(string input, ref int current, out int code) return false; } - current = current + codeLength; + current += codeLength; int whitespaceLength = HttpRuleParser.GetWhitespaceLength(input, current); - current = current + whitespaceLength; + current += whitespaceLength; // Make sure the number is followed by at least one whitespace and that we have characters left to parse. if ((whitespaceLength == 0) || (current == input.Length)) @@ -266,7 +266,7 @@ private static bool TryReadDate(string input, ref int current, out DateTimeOffse // Make sure we have at least one whitespace between and (if we have ) int whitespaceLength = HttpRuleParser.GetWhitespaceLength(input, current); - current = current + whitespaceLength; + current += whitespaceLength; // Read in ' [""]' if ((current < input.Length) && (input[current] == '"')) @@ -303,7 +303,7 @@ private static bool TryReadDate(string input, ref int current, out DateTimeOffse date = temp; current++; // skip closing '"' - current = current + HttpRuleParser.GetWhitespaceLength(input, current); + current += HttpRuleParser.GetWhitespaceLength(input, current); } return true; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpRuleParser.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpRuleParser.cs index deadd8b5b25e7b..f7c5564edf71f1 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpRuleParser.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpRuleParser.cs @@ -315,7 +315,7 @@ private static HttpParseResult GetExpressionLength(string input, int startIndex, // We ignore invalid quoted-pairs. Invalid quoted-pairs may mean that it looked like a quoted pair, // but we actually have a quoted-string: e.g. "\\u00FC" ('\' followed by a char >127 - quoted-pair only // allows ASCII chars after '\'; qdtext allows both '\' and >127 chars). - current = current + quotedPairLength; + current += quotedPairLength; continue; } diff --git a/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpResponseStream.Windows.cs b/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpResponseStream.Windows.cs index dc54f6cd6bfae0..37eabcd78cf49d 100644 --- a/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpResponseStream.Windows.cs +++ b/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpResponseStream.Windows.cs @@ -78,7 +78,7 @@ private void WriteCore(byte[] buffer, int offset, int size) if (_httpContext.Response.BoundaryType == BoundaryType.Chunked) { string chunkHeader = size.ToString("x", CultureInfo.InvariantCulture); - dataToWrite = dataToWrite + (uint)(chunkHeader.Length + 4); + dataToWrite += (uint)(chunkHeader.Length + 4); bufferAsIntPtr = SafeLocalAllocHandle.LocalAlloc((int)dataToWrite); pBufferAsIntPtr = bufferAsIntPtr.DangerousGetHandle(); for (int i = 0; i < chunkHeader.Length; i++) diff --git a/src/libraries/System.Net.Mail/src/System/Net/Mail/MailPriority.cs b/src/libraries/System.Net.Mail/src/System/Net/Mail/MailPriority.cs index 0744a29bb99b4b..6ceea22e88a6a8 100644 --- a/src/libraries/System.Net.Mail/src/System/Net/Mail/MailPriority.cs +++ b/src/libraries/System.Net.Mail/src/System/Net/Mail/MailPriority.cs @@ -147,7 +147,7 @@ internal string? Subject { // Store the decoded value, we'll re-encode before sending value = MimeBasePart.DecodeHeaderValue(value); - _subjectEncoding = _subjectEncoding ?? inputEncoding; + _subjectEncoding ??= inputEncoding; } // Failed to decode, just pass it through as ascii (legacy) catch (FormatException) { } diff --git a/src/libraries/System.Net.Requests/src/System/Net/FtpControlStream.cs b/src/libraries/System.Net.Requests/src/System/Net/FtpControlStream.cs index a093ef49c98e83..af30b091813092 100644 --- a/src/libraries/System.Net.Requests/src/System/Net/FtpControlStream.cs +++ b/src/libraries/System.Net.Requests/src/System/Net/FtpControlStream.cs @@ -1039,8 +1039,7 @@ private static int GetPortV4(string responseString) index--; int port = Convert.ToByte(parsedList[index--], NumberFormatInfo.InvariantInfo); - port = port | - (Convert.ToByte(parsedList[index--], NumberFormatInfo.InvariantInfo) << 8); + port |= (Convert.ToByte(parsedList[index--], NumberFormatInfo.InvariantInfo) << 8); return port; } diff --git a/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/ManagedWebSocket.cs b/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/ManagedWebSocket.cs index 88c011565d6491..4130cff1cc65df 100644 --- a/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/ManagedWebSocket.cs +++ b/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/ManagedWebSocket.cs @@ -620,7 +620,7 @@ private static int WriteHeader(MessageOpcode opcode, byte[] sendBuffer, ReadOnly for (int i = 9; i >= 2; i--) { sendBuffer[i] = unchecked((byte)length); - length = length / 256; + length /= 256; } maskOffset = 2 + sizeof(ulong); // additional 8 bytes for 64-bit length } diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/DirectoryInfo.cs b/src/libraries/System.Private.CoreLib/src/System/IO/DirectoryInfo.cs index 2417f93f556b30..c47ef747ee9882 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/DirectoryInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/DirectoryInfo.cs @@ -31,7 +31,7 @@ private void Init(string originalPath, string? fullPath = null, string? fileName OriginalPath = originalPath; - fullPath = fullPath ?? originalPath; + fullPath ??= originalPath; fullPath = isNormalized ? fullPath : Path.GetFullPath(fullPath); _name = fileName ?? (PathInternal.IsRoot(fullPath.AsSpan()) ? diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/FileInfo.cs b/src/libraries/System.Private.CoreLib/src/System/IO/FileInfo.cs index efa2a139b133bf..3b9cc7b9f14179 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/FileInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/FileInfo.cs @@ -25,7 +25,7 @@ internal FileInfo(string originalPath, string? fullPath = null, string? fileName // Want to throw the original argument name OriginalPath = originalPath; - fullPath = fullPath ?? originalPath; + fullPath ??= originalPath; Debug.Assert(!isNormalized || !PathInternal.IsPartiallyQualified(fullPath.AsSpan()), "should be fully qualified if normalized"); FullPath = isNormalized ? fullPath ?? originalPath : Path.GetFullPath(fullPath); diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs b/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs index 8fd4df503b0f9d..84001aa728f9f4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/ASCIIUtility.cs @@ -198,7 +198,7 @@ private static unsafe nuint GetIndexOfFirstNonAsciiByte_Default(byte* pBuffer, n { if (!BitConverter.IsLittleEndian) { - currentUInt32 = currentUInt32 << 16; + currentUInt32 <<= 16; } goto FoundNonAsciiData; } @@ -1680,7 +1680,7 @@ public static unsafe nuint WidenAsciiToUtf16(byte* pAsciiBuffer, char* pUtf16Buf { if (!BitConverter.IsLittleEndian) { - asciiData = asciiData << 16; + asciiData <<= 16; } goto FoundNonAsciiData; } diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/ExtensionDataReader.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/ExtensionDataReader.cs index bb9f446bfd3d71..0fe6ffba9f56d3 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/ExtensionDataReader.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/ExtensionDataReader.cs @@ -484,7 +484,7 @@ private void GrowElementsIfNeeded() internal static string GetPrefix(string? ns) { - ns = ns ?? string.Empty; + ns ??= string.Empty; string? prefix = (string?)s_nsToPrefixTable[ns]; if (prefix == null) { diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/Json/JsonWriterDelegator.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/Json/JsonWriterDelegator.cs index d14a3847c3ffe0..60433c1382d794 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/Json/JsonWriterDelegator.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/Json/JsonWriterDelegator.cs @@ -191,7 +191,7 @@ private void WriteDateTimeInDefaultFormat(DateTime value) long tickCount = value.Ticks; if (lowBound > tickCount || highBound < tickCount) // We could potentially under/over flow { - tickCount = tickCount - TimeZoneInfo.Local.GetUtcOffset(value).Ticks; + tickCount -= TimeZoneInfo.Local.GetUtcOffset(value).Ticks; if ((tickCount > DateTime.MaxValue.Ticks) || (tickCount < DateTime.MinValue.Ticks)) { throw XmlObjectSerializer.CreateSerializationException(SR.JsonDateTimeOutOfRange, new ArgumentOutOfRangeException(nameof(value))); diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlObjectSerializerReadContext.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlObjectSerializerReadContext.cs index 39514458130825..39ce7dfb2ab5b0 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlObjectSerializerReadContext.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/XmlObjectSerializerReadContext.cs @@ -1009,8 +1009,8 @@ internal XmlReaderDelegator CreateReaderOverChildNodes(IList? xmlA internal static XmlNode CreateWrapperXmlElement(XmlDocument document, IList? xmlAttributes, IList xmlChildNodes, string? prefix, string? localName, string? ns) { - localName = localName ?? "wrapper"; - ns = ns ?? string.Empty; + localName ??= "wrapper"; + ns ??= string.Empty; XmlElement wrapperElement = document.CreateElement(prefix, localName, ns); if (xmlAttributes != null) { diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/ArrayHelper.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/ArrayHelper.cs index 05bffd65b03b29..3baa246fd2a4ef 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/ArrayHelper.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/ArrayHelper.cs @@ -38,10 +38,9 @@ public TArray[] ReadArray(XmlDictionaryReader reader, TArgument localName, TArgu totalRead += read; if (read < array.Length || reader.NodeType == XmlNodeType.EndElement) break; - if (arrays == null) - arrays = new TArray[32][]; + arrays ??= new TArray[32][]; arrays[arrayCount++] = array; - count = count * 2; + count *= 2; } if (totalRead != array.Length || arrayCount > 0) { diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBaseReader.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBaseReader.cs index 928e571a7366ea..07908253c08c0c 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBaseReader.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBaseReader.cs @@ -1485,7 +1485,7 @@ private int ReadBytes(Encoding encoding, int byteBlock, int charBlock, byte[] bu { if (_trailChars == null) _trailChars = new char[4]; - charCount = charCount - _trailCharCount; + charCount -= _trailCharCount; Array.Copy(chars, charCount, _trailChars, 0, _trailCharCount); } } diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBinaryWriter.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBinaryWriter.cs index 7b060146400a68..7ed8b8ebfc6703 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBinaryWriter.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlBinaryWriter.cs @@ -815,12 +815,12 @@ private static long ToBinary(DateTime dt) switch (dt.Kind) { case DateTimeKind.Local: - temp = temp | -9223372036854775808L; // 0x8000000000000000 - temp = temp | dt.ToUniversalTime().Ticks; + temp |= -9223372036854775808L; // 0x8000000000000000 + temp |= dt.ToUniversalTime().Ticks; break; case DateTimeKind.Utc: - temp = temp | 0x4000000000000000L; - temp = temp | dt.Ticks; + temp |= 0x4000000000000000L; + temp |= dt.Ticks; break; case DateTimeKind.Unspecified: temp = dt.Ticks; diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlDictionaryReader.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlDictionaryReader.cs index e2daea3d7425a0..2eb1a86b865b6a 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlDictionaryReader.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlDictionaryReader.cs @@ -534,7 +534,7 @@ private byte[] ReadContentAsBytes(bool base64, int maxByteArrayContentLength) totalRead += read; if (read < buffer.Length) break; - count = count * 2; + count *= 2; } buffer = new byte[totalRead]; int offset = 0; diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlDictionaryWriter.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlDictionaryWriter.cs index 49babc9f9f167e..091df90f056efe 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlDictionaryWriter.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlDictionaryWriter.cs @@ -217,7 +217,7 @@ public virtual void WriteValue(IStreamProvider value) break; if (blockSize < 65536 && bytesRead == blockSize) { - blockSize = blockSize * 16; + blockSize *= 16; block = new byte[blockSize]; } } diff --git a/src/libraries/System.Private.Uri/src/System/UriExt.cs b/src/libraries/System.Private.Uri/src/System/UriExt.cs index ff5f5776c541ca..fba947f22e68e0 100644 --- a/src/libraries/System.Private.Uri/src/System/UriExt.cs +++ b/src/libraries/System.Private.Uri/src/System/UriExt.cs @@ -459,22 +459,22 @@ internal unsafe bool InternalIsWellFormedOriginalString() { if ((nonCanonical & (Flags.E_UserNotCanonical | Flags.UserIriCanonical)) == (Flags.E_UserNotCanonical | Flags.UserIriCanonical)) { - nonCanonical = nonCanonical & ~(Flags.E_UserNotCanonical | Flags.UserIriCanonical); + nonCanonical &= ~(Flags.E_UserNotCanonical | Flags.UserIriCanonical); } if ((nonCanonical & (Flags.E_PathNotCanonical | Flags.PathIriCanonical)) == (Flags.E_PathNotCanonical | Flags.PathIriCanonical)) { - nonCanonical = nonCanonical & ~(Flags.E_PathNotCanonical | Flags.PathIriCanonical); + nonCanonical &= ~(Flags.E_PathNotCanonical | Flags.PathIriCanonical); } if ((nonCanonical & (Flags.E_QueryNotCanonical | Flags.QueryIriCanonical)) == (Flags.E_QueryNotCanonical | Flags.QueryIriCanonical)) { - nonCanonical = nonCanonical & ~(Flags.E_QueryNotCanonical | Flags.QueryIriCanonical); + nonCanonical &= ~(Flags.E_QueryNotCanonical | Flags.QueryIriCanonical); } if ((nonCanonical & (Flags.E_FragmentNotCanonical | Flags.FragmentIriCanonical)) == (Flags.E_FragmentNotCanonical | Flags.FragmentIriCanonical)) { - nonCanonical = nonCanonical & ~(Flags.E_FragmentNotCanonical | Flags.FragmentIriCanonical); + nonCanonical &= ~(Flags.E_FragmentNotCanonical | Flags.FragmentIriCanonical); } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/SqlUtils.cs b/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/SqlUtils.cs index a88f9cfde36f40..d22aefc772f722 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/SqlUtils.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/SqlUtils.cs @@ -455,7 +455,7 @@ private static void BreakDownXsdDate(long val, out int yr, out int mnth, out int { if (val < 0) goto Error; - val = val / 4; // trim indicator bits + val /= 4; // trim indicator bits int totalMin = (int)(val % (29 * 60)) - 60 * 14; long totalDays = val / (29 * 60); @@ -480,7 +480,7 @@ private static void BreakDownXsdTime(long val, out int hr, out int min, out int { if (val < 0) goto Error; - val = val / 4; // trim indicator bits + val /= 4; // trim indicator bits ms = (int)(val % 1000); val /= 1000; sec = (int)(val % 60); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/XmlBinaryReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/XmlBinaryReader.cs index 2e0e70a96eae26..fddf94c8ee5575 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/XmlBinaryReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/XmlBinaryReader.cs @@ -387,7 +387,7 @@ public XmlSqlBinaryReader(Stream stream, byte[] data, int len, string baseUri, b _ignorePIs = settings.IgnoreProcessingInstructions; _ignoreComments = settings.IgnoreComments; - s_tokenTypeMap = s_tokenTypeMap ?? GenerateTokenTypeMap(); + s_tokenTypeMap ??= GenerateTokenTypeMap(); } public override XmlReaderSettings Settings @@ -2095,17 +2095,17 @@ private int ParseMB32_(byte b) Debug.Assert(0 != (b & 0x80)); b = ReadByte(); t = (uint)b & (uint)0x7F; - u = u + (t << 7); + u += (t << 7); if (b > 127) { b = ReadByte(); t = (uint)b & (uint)0x7F; - u = u + (t << 14); + u += (t << 14); if (b > 127) { b = ReadByte(); t = (uint)b & (uint)0x7F; - u = u + (t << 21); + u += (t << 21); if (b > 127) { b = ReadByte(); @@ -2115,7 +2115,7 @@ private int ParseMB32_(byte b) t = (uint)b & (uint)0x07; if (b > 7) throw ThrowXmlException(SR.XmlBinary_ValueTooBig); - u = u + (t << 28); + u += (t << 28); } } } @@ -2134,17 +2134,17 @@ private int ParseMB32(int pos) { b = data[pos++]; t = (uint)b & (uint)0x7F; - u = u + (t << 7); + u += (t << 7); if (b > 127) { b = data[pos++]; t = (uint)b & (uint)0x7F; - u = u + (t << 14); + u += (t << 14); if (b > 127) { b = data[pos++]; t = (uint)b & (uint)0x7F; - u = u + (t << 21); + u += (t << 21); if (b > 127) { b = data[pos++]; @@ -2152,7 +2152,7 @@ private int ParseMB32(int pos) t = (uint)b & (uint)0x07; if (b > 7) throw ThrowXmlException(SR.XmlBinary_ValueTooBig); - u = u + (t << 28); + u += (t << 28); } } } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs index 9819b04db6c302..224eab23a651d0 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImpl.cs @@ -3466,7 +3466,7 @@ private int ReadData() int copyCharsCount = _ps.charsUsed - _ps.charPos; if (copyCharsCount < charsLen - 1) { - _ps.lineStartPos = _ps.lineStartPos - _ps.charPos; + _ps.lineStartPos -= _ps.charPos; if (copyCharsCount > 0) { BlockCopyChars(_ps.chars, _ps.charPos, _ps.chars, 0, copyCharsCount); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImplAsync.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImplAsync.cs index 1f4672577e2c40..b828f2ad976e94 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImplAsync.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/XmlTextReaderImplAsync.cs @@ -1128,7 +1128,7 @@ private async Task ReadDataAsync() int copyCharsCount = _ps.charsUsed - _ps.charPos; if (copyCharsCount < charsLen - 1) { - _ps.lineStartPos = _ps.lineStartPos - _ps.charPos; + _ps.lineStartPos -= _ps.charPos; if (copyCharsCount > 0) { BlockCopyChars(_ps.chars, _ps.charPos, _ps.chars, 0, copyCharsCount); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Dom/DocumentSchemaValidator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Dom/DocumentSchemaValidator.cs index 5b5e5089f888b5..d1ffd7ae950015 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Dom/DocumentSchemaValidator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Dom/DocumentSchemaValidator.cs @@ -525,7 +525,7 @@ private void SetDefaultAttributeSchemaInfo(XmlSchemaAttribute schemaAttribute) if (parentNode == null) { //Did not find any type info all the way to the root, currentNode is Document || DocumentFragment - nodeIndex = nodeIndex - 1; //Subtract the one for document and set the node to null + nodeIndex--; //Subtract the one for document and set the node to null _nodeSequenceToValidate![nodeIndex] = null; return GetTypeFromAncestors(elementToValidate, null, nodeIndex); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/ContentValidator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/ContentValidator.cs index a4ec00be589ab3..c7309296d1fbd5 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/ContentValidator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/ContentValidator.cs @@ -1929,7 +1929,7 @@ public override void InitValidation(ValidationState context) { //If the first bitset itself matched, then no need to remove anything runningPositions!.RemoveRange(0, k); //Delete entries from 0 to k-1 } - matchCount = matchCount - k; + matchCount -= k; k = 0; // Since we re-sized the array while (k < matchCount) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/FacetChecker.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/FacetChecker.cs index a29d4928dc8b08..57500d13e2e175 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/FacetChecker.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/FacetChecker.cs @@ -986,7 +986,7 @@ internal static decimal Power(int x, int y) } for (int i = 0; i < y; i++) { - returnValue = returnValue * decimalValue; + returnValue *= decimalValue; } return returnValue; } @@ -1110,7 +1110,7 @@ internal static bool MatchEnumeration(decimal value, ArrayList enumeration, XmlV } while (decimal.Truncate(value) != value) { //Till it has a fraction - value = value * 10; + value *= 10; powerCnt++; } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlReflectionImporter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlReflectionImporter.cs index f3fb4eb9fb230b..9d6998aba7e72f 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlReflectionImporter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlReflectionImporter.cs @@ -2253,7 +2253,7 @@ private static ElementAccessor CreateElementAccessor(TypeMapping mapping, string [RequiresUnreferencedCode("Calls TypeScope.GetTypeDesc(Type) which has RequiresUnreferencedCode")] internal static XmlTypeMapping GetTopLevelMapping(Type type, string? defaultNamespace) { - defaultNamespace = defaultNamespace ?? string.Empty; + defaultNamespace ??= string.Empty; XmlAttributes a = new XmlAttributes(type); TypeDesc typeDesc = new TypeScope().GetTypeDesc(type); ElementAccessor element = new ElementAccessor(); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemaImporter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemaImporter.cs index fbc15d44dc3754..7c7c3b6648c086 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemaImporter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemaImporter.cs @@ -1389,7 +1389,7 @@ private bool IsCyclicReferencedType(XmlSchemaElement element, List ident [RequiresUnreferencedCode("calls ImportSubstitutionGroupMember")] private void ImportElementMember(XmlSchemaElement element, string identifier, CodeIdentifiers members, CodeIdentifiers membersScope, INameScope elementsScope, string? ns, bool repeats, ref bool needExplicitOrder, bool allowDuplicates, bool allowUnboundedElements) { - repeats = repeats | element.IsMultipleOccurrence; + repeats |= element.IsMultipleOccurrence; XmlSchemaElement? headElement = GetTopLevelElement(element); if (headElement != null && ImportSubstitutionGroupMember(headElement, identifier, members, membersScope, ns, repeats, ref needExplicitOrder, allowDuplicates)) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriter.cs index 11449885a9a6e7..bcdfd587ac7f7b 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriter.cs @@ -1222,7 +1222,7 @@ private void WriteArray(string name, string? ns, object o, Type type) } if (arrayDims.Length > 0) - typeName = typeName + arrayDims.ToString(); + typeName += arrayDims.ToString(); if (_soap12 && name != null && name.Length > 0) WriteStartElement(name, ns, null, false); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPathConvert.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPathConvert.cs index db78c6ce2501dd..abce1eebfb2bf8 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPathConvert.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPathConvert.cs @@ -428,7 +428,7 @@ private void Normalize() w2 = 32 - w1; _u2 = (_u2 << w1) | (_u1 >> w2); _u1 = (_u1 << w1) | (_u0 >> w2); - _u0 = (_u0 << w1); + _u0 <<= w1; _exp -= w1; } } diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BitArithmetic.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BitArithmetic.cs index 32eb1b402454dc..7ad3c4aba6e618 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BitArithmetic.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BitArithmetic.cs @@ -22,7 +22,7 @@ internal static int CountBits(uint v) #else unchecked { - v = v - ((v >> 1) & 0x55555555u); + v -= ((v >> 1) & 0x55555555u); v = (v & 0x33333333u) + ((v >> 2) & 0x33333333u); return (int)((v + (v >> 4) & 0xF0F0F0Fu) * 0x1010101u) >> 24; } @@ -38,7 +38,7 @@ internal static int CountBits(ulong v) const ulong Mask00110011 = 0x3333333333333333UL; const ulong Mask00001111 = 0x0F0F0F0F0F0F0F0FUL; const ulong Mask00000001 = 0x0101010101010101UL; - v = v - ((v >> 1) & Mask01010101); + v -= ((v >> 1) & Mask01010101); v = (v & Mask00110011) + ((v >> 2) & Mask00110011); return (int)(unchecked(((v + (v >> 4)) & Mask00001111) * Mask00000001) >> 56); #endif diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEReader.EmbeddedPortablePdb.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEReader.EmbeddedPortablePdb.cs index a099e858919c25..08ba31fdda3c05 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEReader.EmbeddedPortablePdb.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEReader.EmbeddedPortablePdb.cs @@ -158,7 +158,7 @@ partial void TryOpenEmbeddedPortablePdb(DebugDirectoryEntry embeddedPdbEntry, re } catch (Exception e) when (e is BadImageFormatException || e is IOException) { - errorToReport = errorToReport ?? e; + errorToReport ??= e; openedEmbeddedPdb = false; } finally diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEReader.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEReader.cs index be70102491819f..eda470b5bd7137 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEReader.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEReader.cs @@ -768,7 +768,7 @@ private bool TryOpenCodeViewPortablePdb(DebugDirectoryEntry codeViewEntry, strin } catch (Exception e) when (e is BadImageFormatException || e is IOException) { - errorToReport = errorToReport ?? e; + errorToReport ??= e; return false; } @@ -832,7 +832,7 @@ private static bool TryOpenPortablePdbFile(string path, BlobContentId id, Func left, ReadOnlySpan right, u { carry += right[i] * q; uint digit = unchecked((uint)carry); - carry = carry >> 32; + carry >>= 32; ref uint leftElement = ref left[i]; if (leftElement < digit) ++carry; @@ -249,8 +249,8 @@ private static bool DivideGuessTooBig(ulong q, ulong valHi, uint valLo, ulong chkHi = divHi * q; ulong chkLo = divLo * q; - chkHi = chkHi + (chkLo >> 32); - chkLo = chkLo & 0xFFFFFFFF; + chkHi += (chkLo >> 32); + chkLo &= 0xFFFFFFFF; if (chkHi < valHi) return false; diff --git a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.PowMod.cs b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.PowMod.cs index 0407feff54fe38..c292558176a169 100644 --- a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.PowMod.cs +++ b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigIntegerCalculator.PowMod.cs @@ -59,7 +59,7 @@ private static Span PowCore(Span value, int valueLength, Span bitsLength = MultiplySelf(ref result, bitsLength, value.Slice(0, valueLength), ref temp); if (power != 1) valueLength = SquareSelf(ref value, valueLength, ref temp); - power = power >> 1; + power >>= 1; } return result; @@ -120,7 +120,7 @@ public static int PowBound(uint power, int valueLength) if (power != 1) valueLength += valueLength; } - power = power >> 1; + power >>= 1; } return resultLength; @@ -173,7 +173,7 @@ private static uint PowCore(ulong value, ReadOnlySpan power, uint modulus, if ((p & 1) == 1) result = (result * value) % modulus; value = (value * value) % modulus; - p = p >> 1; + p >>= 1; } } @@ -191,7 +191,7 @@ private static uint PowCore(ulong value, uint power, uint modulus, ulong result) result = (result * value) % modulus; if (power != 1) value = (value * value) % modulus; - power = power >> 1; + power >>= 1; } return (uint)(result % modulus); @@ -431,7 +431,7 @@ private static Span PowCore(Span value, int valueLength, } valueLength = SquareSelf(ref value, valueLength, ref temp); valueLength = Reduce(value.Slice(0, valueLength), modulus); - p = p >> 1; + p >>= 1; } } @@ -461,7 +461,7 @@ private static Span PowCore(Span value, int valueLength, valueLength = SquareSelf(ref value, valueLength, ref temp); valueLength = Reduce(value.Slice(0, valueLength), modulus); } - power = power >> 1; + power >>= 1; } return result.Slice(0, resultLength); @@ -490,7 +490,7 @@ private static Span PowCore(Span value, int valueLength, } valueLength = SquareSelf(ref value, valueLength, ref temp); valueLength = reducer.Reduce(value.Slice(0, valueLength)); - p = p >> 1; + p >>= 1; } } @@ -520,7 +520,7 @@ private static Span PowCore(Span value, int valueLength, valueLength = SquareSelf(ref value, valueLength, ref temp); valueLength = reducer.Reduce(value.Slice(0, valueLength)); } - power = power >> 1; + power >>= 1; } return result; diff --git a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryObjectReader.cs b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryObjectReader.cs index 94efc7f679fc70..ba514525295f11 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryObjectReader.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryObjectReader.cs @@ -483,7 +483,7 @@ private void ParseArray(ParseRecord pr) int sum = 1; for (int i = 0; i < pr._rank; i++) { - sum = sum * pr._lengthA[i]; + sum *= pr._lengthA[i]; } pr._indexMap = new int[pr._rank]; pr._rectangularMap = new int[pr._rank]; diff --git a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryParser.cs b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryParser.cs index 058c5ac1412662..81d475f8387ba7 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryParser.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/Formatters/Binary/BinaryParser.cs @@ -835,7 +835,7 @@ private void ReadArray(BinaryHeaderEnum binaryHeaderEnum) case BinaryArrayTypeEnum.RectangularOffset: int arrayLength = 1; for (int i = 0; i < record._rank; i++) - arrayLength = arrayLength * record._lengthA[i]; + arrayLength *= record._lengthA[i]; op._numItems = arrayLength; pr._arrayTypeEnum = InternalArrayTypeE.Rectangular; break; diff --git a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/EnvelopedCms.cs b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/EnvelopedCms.cs index 0fab983af14d2f..b52bfb473e562b 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/EnvelopedCms.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/src/System/Security/Cryptography/Pkcs/EnvelopedCms.cs @@ -246,7 +246,7 @@ public void Decrypt(RecipientInfo recipientInfo, AsymmetricAlgorithm? privateKey private void DecryptContent(RecipientInfoCollection recipientInfos, X509Certificate2Collection? extraStore) { CheckStateForDecryption(); - extraStore = extraStore ?? new X509Certificate2Collection(); + extraStore ??= new X509Certificate2Collection(); X509Certificate2Collection certs = new X509Certificate2Collection(); PkcsPal.Instance.AddCertsFromStoreForDecryption(certs); diff --git a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedXml.cs b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedXml.cs index 41614db010a839..89b05ff113cfcc 100644 --- a/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedXml.cs +++ b/src/libraries/System.Security.Cryptography.Xml/src/System/Security/Cryptography/Xml/SignedXml.cs @@ -976,7 +976,7 @@ private static bool CryptographicEquals(byte[] a, byte[] b) // This cannot overflow more than once (and back to 0) because bytes are 1 byte // in length, and result is 4 bytes. The OR propagates all set bytes, so the differences // can't add up and overflow a second time. - result = result | (a[i] - b[i]); + result |= (a[i] - b[i]); } return (0 == result); diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.Windows.GetChainStatusInformation.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.Windows.GetChainStatusInformation.cs index e22f6c8adb49a2..a74354c0189eaa 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.Windows.GetChainStatusInformation.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/ChainPal.Windows.GetChainStatusInformation.cs @@ -13,7 +13,7 @@ private static X509ChainStatus[] GetChainStatusInformation(CertTrustErrorStatus return Array.Empty(); int count = 0; - for (uint bits = (uint)dwStatus; bits != 0; bits = bits >> 1) + for (uint bits = (uint)dwStatus; bits != 0; bits >>= 1) { if ((bits & 0x1) != 0) count++; @@ -36,7 +36,7 @@ private static X509ChainStatus[] GetChainStatusInformation(CertTrustErrorStatus } int shiftCount = 0; - for (uint bits = (uint)dwStatus; bits != 0; bits = bits >> 1) + for (uint bits = (uint)dwStatus; bits != 0; bits >>= 1) { if ((bits & 0x1) != 0) { diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.iOS.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.iOS.cs index 3e8c5acfd25ae7..02c3af95fa66f3 100644 --- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.iOS.cs +++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.iOS.cs @@ -23,7 +23,7 @@ internal static partial ILoaderPal FromBlob(ReadOnlySpan rawData, SafePass rawData, (derData, contentType) => { - certificateList = certificateList ?? new List(); + certificateList ??= new List(); certificateList.Add(AppleCertificatePal.FromDerBlob(derData, contentType, password, keyStorageFlags)); return true; }); diff --git a/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/Atom10FeedFormatter.cs b/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/Atom10FeedFormatter.cs index fd6620844bb462..2050b173aefa64 100644 --- a/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/Atom10FeedFormatter.cs +++ b/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/Atom10FeedFormatter.cs @@ -762,7 +762,7 @@ private SyndicationFeed ReadFeedFrom(XmlReader reader, SyndicationFeed result, b } else if (reader.IsStartElement(Atom10Constants.EntryTag, Atom10Constants.Atom10Namespace) && !isSourceFeed) { - feedItems = feedItems ?? new NullNotAllowedCollection(); + feedItems ??= new NullNotAllowedCollection(); IEnumerable items = ReadItems(reader, result, out areAllItemsRead); foreach (SyndicationItem item in items) { @@ -1129,14 +1129,14 @@ private void WriteFeedTo(XmlWriter writer, SyndicationFeed feed, bool isSourceFe TextSyndicationContent title = feed.Title; if (isElementRequired) { - title = title ?? new TextSyndicationContent(string.Empty); + title ??= new TextSyndicationContent(string.Empty); } WriteContentTo(writer, Atom10Constants.TitleTag, title); WriteContentTo(writer, Atom10Constants.SubtitleTag, feed.Description); string id = feed.Id; if (isElementRequired) { - id = id ?? s_idGenerator.Next(); + id ??= s_idGenerator.Next(); } WriteElement(writer, Atom10Constants.IdTag, id); WriteContentTo(writer, Atom10Constants.RightsTag, feed.Copyright); diff --git a/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/Rss20FeedFormatter.cs b/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/Rss20FeedFormatter.cs index 9fe755dfbc3011..980318ecc9776a 100644 --- a/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/Rss20FeedFormatter.cs +++ b/src/libraries/System.ServiceModel.Syndication/src/System/ServiceModel/Syndication/Rss20FeedFormatter.cs @@ -736,7 +736,7 @@ private void ReadXml(XmlReader reader, SyndicationFeed result) } else if (reader.IsStartElement(Rss20Constants.ItemTag, Rss20Constants.Rss20Namespace)) { - feedItems = feedItems ?? new NullNotAllowedCollection(); + feedItems ??= new NullNotAllowedCollection(); IEnumerable items = ReadItems(reader, result, out areAllItemsRead); foreach (SyndicationItem item in items) { diff --git a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs index 905af30eaa1f5c..fbbd18ecf895cf 100644 --- a/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs +++ b/src/libraries/System.ServiceProcess.ServiceController/src/System/ServiceProcess/ServiceBase.cs @@ -909,7 +909,7 @@ public unsafe void ServiceMainCallback(int argCount, IntPtr argPointer) _commandPropsFrozen = true; if ((_status.controlsAccepted & AcceptOptions.ACCEPT_STOP) != 0) { - _status.controlsAccepted = _status.controlsAccepted | AcceptOptions.ACCEPT_SHUTDOWN; + _status.controlsAccepted |= AcceptOptions.ACCEPT_SHUTDOWN; } _status.currentState = ServiceControlStatus.STATE_START_PENDING; diff --git a/src/libraries/System.Speech/src/Internal/Synthesis/AudioFormatConverter.cs b/src/libraries/System.Speech/src/Internal/Synthesis/AudioFormatConverter.cs index 39c4db1d31e57d..556ccb9eda1d03 100644 --- a/src/libraries/System.Speech/src/Internal/Synthesis/AudioFormatConverter.cs +++ b/src/libraries/System.Speech/src/Internal/Synthesis/AudioFormatConverter.cs @@ -221,7 +221,7 @@ private static byte[] CalcLinear2ULawTable() if (sample > uCLIP) sample = uCLIP; // clip the magnitude // Convert from 16 bit linear to ULaw. - sample = sample + uBIAS; + sample += uBIAS; exponent = s_exp_lut_linear2ulaw[(sample >> 7) & 0xFF]; mantissa = (sample >> (exponent + 3)) & 0x0F; diff --git a/src/libraries/System.Speech/src/Internal/Synthesis/SSmlParser.cs b/src/libraries/System.Speech/src/Internal/Synthesis/SSmlParser.cs index 11d62a89d2b1b5..de41d0223ea566 100644 --- a/src/libraries/System.Speech/src/Internal/Synthesis/SSmlParser.cs +++ b/src/libraries/System.Speech/src/Internal/Synthesis/SSmlParser.cs @@ -1701,7 +1701,7 @@ private static bool TryParseNumber(string sNumber, ref ProsodyNumber number) float percent = (float)value / 100f; if (sNumber[0] != '+' && sNumber[0] != '-') { - number.Number = number.Number * percent; + number.Number *= percent; } else { diff --git a/src/libraries/System.Speech/src/Recognition/SrgsGrammar/SrgsElementFactory.cs b/src/libraries/System.Speech/src/Recognition/SrgsGrammar/SrgsElementFactory.cs index 06af30b0818674..a731a35b8cb7ba 100644 --- a/src/libraries/System.Speech/src/Recognition/SrgsGrammar/SrgsElementFactory.cs +++ b/src/libraries/System.Speech/src/Recognition/SrgsGrammar/SrgsElementFactory.cs @@ -151,7 +151,7 @@ void IElementFactory.AddScript(IGrammar grammar, string sRule, string code) SrgsRule rule = srgsGrammar.Rules[sRule]; if (rule != null) { - rule.Script = rule.Script + code; + rule.Script += code; } else { diff --git a/src/libraries/System.Speech/src/Recognition/SrgsGrammar/SrgsGrammar.cs b/src/libraries/System.Speech/src/Recognition/SrgsGrammar/SrgsGrammar.cs index 7837767ebc84f9..0183a01dfe3c4c 100644 --- a/src/libraries/System.Speech/src/Recognition/SrgsGrammar/SrgsGrammar.cs +++ b/src/libraries/System.Speech/src/Recognition/SrgsGrammar/SrgsGrammar.cs @@ -232,7 +232,7 @@ void IElement.PostParse(IElement parent) SrgsRule rule = Rules[script._name]; if (rule != null) { - rule.Script = rule.Script + script._value; + rule.Script += script._value; } else { diff --git a/src/libraries/System.Text.Encoding.CodePages/src/System/Text/EUCJPEncoding.cs b/src/libraries/System.Text.Encoding.CodePages/src/System/Text/EUCJPEncoding.cs index 7c4b7485d0c083..0135bfdb6d7da3 100644 --- a/src/libraries/System.Text.Encoding.CodePages/src/System/Text/EUCJPEncoding.cs +++ b/src/libraries/System.Text.Encoding.CodePages/src/System/Text/EUCJPEncoding.cs @@ -63,11 +63,11 @@ protected override bool CleanUpBytes(ref int bytes) if (bytes >= 0xfa40 && bytes <= 0xfa5b) { if (bytes <= 0xfa49) - bytes = bytes - 0x0b51; + bytes -= 0x0b51; else if (bytes >= 0xfa4a && bytes <= 0xfa53) - bytes = bytes - 0x072f6; + bytes -= 0x072f6; else if (bytes >= 0xfa54 && bytes <= 0xfa57) - bytes = bytes - 0x0b5b; + bytes -= 0x0b5b; else if (bytes == 0xfa58) bytes = 0x878a; else if (bytes == 0xfa59) @@ -81,11 +81,11 @@ protected override bool CleanUpBytes(ref int bytes) { byte tc = unchecked((byte)bytes); if (tc < 0x5c) - bytes = bytes - 0x0d5f; + bytes -= 0x0d5f; else if (tc >= 0x80 && tc <= 0x9B) - bytes = bytes - 0x0d1d; + bytes -= 0x0d1d; else - bytes = bytes - 0x0d1c; + bytes -= 0x0d1c; } } diff --git a/src/libraries/System.Text.Encoding.CodePages/src/System/Text/ISO2022Encoding.cs b/src/libraries/System.Text.Encoding.CodePages/src/System/Text/ISO2022Encoding.cs index 602212497b4330..65537fd283b2a9 100644 --- a/src/libraries/System.Text.Encoding.CodePages/src/System/Text/ISO2022Encoding.cs +++ b/src/libraries/System.Text.Encoding.CodePages/src/System/Text/ISO2022Encoding.cs @@ -114,11 +114,11 @@ protected override bool CleanUpBytes(ref int bytes) if (bytes >= 0xfa40 && bytes <= 0xfa5b) { if (bytes <= 0xfa49) - bytes = bytes - 0x0b51; + bytes -= 0x0b51; else if (bytes >= 0xfa4a && bytes <= 0xfa53) - bytes = bytes - 0x072f6; + bytes -= 0x072f6; else if (bytes >= 0xfa54 && bytes <= 0xfa57) - bytes = bytes - 0x0b5b; + bytes -= 0x0b5b; else if (bytes == 0xfa58) bytes = 0x878a; else if (bytes == 0xfa59) @@ -132,11 +132,11 @@ protected override bool CleanUpBytes(ref int bytes) { byte tc = unchecked((byte)bytes); if (tc < 0x5c) - bytes = bytes - 0x0d5f; + bytes -= 0x0d5f; else if (tc >= 0x80 && tc <= 0x9B) - bytes = bytes - 0x0d1d; + bytes -= 0x0d1d; else - bytes = bytes - 0x0d1c; + bytes -= 0x0d1c; } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/BitStack.cs b/src/libraries/System.Text.Json/src/System/Text/Json/BitStack.cs index 9ba42d26206199..12255d985358c6 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/BitStack.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/BitStack.cs @@ -47,7 +47,7 @@ public void PushFalse() { if (_currentDepth < AllocationFreeMaxDepth) { - _allocationFreeContainer = _allocationFreeContainer << 1; + _allocationFreeContainer <<= 1; } else { diff --git a/src/libraries/System.Threading/src/System/Threading/Barrier.cs b/src/libraries/System.Threading/src/System/Threading/Barrier.cs index 61114b240d0c84..8baebc3eb5815f 100644 --- a/src/libraries/System.Threading/src/System/Threading/Barrier.cs +++ b/src/libraries/System.Threading/src/System/Threading/Barrier.cs @@ -814,7 +814,7 @@ private static void InvokePostPhaseAction(object? obj) private void SetResetEvents(bool observedSense) { // Increment the phase count using Volatile class because m_currentPhase is 64 bit long type, that could cause torn write on 32 bit machines - CurrentPhaseNumber = CurrentPhaseNumber + 1; + CurrentPhaseNumber++; if (observedSense) { _oddEvent.Reset(); diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/FieldBuilder.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/FieldBuilder.Mono.cs index 0ceb6a433e8b47..33f29efbfa32e5 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/FieldBuilder.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/FieldBuilder.Mono.cs @@ -148,7 +148,7 @@ internal override int GetFieldOffset() internal void SetRVAData(byte[] data) { - attrs = attrs | FieldAttributes.HasFieldRVA; + attrs |= FieldAttributes.HasFieldRVA; rva_data = (byte[])data.Clone(); } diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/MonoArrayMethod.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/MonoArrayMethod.cs index 8421804e0b6b06..93f961ed2774bf 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/MonoArrayMethod.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/Emit/MonoArrayMethod.cs @@ -167,8 +167,8 @@ public override string ToString() for (int i = 0; i < p.Length; ++i) { if (i > 0) - parms = parms + ", "; - parms = parms + p[i].ParameterType.Name; + parms += ", "; + parms += p[i].ParameterType.Name; } if (ReturnType != null) return ReturnType.Name + " " + Name + "(" + parms + ")"; diff --git a/src/mono/System.Private.CoreLib/src/System/String.Mono.cs b/src/mono/System.Private.CoreLib/src/System/String.Mono.cs index 780fd4fe66e248..c700d31af50596 100644 --- a/src/mono/System.Private.CoreLib/src/System/String.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/String.Mono.cs @@ -47,8 +47,8 @@ private static unsafe void memset(byte* dest, int val, int len) } if (val != 0) { - val = val | (val << 8); - val = val | (val << 16); + val |= (val << 8); + val |= (val << 16); } // align to 4 int rest = (int)dest & 3; diff --git a/src/mono/wasm/host/Options.cs b/src/mono/wasm/host/Options.cs index 3fa1de9912575b..d2f64bf287f9ff 100644 --- a/src/mono/wasm/host/Options.cs +++ b/src/mono/wasm/host/Options.cs @@ -1796,7 +1796,7 @@ private void AddCommand(Command value) base.Add(value); - help = help ?? value as HelpCommand; + help ??= value as HelpCommand; } public CommandSet Add(string header) @@ -1955,7 +1955,7 @@ public IEnumerable GetCompletions(string prefix = null) private static void ExtractToken(ref string input, out string rest) { rest = ""; - input = input ?? ""; + input ??= ""; int top = input.Length; for (int i = 0; i < top; i++) From 10438a57b888cbdc6dc15771dc662adde9fd6b14 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Fri, 17 Jun 2022 05:26:20 -0400 Subject: [PATCH 185/337] Use new byte[] span optimization in a few more places (#70665) * Use new byte[] span optimization in a few more places Separated out of larger change to use CreateSpan (these don't rely on that). * Address PR feedback --- .../src/System/Data/SQLTypes/SQLDecimal.cs | 9 ++-- .../src/System/Data/SQLTypes/SQLGuid.cs | 20 +++++---- .../AccountManagement/interopt.cs | 2 - .../src/System/Xml/XmlUTF8TextReader.cs | 44 +++++++++---------- .../src/System/Xml/BinaryXml/SqlUtils.cs | 9 ++-- .../src/System/Xml/Xsl/XPath/XPathParser.cs | 43 +++++++++--------- .../PortableExecutable/PEBuilder.cs | 17 ++++--- .../Cryptography/Cose/CoseHeaderMap.cs | 6 +-- 8 files changed, 75 insertions(+), 75 deletions(-) diff --git a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLDecimal.cs b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLDecimal.cs index 83ad2822fd1c29..d1b9ab1010ef58 100644 --- a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLDecimal.cs +++ b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLDecimal.cs @@ -1878,12 +1878,9 @@ private void ZeroToMaxLen(int cUI4sCur) { //Precision Length // 0 invalid // 1-9 1 - // 10-19 2 - // 20-28 3 - // 29-38 4 - // The array in Shiloh. Listed here for comparison. - //private static readonly byte[] rgCLenFromPrec = new byte[] {5,5,5,5,5,5,5,5,5,9,9,9,9,9, - // 9,9,9,9,9,13,13,13,13,13,13,13,13,13,17,17,17,17,17,17,17,17,17,17}; + // 10-19 2 + // 20-28 3 + // 29-38 4 private static ReadOnlySpan RgCLenFromPrec => new byte[] // rely on C# compiler optimization to eliminate allocation { 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, diff --git a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLGuid.cs b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLGuid.cs index 2742c25d53b53a..316706e0cc7df3 100644 --- a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLGuid.cs +++ b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLGuid.cs @@ -20,10 +20,6 @@ public struct SqlGuid : INullable, IComparable, IXmlSerializable, IEquatable rgiGuidOrder = new byte[16] { 10, 11, 12, 13, 14, 15, 8, 9, 6, 7, 4, 5, 0, 1, 2, 3 }; + + // Swap to the correct order to be compared + ReadOnlySpan xBytes = x.m_value; + ReadOnlySpan yBytes = y.m_value; for (int i = 0; i < SizeOfGuid; i++) { - byte b1, b2; - - b1 = x.m_value![s_rgiGuidOrder[i]]; - b2 = y.m_value![s_rgiGuidOrder[i]]; + byte b1 = xBytes[rgiGuidOrder[i]]; + byte b2 = yBytes[rgiGuidOrder[i]]; if (b1 != b2) + { return (b1 < b2) ? EComparison.LT : EComparison.GT; + } } + return EComparison.EQ; } diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/interopt.cs b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/interopt.cs index 64fcab520bf431..6d0a1866f3c785 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/interopt.cs +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/interopt.cs @@ -14,8 +14,6 @@ namespace System.DirectoryServices.AccountManagement internal static class Constants { - internal static byte[] GUID_USERS_CONTAINER_BYTE = new byte[] { 0xa9, 0xd1, 0xca, 0x15, 0x76, 0x88, 0x11, 0xd1, 0xad, 0xed, 0x00, 0xc0, 0x4f, 0xd8, 0xd5, 0xcd }; - internal static byte[] GUID_COMPUTRS_CONTAINER_BYTE = new byte[] { 0xaa, 0x31, 0x28, 0x25, 0x76, 0x88, 0x11, 0xd1, 0xad, 0xed, 0x00, 0xc0, 0x4f, 0xd8, 0xd5, 0xcd }; internal static byte[] GUID_FOREIGNSECURITYPRINCIPALS_CONTAINER_BYTE = new byte[] { 0x22, 0xb7, 0x0c, 0x67, 0xd5, 0x6e, 0x4e, 0xfb, 0x91, 0xe9, 0x30, 0x0f, 0xca, 0x3d, 0xc1, 0xaa }; } diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlUTF8TextReader.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlUTF8TextReader.cs index 578117e87fb6ed..0ee99f4f8eef0d 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlUTF8TextReader.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Xml/XmlUTF8TextReader.cs @@ -31,7 +31,7 @@ internal sealed class XmlUTF8TextReader : XmlBaseReader, IXmlLineInfo, IXmlTextR private OnXmlDictionaryReaderClose? _onClose; private bool _buffered; private int _maxBytesPerRead; - private static readonly byte[] s_charType = new byte[256] + private static ReadOnlySpan CharTypeMap => new byte[256] { /* 0 (.) */ CharType.None, @@ -609,7 +609,7 @@ public override void Close() private void SkipWhitespace() { - while (!BufferReader.EndOfFile && (s_charType[BufferReader.GetByte()] & CharType.Whitespace) != 0) + while (!BufferReader.EndOfFile && (CharTypeMap[BufferReader.GetByte()] & CharType.Whitespace) != 0) BufferReader.SkipByte(); } @@ -623,7 +623,7 @@ private void ReadDeclaration() buffer[offset + 1] != (byte)'x' || buffer[offset + 2] != (byte)'m' || buffer[offset + 3] != (byte)'l' || - (s_charType[buffer[offset + 4]] & CharType.Whitespace) == 0) + (CharTypeMap[buffer[offset + 4]] & CharType.Whitespace) == 0) { XmlExceptionHelper.ThrowProcessingInstructionNotSupported(this); } @@ -646,7 +646,7 @@ private void ReadDeclaration() while (valueLength > 0) { byte ch = BufferReader.GetByte(valueOffset + valueLength - 1); - if ((s_charType[ch] & CharType.Whitespace) == 0) + if ((CharTypeMap[ch] & CharType.Whitespace) == 0) break; valueLength--; } @@ -689,14 +689,14 @@ private void ReadQualifiedName(PrefixHandle prefix, StringHandle localName) { ch = buffer[offset]; prefixChar = ch; - if ((s_charType[ch] & CharType.FirstName) == 0) + if ((CharTypeMap[ch] & CharType.FirstName) == 0) anyChar |= 0x80; anyChar |= ch; offset++; while (offset < offsetMax) { ch = buffer[offset]; - if ((s_charType[ch] & CharType.Name) == 0) + if ((CharTypeMap[ch] & CharType.Name) == 0) break; anyChar |= ch; offset++; @@ -720,14 +720,14 @@ private void ReadQualifiedName(PrefixHandle prefix, StringHandle localName) if (offset < offsetMax) { ch = buffer[offset]; - if ((s_charType[ch] & CharType.FirstName) == 0) + if ((CharTypeMap[ch] & CharType.FirstName) == 0) anyChar |= 0x80; anyChar |= ch; offset++; while (offset < offsetMax) { ch = buffer[offset]; - if ((s_charType[ch] & CharType.Name) == 0) + if ((CharTypeMap[ch] & CharType.Name) == 0) break; anyChar |= ch; offset++; @@ -758,9 +758,9 @@ private void ReadQualifiedName(PrefixHandle prefix, StringHandle localName) private static int ReadAttributeText(byte[] buffer, int offset, int offsetMax) { - byte[] charType = XmlUTF8TextReader.s_charType; + ReadOnlySpan charTypeMap = XmlUTF8TextReader.CharTypeMap; int textOffset = offset; - while (offset < offsetMax && (charType[buffer[offset]] & CharType.AttributeText) != 0) + while (offset < offsetMax && (charTypeMap[buffer[offset]] & CharType.AttributeText) != 0) offset++; return offset - textOffset; } @@ -864,7 +864,7 @@ private void ReadAttributes() ch = BufferReader.GetByte(); bool space = false; - while ((s_charType[ch] & CharType.Whitespace) != 0) + while ((CharTypeMap[ch] & CharType.Whitespace) != 0) { space = true; BufferReader.SkipByte(); @@ -958,7 +958,7 @@ private void BufferElement() ReadQualifiedName(elementNode.Prefix, elementNode.LocalName); elementNode.NameLength = BufferReader.Offset - elementNode.NameOffset; byte ch = BufferReader.GetByte(); - while ((s_charType[ch] & CharType.Whitespace) != 0) + while ((CharTypeMap[ch] & CharType.Whitespace) != 0) { BufferReader.SkipByte(); ch = BufferReader.GetByte(); @@ -1024,7 +1024,7 @@ private void ReadComment() byte b = BufferReader.GetByte(); if (b == '-') break; - if ((s_charType[b] & CharType.Comment) == 0) + if ((CharTypeMap[b] & CharType.Comment) == 0) { if (b == 0xEF) ReadNonFFFE(); @@ -1136,18 +1136,18 @@ private void ReadWhitespace() private static int ReadWhitespace(byte[] buffer, int offset, int offsetMax) { - byte[] charType = XmlUTF8TextReader.s_charType; + ReadOnlySpan charTypeMap = XmlUTF8TextReader.CharTypeMap; int wsOffset = offset; - while (offset < offsetMax && (charType[buffer[offset]] & CharType.SpecialWhitespace) != 0) + while (offset < offsetMax && (charTypeMap[buffer[offset]] & CharType.SpecialWhitespace) != 0) offset++; return offset - wsOffset; } private static int ReadText(byte[] buffer, int offset, int offsetMax) { - byte[] charType = XmlUTF8TextReader.s_charType; + ReadOnlySpan charTypeMap = XmlUTF8TextReader.CharTypeMap; int textOffset = offset; - while (offset < offsetMax && (charType[buffer[offset]] & CharType.Text) != 0) + while (offset < offsetMax && (charTypeMap[buffer[offset]] & CharType.Text) != 0) offset++; return offset - textOffset; } @@ -1155,10 +1155,10 @@ private static int ReadText(byte[] buffer, int offset, int offsetMax) // Read Unicode codepoints 0xFvvv private int ReadTextAndWatchForInvalidCharacters(byte[] buffer, int offset, int offsetMax) { - byte[] charType = XmlUTF8TextReader.s_charType; + ReadOnlySpan charTypeMap = XmlUTF8TextReader.CharTypeMap; int textOffset = offset; - while (offset < offsetMax && ((charType[buffer[offset]] & CharType.Text) != 0 || buffer[offset] == 0xEF)) + while (offset < offsetMax && ((charTypeMap[buffer[offset]] & CharType.Text) != 0 || buffer[offset] == 0xEF)) { if (buffer[offset] != 0xEF) { @@ -1286,7 +1286,7 @@ private void ReadText(bool hasLeadingByteOf0xEF) private void ReadEscapedText() { int ch = ReadCharRef(); - if (ch < 256 && (s_charType[ch] & CharType.Whitespace) != 0) + if (ch < 256 && (CharTypeMap[ch] & CharType.Whitespace) != 0) MoveToWhitespaceText().Value.SetCharValue(ch); else MoveToComplexText().Value.SetCharValue(ch); @@ -1345,7 +1345,7 @@ public override bool Read() else ReadStartElement(); } - else if ((s_charType[ch] & CharType.SpecialWhitespace) != 0) + else if ((CharTypeMap[ch] & CharType.SpecialWhitespace) != 0) { ReadWhitespace(); } @@ -1353,7 +1353,7 @@ public override bool Read() { XmlExceptionHelper.ThrowInvalidRootData(this); } - else if ((s_charType[ch] & CharType.Text) != 0) + else if ((CharTypeMap[ch] & CharType.Text) != 0) { ReadText(false); } diff --git a/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/SqlUtils.cs b/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/SqlUtils.cs index d22aefc772f722..d73d3f08743680 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/SqlUtils.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/BinaryXml/SqlUtils.cs @@ -117,12 +117,9 @@ ref int ciulU // InOut| # of digits //Precision Length // 0 invalid // 1-9 1 - // 10-19 2 - // 20-28 3 - // 29-38 4 - // The array in Shiloh. Listed here for comparison. - //private static readonly byte[] rgCLenFromPrec = new byte[] {5,5,5,5,5,5,5,5,5,9,9,9,9,9, - // 9,9,9,9,9,13,13,13,13,13,13,13,13,13,17,17,17,17,17,17,17,17,17,17}; + // 10-19 2 + // 20-28 3 + // 29-38 4 private static ReadOnlySpan RgCLenFromPrec => new byte[] { // rely on C# compiler optimization to eliminate allocation 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 }; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathParser.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathParser.cs index f2226a57863dde..49ed3bfde39c8e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathParser.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/XPath/XPathParser.cs @@ -356,11 +356,31 @@ private Node ParseSubExpr(int callerPrec) XPathOperator op; Node opnd; + ReadOnlySpan xpathOperatorPrecedence = new byte[] + { + /*Unknown */ 0, + /*Or */ 1, + /*And */ 2, + /*Eq */ 3, + /*Ne */ 3, + /*Lt */ 4, + /*Le */ 4, + /*Gt */ 4, + /*Ge */ 4, + /*Plus */ 5, + /*Minus */ 5, + /*Multiply */ 6, + /*Divide */ 6, + /*Modulo */ 6, + /*UnaryMinus */ 7, + /*Union */ 8, // Not used + }; + // Check for unary operators if (_scanner!.Kind == LexKind.Minus) { op = XPathOperator.UnaryMinus; - int opPrec = s_XPathOperatorPrecedence[(int)op]; + byte opPrec = xpathOperatorPrecedence[(int)op]; _scanner.NextLex(); opnd = _builder!.Operator(op, ParseSubExpr(opPrec), default(Node)); } @@ -373,7 +393,7 @@ private Node ParseSubExpr(int callerPrec) while (true) { op = (_scanner.Kind <= LexKind.LastOperator) ? (XPathOperator)_scanner.Kind : XPathOperator.Unknown; - int opPrec = s_XPathOperatorPrecedence[(int)op]; + byte opPrec = xpathOperatorPrecedence[(int)op]; if (opPrec <= callerPrec) { break; @@ -387,25 +407,6 @@ private Node ParseSubExpr(int callerPrec) return opnd; } - private static readonly int[] s_XPathOperatorPrecedence = { - /*Unknown */ 0, - /*Or */ 1, - /*And */ 2, - /*Eq */ 3, - /*Ne */ 3, - /*Lt */ 4, - /*Le */ 4, - /*Gt */ 4, - /*Ge */ 4, - /*Plus */ 5, - /*Minus */ 5, - /*Multiply */ 6, - /*Divide */ 6, - /*Modulo */ 6, - /*UnaryMinus */ 7, - /*Union */ 8, // Not used - }; - /* * UnionExpr ::= PathExpr ('|' PathExpr)* */ diff --git a/src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEBuilder.cs b/src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEBuilder.cs index 51a90c19f4286a..8a30e71d7e74c1 100644 --- a/src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEBuilder.cs +++ b/src/libraries/System.Reflection.Metadata/src/System/Reflection/PortableExecutable/PEBuilder.cs @@ -150,16 +150,23 @@ private ImmutableArray SerializeSections() return result.MoveToImmutable(); } - private static void WritePESignature(BlobBuilder builder) + private static unsafe void WritePESignature(BlobBuilder builder) { // MS-DOS stub (128 bytes) - builder.WriteBytes(s_dosHeader); + ReadOnlySpan header = DosHeader; + Debug.Assert(DosHeader.Length == DosHeaderSize); + fixed (byte* ptr = header) + { + builder.WriteBytes(ptr, header.Length); + } // PE Signature "PE\0\0" builder.WriteUInt32(PEHeaders.PESignature); } - private static readonly byte[] s_dosHeader = new byte[] + internal const int DosHeaderSize = 0x80; + + private static ReadOnlySpan DosHeader => new byte[DosHeaderSize] { 0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, @@ -170,7 +177,7 @@ private static void WritePESignature(BlobBuilder builder) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, // NT Header offset (0x80 == s_dosHeader.Length) + 0x80, 0x00, 0x00, 0x00, // NT Header offset (0x80 == DosHeader.Length) 0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd, 0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68, @@ -182,8 +189,6 @@ private static void WritePESignature(BlobBuilder builder) 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - internal static int DosHeaderSize = s_dosHeader.Length; - private void WriteCoffHeader(BlobBuilder builder, ImmutableArray sections, out Blob stampFixup) { // Machine diff --git a/src/libraries/System.Security.Cryptography.Cose/src/System/Security/Cryptography/Cose/CoseHeaderMap.cs b/src/libraries/System.Security.Cryptography.Cose/src/System/Security/Cryptography/Cose/CoseHeaderMap.cs index a3eb9c1e45c8d9..a88953864480de 100644 --- a/src/libraries/System.Security.Cryptography.Cose/src/System/Security/Cryptography/Cose/CoseHeaderMap.cs +++ b/src/libraries/System.Security.Cryptography.Cose/src/System/Security/Cryptography/Cose/CoseHeaderMap.cs @@ -11,7 +11,6 @@ namespace System.Security.Cryptography.Cose { public sealed class CoseHeaderMap : IEnumerable<(CoseHeaderLabel Label, ReadOnlyMemory EncodedValue)> { - private static readonly byte[] s_emptyBstrEncoded = new byte[] { 0x40 }; private static readonly CoseHeaderMap s_emptyMap = new CoseHeaderMap(isReadOnly: true); public bool IsReadOnly { get; internal set; } @@ -199,8 +198,9 @@ internal static int Encode(CoseHeaderMap? map, Span destination, bool must if (map._headerParameters.Count == 0 && mustReturnEmptyBstrIfEmpty && !shouldSlipAlgHeader) { - s_emptyBstrEncoded.CopyTo(destination); - return s_emptyBstrEncoded.Length; + // Empty Bstr encoded + destination[0] = 0x40; + return 1; } int mapLength = map._headerParameters.Count; From 8a6672aee95444bb781f496cbaf8f1962b9eb81e Mon Sep 17 00:00:00 2001 From: Radek Zikmund <32671551+rzikm@users.noreply.github.com> Date: Fri, 17 Jun 2022 11:56:33 +0200 Subject: [PATCH 186/337] Improve TLS1.3 detection in registry for QUIC (#70730) * Improve TLS1.3 detection in registry for QUIC * Split client and server detection * Code review feedback --- .../MsQuic/Internal/MsQuicApi.cs | 37 +++++++++++-------- .../Interop/SafeMsQuicConfigurationHandle.cs | 7 ++-- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Internal/MsQuicApi.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Internal/MsQuicApi.cs index 0cb01e754b0e13..2078043ddd564d 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Internal/MsQuicApi.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Internal/MsQuicApi.cs @@ -38,7 +38,8 @@ private MsQuicApi(QUIC_API_TABLE* apiTable) fixed (byte* pAppName = "System.Net.Quic"u8) { - var cfg = new QUIC_REGISTRATION_CONFIG { + var cfg = new QUIC_REGISTRATION_CONFIG + { AppName = (sbyte*)pAppName, ExecutionProfile = QUIC_EXECUTION_PROFILE.LOW_LATENCY }; @@ -54,7 +55,8 @@ private MsQuicApi(QUIC_API_TABLE* apiTable) internal static bool IsQuicSupported { get; } - internal static bool Tls13MayBeDisabled { get; } + internal static bool Tls13ServerMayBeDisabled { get; } + internal static bool Tls13ClientMayBeDisabled { get; } static MsQuicApi() { @@ -70,7 +72,8 @@ static MsQuicApi() return; } - Tls13MayBeDisabled = IsTls13Disabled(); + Tls13ServerMayBeDisabled = IsTls13Disabled(true); + Tls13ClientMayBeDisabled = IsTls13Disabled(false); } IntPtr msQuicHandle; @@ -120,24 +123,28 @@ static MsQuicApi() private static bool IsWindowsVersionSupported() => OperatingSystem.IsWindowsVersionAtLeast(MinWindowsVersion.Major, MinWindowsVersion.Minor, MinWindowsVersion.Build, MinWindowsVersion.Revision); - private static bool IsTls13Disabled() + private static bool IsTls13Disabled(bool isServer) { #if TARGET_WINDOWS - string[] SChannelTLS13RegKeys = { - @"SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Client", - @"SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Server" - }; + string SChannelTls13RegistryKey = isServer + ? @"SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Server" + : @"SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.3\Client"; + + using var regKey = Registry.LocalMachine.OpenSubKey(SChannelTls13RegistryKey); - foreach (var key in SChannelTLS13RegKeys) + if (regKey is null) { - using var regKey = Registry.LocalMachine.OpenSubKey(key); + return false; + } - if (regKey is null) return false; + if (regKey.GetValue("Enabled") is int enabled && enabled == 0) + { + return true; + } - if (regKey.GetValue("Enabled") is int enabled && enabled == 0) - { - return true; - } + if (regKey.GetValue("DisabledByDefault") is int disabled && disabled == 1) + { + return true; } #endif return false; diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs index 1ace58df055d6b..06c52eef541621 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Implementations/MsQuic/Interop/SafeMsQuicConfigurationHandle.cs @@ -120,7 +120,8 @@ private static unsafe SafeMsQuicConfigurationHandle Create(QuicOptions options, throw new Exception("MaxBidirectionalStreams overflow."); } - if ((flags & QUIC_CREDENTIAL_FLAGS.CLIENT) == 0) + bool isServer = (flags & QUIC_CREDENTIAL_FLAGS.CLIENT) == 0; + if (isServer) { if (certificate == null && certificateContext == null) { @@ -241,9 +242,9 @@ private static unsafe SafeMsQuicConfigurationHandle Create(QuicOptions options, } #if TARGET_WINDOWS - if ((Interop.SECURITY_STATUS)status == Interop.SECURITY_STATUS.AlgorithmMismatch && MsQuicApi.Tls13MayBeDisabled) + if ((Interop.SECURITY_STATUS)status == Interop.SECURITY_STATUS.AlgorithmMismatch && (isServer ? MsQuicApi.Tls13ServerMayBeDisabled : MsQuicApi.Tls13ClientMayBeDisabled)) { - throw new MsQuicException(status, SR.net_ssl_app_protocols_invalid); + throw new MsQuicException(status, SR.net_quic_tls_version_notsupported); } #endif From 07b574185b2c2d6b447827b32a1adecc07e92bb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Fri, 17 Jun 2022 20:49:48 +0900 Subject: [PATCH 187/337] Generate method bodies for delegate Invoke methods (#70883) There is a dataflow warning suppression in System.Linq.Expressions that assumes we'll always have an invocable method body for delegate Invoke method. We need one in IL. We don't in native code. Emulate what IL Linker does and generate a method body. This is a size regression. Suppression: https://github.com/dotnet/runtime/blob/3b2883b097a773715ca84056885e0ca1488da36e/src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/TypeUtils.cs#L906-L912 Fixes #70880. --- .../DependencyAnalysis/TypeMetadataNode.cs | 9 ++++++--- .../nativeaot/SmokeTests/Reflection/Reflection.cs | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeMetadataNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeMetadataNode.cs index a85e669a17a532..b81cddee9188c6 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeMetadataNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/TypeMetadataNode.cs @@ -46,11 +46,14 @@ public override IEnumerable GetStaticDependencies(NodeFacto var mdManager = (UsageBasedMetadataManager)factory.MetadataManager; if (_type.IsDelegate) { - // A delegate type metadata is rather useless without the Invoke method. - // If someone reflects on a delegate, chances are they're going to look at the signature. + // We've decided as a policy that delegate Invoke methods will be generated in full. + // The libraries (e.g. System.Linq.Expressions) have trimming warning suppressions + // in places where they assume IL-level trimming (where the method cannot be removed). + // We ask for a full reflectable method with its method body instead of just the + // metadata. var invokeMethod = _type.GetMethod("Invoke", null); if (!mdManager.IsReflectionBlocked(invokeMethod)) - dependencies.Add(factory.MethodMetadata(invokeMethod), "Delegate invoke method metadata"); + dependencies.Add(factory.ReflectableMethod(invokeMethod), "Delegate invoke method"); } if (_type.IsEnum) diff --git a/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs b/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs index 78d1a6c0560c62..67894c9e5fb52e 100644 --- a/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs +++ b/src/tests/nativeaot/SmokeTests/Reflection/Reflection.cs @@ -9,6 +9,7 @@ using System; using System.Diagnostics.CodeAnalysis; +using System.Linq.Expressions; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Reflection; @@ -31,6 +32,7 @@ private static int Main() TestVirtualDelegateTargets.Run(); TestRunClassConstructor.Run(); TestFieldMetadata.Run(); + TestLinqInvocation.Run(); #if !OPTIMIZED_MODE_WITHOUT_SCANNER TestContainment.Run(); TestInterfaceMethod.Run(); @@ -1859,6 +1861,19 @@ public static void Run() } } + class TestLinqInvocation + { + delegate void RunMeDelegate(); + + static void RunMe() { } + + public static void Run() + { + Expression> ex = (RunMeDelegate m) => m(); + ex.Compile()(RunMe); + } + } + class TestRunClassConstructor { static class TypeWithNoStaticFieldsButACCtor From c75659b31a2fd0044e416608a4637a0930b7b71a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Fri, 17 Jun 2022 20:50:44 +0900 Subject: [PATCH 188/337] Avoid crashing on unresolved dependencies (#70871) Fixes #70815. --- .../Compiler/LazyGenerics/GraphBuilder.cs | 7 +++++-- .../Compiler/UsageBasedMetadataManager.cs | 20 +++++++++++++------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/LazyGenerics/GraphBuilder.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/LazyGenerics/GraphBuilder.cs index 5cdf10665fa280..fd03cb65957872 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/LazyGenerics/GraphBuilder.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/LazyGenerics/GraphBuilder.cs @@ -201,8 +201,11 @@ private void WalkMethod(EcmaMethod method) && _metadataReader.GetMemberReference((MemberReferenceHandle)accessedMethod).Parent.Kind == HandleKind.TypeSpecification)) { var m = methodIL.GetObject(MetadataTokens.GetToken(accessedMethod), NotFoundBehavior.ReturnNull) as MethodDesc; - ProcessTypeReference(m.OwningType, typeContext, methodContext); - ProcessMethodCall(m, typeContext, methodContext); + if (m != null) + { + ProcessTypeReference(m.OwningType, typeContext, methodContext); + ProcessMethodCall(m, typeContext, methodContext); + } } break; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs index d11c8c8b928861..1fce61d2bdc739 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/UsageBasedMetadataManager.cs @@ -683,13 +683,21 @@ private void GetFlowDependenciesForInstantiation(ref DependencyList dependencies var genericParameter = (GenericParameterDesc)typicalInstantiation[i]; if (FlowAnnotations.GetGenericParameterAnnotation(genericParameter) != default) { - var deps = ILCompiler.Dataflow.ReflectionMethodBodyScanner.ProcessGenericArgumentDataFlow(factory, FlowAnnotations, Logger, genericParameter, instantiation[i], source); - if (deps.Count > 0) + try { - if (dependencies == null) - dependencies = deps; - else - dependencies.AddRange(deps); + var deps = ILCompiler.Dataflow.ReflectionMethodBodyScanner.ProcessGenericArgumentDataFlow(factory, FlowAnnotations, Logger, genericParameter, instantiation[i], source); + if (deps.Count > 0) + { + if (dependencies == null) + dependencies = deps; + else + dependencies.AddRange(deps); + } + } + catch (TypeSystemException) + { + // Wasn't able to do dataflow because of missing references or something like that. + // This likely won't compile either, so we don't care about missing dependencies. } } } From 3fdee968742f3de26001efc011f3886479e836bc Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Fri, 17 Jun 2022 08:11:32 -0400 Subject: [PATCH 189/337] Enable IDE0020 (Use pattern matching) (#70523) * Enable IDE0020 (Use pattern matching) * Update src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriter.cs Co-authored-by: Buyaa Namnan * Update variable naming Co-authored-by: Buyaa Namnan --- eng/CodeAnalysis.src.globalconfig | 2 +- .../src/System/RuntimeTypeHandle.cs | 3 +- .../MissingMetadataExceptionCreator.cs | 7 +- .../Runtime/TypeLoader/TypeBuilder.cs | 16 ++--- .../Runtime/TypeLoader/TypeBuilderState.cs | 4 +- ...peLoaderEnvironment.LdTokenResultLookup.cs | 6 +- .../Internal/TypeSystem/TypeDesc.Runtime.cs | 8 +-- .../TypeSystem/TypeSystemContext.Runtime.cs | 4 +- .../TypedParts/Discovery/DiscoveredPart.cs | 3 +- .../src/System/Data/ConstraintCollection.cs | 3 +- .../Data/DataColumnPropertyDescriptor.cs | 13 +--- .../src/System/Data/DataRelation.cs | 3 +- .../Data/DataRelationPropertyDescriptor.cs | 12 +--- .../Data/DataTablePropertyDescriptor.cs | 12 +--- .../src/System/Data/Filter/BinaryNode.cs | 3 +- .../src/System/Data/SQLTypes/SQLBinary.cs | 4 +- .../src/System/Data/SQLTypes/SQLBoolean.cs | 4 +- .../src/System/Data/SQLTypes/SQLByte.cs | 4 +- .../src/System/Data/SQLTypes/SQLDateTime.cs | 4 +- .../src/System/Data/SQLTypes/SQLDouble.cs | 4 +- .../src/System/Data/SQLTypes/SQLGuid.cs | 4 +- .../src/System/Data/SQLTypes/SQLInt16.cs | 4 +- .../src/System/Data/SQLTypes/SQLInt32.cs | 4 +- .../src/System/Data/SQLTypes/SQLInt64.cs | 4 +- .../src/System/Data/SQLTypes/SQLMoney.cs | 4 +- .../src/System/Data/SQLTypes/SQLSingle.cs | 4 +- .../src/System/Data/SQLTypes/SQLString.cs | 4 +- .../src/System/Data/SimpleType.cs | 4 +- .../src/System/Data/XMLSchema.cs | 20 ++---- .../src/System/Data/XmlDataLoader.cs | 3 +- .../src/System/Data/xmlsaver.cs | 12 +--- .../System.Data.OleDb/src/OleDbConnection.cs | 3 +- .../AccountManagement/StoreCtx.cs | 6 +- .../DirectoryServices/DirectoryEntry.cs | 24 ++----- .../Interpreter/InstructionList.cs | 3 +- .../Runtime/Serialization/AccessorBuilder.cs | 6 +- .../Serialization/ClassDataContract.cs | 4 +- .../Runtime/Serialization/CodeGenerator.cs | 9 +-- .../Runtime/Serialization/DataContract.cs | 9 +-- .../Runtime/Serialization/SchemaExporter.cs | 3 +- .../src/System/Xml/Schema/Preprocessor.cs | 27 +++----- .../Xml/Schema/SchemaCollectionCompiler.cs | 39 ++++------- .../Schema/SchemaCollectionpreProcessor.cs | 53 +++++---------- .../System/Xml/Schema/SchemaSetCompiler.cs | 42 ++++-------- .../System/Xml/Schema/XmlSchemaValidator.cs | 6 +- .../System/Xml/Serialization/CodeGenerator.cs | 9 +-- .../System/Xml/Serialization/ImportContext.cs | 31 ++++----- .../Xml/Serialization/SchemaObjectWriter.cs | 9 +-- .../Serialization/SoapReflectionImporter.cs | 3 +- .../src/System/Xml/Serialization/Types.cs | 3 +- .../System/Xml/Serialization/XmlAttributes.cs | 3 +- .../Serialization/XmlReflectionImporter.cs | 3 +- .../Xml/Serialization/XmlSchemaExporter.cs | 25 +++---- .../Xml/Serialization/XmlSchemaImporter.cs | 63 +++++++----------- .../System/Xml/Serialization/XmlSchemas.cs | 12 ++-- .../Serialization/XmlSerializationReader.cs | 42 +++++------- .../XmlSerializationReaderILGen.cs | 40 +++++------- .../Serialization/XmlSerializationWriter.cs | 65 +++++++++---------- .../XmlSerializationWriterILGen.cs | 53 +++++++-------- .../System/Xml/Serialization/XmlSerializer.cs | 3 +- .../src/System/Xml/Xsl/QIL/QilXmlWriter.cs | 4 +- 61 files changed, 274 insertions(+), 514 deletions(-) diff --git a/eng/CodeAnalysis.src.globalconfig b/eng/CodeAnalysis.src.globalconfig index ef23d84e18ff26..aba919edc30b34 100644 --- a/eng/CodeAnalysis.src.globalconfig +++ b/eng/CodeAnalysis.src.globalconfig @@ -1356,7 +1356,7 @@ dotnet_diagnostic.IDE0018.severity = suggestion dotnet_diagnostic.IDE0019.severity = suggestion # IDE0020: Use pattern matching to avoid is check followed by a cast (with variable) -dotnet_diagnostic.IDE0020.severity = suggestion +dotnet_diagnostic.IDE0020.severity = warning # IDE0021: Use expression body for constructors dotnet_diagnostic.IDE0021.severity = silent diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs index 83fce9bcd1cc15..433ecd599297b6 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs @@ -32,9 +32,8 @@ private RuntimeTypeHandle(IntPtr value) public override bool Equals(object? obj) { - if (obj is RuntimeTypeHandle) + if (obj is RuntimeTypeHandle handle) { - RuntimeTypeHandle handle = (RuntimeTypeHandle)obj; return Equals(handle); } return false; diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/PayForPlayExperience/MissingMetadataExceptionCreator.cs b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/PayForPlayExperience/MissingMetadataExceptionCreator.cs index 818ba99f82a950..46b245f9db7438 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/PayForPlayExperience/MissingMetadataExceptionCreator.cs +++ b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/PayForPlayExperience/MissingMetadataExceptionCreator.cs @@ -99,16 +99,13 @@ public static string ComputeUsefulPertainantIfPossible(object pertainant) return type.ToDisplayStringIfAvailable(null); } - if (pertainant is MemberInfo) + if (pertainant is MemberInfo memberInfo) { - MemberInfo memberInfo = (MemberInfo)pertainant; - StringBuilder friendlyName = new StringBuilder(memberInfo.DeclaringType.ToDisplayStringIfAvailable(null)); friendlyName.Append('.'); friendlyName.Append(memberInfo.Name); - if (pertainant is MethodBase) + if (pertainant is MethodBase method) { - MethodBase method = (MethodBase)pertainant; bool first; // write out generic parameters diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs index 1db84afc02197c..ab1bbfba737a46 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilder.cs @@ -266,10 +266,8 @@ internal void PrepareType(TypeDesc type) bool noExtraPreparation = false; // Set this to true for types which don't need other types to be prepared. I.e GenericTypeDefinitions - if (type is DefType) + if (type is DefType typeAsDefType) { - DefType typeAsDefType = (DefType)type; - if (typeAsDefType.HasInstantiation) { if (typeAsDefType.IsTypeDefinition) @@ -305,10 +303,8 @@ internal void PrepareType(TypeDesc type) { PrepareType(((ParameterizedType)type).ParameterType); - if (type is ArrayType) + if (type is ArrayType typeAsArrayType) { - ArrayType typeAsArrayType = (ArrayType)type; - if (typeAsArrayType.IsSzArray && !typeAsArrayType.ElementType.IsPointer) { TypeDesc.ComputeTemplate(state); @@ -1326,10 +1322,8 @@ private void FinishRuntimeType(TypeDesc type) var state = type.GetTypeBuilderState(); - if (type is DefType) + if (type is DefType typeAsDefType) { - DefType typeAsDefType = (DefType)type; - if (type.HasInstantiation) { // Type definitions don't need any further finishing once created by the EETypeCreator @@ -1367,10 +1361,8 @@ private void FinishRuntimeType(TypeDesc type) } else if (type is ParameterizedType) { - if (type is ArrayType) + if (type is ArrayType typeAsSzArrayType) { - ArrayType typeAsSzArrayType = (ArrayType)type; - state.HalfBakedRuntimeTypeHandle.SetRelatedParameterType(GetRuntimeTypeHandle(typeAsSzArrayType.ElementType)); state.HalfBakedRuntimeTypeHandle.SetComponentSize(state.ComponentSize.Value); diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilderState.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilderState.cs index 85037bae3fa1e2..dcc81310178d82 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilderState.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeBuilderState.cs @@ -973,10 +973,8 @@ public int? FieldAlignment { return checked((ushort)((DefType)TypeBeingBuilt).InstanceFieldAlignment.AsInt); } - else if (TypeBeingBuilt is ArrayType) + else if (TypeBeingBuilt is ArrayType arrayType) { - ArrayType arrayType = (ArrayType)TypeBeingBuilt; - if (arrayType.ElementType is DefType) { return checked((ushort)((DefType)arrayType.ElementType).InstanceFieldAlignment.AsInt); diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.LdTokenResultLookup.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.LdTokenResultLookup.cs index fd332cf1b751de..5083a87002d38c 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.LdTokenResultLookup.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/Runtime/TypeLoader/TypeLoaderEnvironment.LdTokenResultLookup.cs @@ -100,9 +100,8 @@ public RuntimeFieldHandleKey(RuntimeTypeHandle declaringType, string fieldName) public override bool Equals(object obj) { - if (obj is RuntimeFieldHandleKey) + if (obj is RuntimeFieldHandleKey other) { - RuntimeFieldHandleKey other = (RuntimeFieldHandleKey)obj; return Equals(other); } return false; @@ -145,9 +144,8 @@ public RuntimeMethodHandleKey(RuntimeTypeHandle declaringType, string methodName public override bool Equals(object obj) { - if (obj is RuntimeMethodHandleKey) + if (obj is RuntimeMethodHandleKey other) { - RuntimeMethodHandleKey other = (RuntimeMethodHandleKey)obj; return Equals(other); } return false; diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeDesc.Runtime.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeDesc.Runtime.cs index 66cd911473ffa1..09332e167c4b06 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeDesc.Runtime.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeDesc.Runtime.cs @@ -84,10 +84,8 @@ internal bool RetrieveRuntimeTypeHandleIfPossible() if (state != null && state.AttemptedAndFailedToRetrieveTypeHandle) return false; - if (type is DefType) + if (type is DefType typeAsDefType) { - DefType typeAsDefType = (DefType)type; - TypeDesc typeDefinition = typeAsDefType.GetTypeDefinition(); RuntimeTypeHandle typeDefHandle = typeDefinition.RuntimeTypeHandle; if (typeDefHandle.IsNull()) @@ -155,10 +153,8 @@ internal bool RetrieveRuntimeTypeHandleIfPossible() } } } - else if (type is ParameterizedType) + else if (type is ParameterizedType typeAsParameterType) { - ParameterizedType typeAsParameterType = (ParameterizedType)type; - if (typeAsParameterType.ParameterType.RetrieveRuntimeTypeHandleIfPossible()) { RuntimeTypeHandle rtth; diff --git a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs index 55923303d641e2..1f2b9cd01f0005 100644 --- a/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs +++ b/src/coreclr/nativeaot/System.Private.TypeLoader/src/Internal/TypeSystem/TypeSystemContext.Runtime.cs @@ -321,10 +321,8 @@ protected override int GetValueHashCode(MethodDesc value) protected override bool CompareKeyToValue(RuntimeMethodKey key, MethodDesc value) { - if (value is RuntimeMethodDesc) + if (value is RuntimeMethodDesc runtimeMethod) { - RuntimeMethodDesc runtimeMethod = (RuntimeMethodDesc)value; - if (key._unboxingStub != runtimeMethod.UnboxingStub) return false; diff --git a/src/libraries/System.Composition.TypedParts/src/System/Composition/TypedParts/Discovery/DiscoveredPart.cs b/src/libraries/System.Composition.TypedParts/src/System/Composition/TypedParts/Discovery/DiscoveredPart.cs index 2f3f6dcc923eb5..48e8d77d2b318e 100644 --- a/src/libraries/System.Composition.TypedParts/src/System/Composition/TypedParts/Discovery/DiscoveredPart.cs +++ b/src/libraries/System.Composition.TypedParts/src/System/Composition/TypedParts/Discovery/DiscoveredPart.cs @@ -212,9 +212,8 @@ public IDictionary GetPartMetadata(TypeInfo partType) var partMetadata = new Dictionary(); foreach (var attr in _attributeContext.GetDeclaredAttributes(partType.AsType(), partType)) { - if (attr is PartMetadataAttribute) + if (attr is PartMetadataAttribute ma) { - var ma = (PartMetadataAttribute)attr; partMetadata.Add(ma.Name, ma.Value); } } diff --git a/src/libraries/System.Data.Common/src/System/Data/ConstraintCollection.cs b/src/libraries/System.Data.Common/src/System/Data/ConstraintCollection.cs index 2efbd4faacacaa..b410f4b96068de 100644 --- a/src/libraries/System.Data.Common/src/System/Data/ConstraintCollection.cs +++ b/src/libraries/System.Data.Common/src/System/Data/ConstraintCollection.cs @@ -113,9 +113,8 @@ internal void Add(Constraint constraint, bool addUniqueWhenAddingForeign) } AddUniqueConstraint((UniqueConstraint)constraint); } - else if (constraint is ForeignKeyConstraint) + else if (constraint is ForeignKeyConstraint fk) { - ForeignKeyConstraint fk = (ForeignKeyConstraint)constraint; if (addUniqueWhenAddingForeign) { UniqueConstraint? key = fk.RelatedTable.Constraints.FindKeyConstraint(fk.RelatedColumnsReference); diff --git a/src/libraries/System.Data.Common/src/System/Data/DataColumnPropertyDescriptor.cs b/src/libraries/System.Data.Common/src/System/Data/DataColumnPropertyDescriptor.cs index a26a31506adf3d..8e830656626e27 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataColumnPropertyDescriptor.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataColumnPropertyDescriptor.cs @@ -43,16 +43,9 @@ public override AttributeCollection Attributes public override Type PropertyType => Column.DataType; - public override bool Equals([NotNullWhen(true)] object? other) - { - if (other is DataColumnPropertyDescriptor) - { - DataColumnPropertyDescriptor descriptor = (DataColumnPropertyDescriptor)other; - return (descriptor.Column == Column); - } - - return false; - } + public override bool Equals([NotNullWhen(true)] object? other) => + other is DataColumnPropertyDescriptor descriptor && + descriptor.Column == Column; public override int GetHashCode() => Column.GetHashCode(); diff --git a/src/libraries/System.Data.Common/src/System/Data/DataRelation.cs b/src/libraries/System.Data.Common/src/System/Data/DataRelation.cs index 4154474effaf4d..71170c51c79a9e 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataRelation.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataRelation.cs @@ -796,9 +796,8 @@ internal void ValidateMultipleNestedRelations() foreach (Constraint cs in ChildTable.Constraints) { - if (cs is ForeignKeyConstraint) + if (cs is ForeignKeyConstraint fk) { - ForeignKeyConstraint fk = (ForeignKeyConstraint)cs; if (!XmlTreeGen.AutoGenerated(fk, true)) { throw ExceptionBuilder.TableCantBeNestedInTwoTables(ChildTable.TableName); diff --git a/src/libraries/System.Data.Common/src/System/Data/DataRelationPropertyDescriptor.cs b/src/libraries/System.Data.Common/src/System/Data/DataRelationPropertyDescriptor.cs index 4732907089cc38..5ea84cfa17e60e 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataRelationPropertyDescriptor.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataRelationPropertyDescriptor.cs @@ -21,15 +21,9 @@ internal DataRelationPropertyDescriptor(DataRelation dataRelation) : base(dataRe public override Type PropertyType => typeof(IBindingList); - public override bool Equals([NotNullWhen(true)] object? other) - { - if (other is DataRelationPropertyDescriptor) - { - DataRelationPropertyDescriptor descriptor = (DataRelationPropertyDescriptor)other; - return (descriptor.Relation == Relation); - } - return false; - } + public override bool Equals([NotNullWhen(true)] object? other) => + other is DataRelationPropertyDescriptor descriptor && + descriptor.Relation == Relation; public override int GetHashCode() => Relation.GetHashCode(); diff --git a/src/libraries/System.Data.Common/src/System/Data/DataTablePropertyDescriptor.cs b/src/libraries/System.Data.Common/src/System/Data/DataTablePropertyDescriptor.cs index 766f9db78e7fee..8a4668c7eac15d 100644 --- a/src/libraries/System.Data.Common/src/System/Data/DataTablePropertyDescriptor.cs +++ b/src/libraries/System.Data.Common/src/System/Data/DataTablePropertyDescriptor.cs @@ -21,15 +21,9 @@ internal DataTablePropertyDescriptor(DataTable dataTable) : base(dataTable.Table public override Type PropertyType => typeof(IBindingList); - public override bool Equals([NotNullWhen(true)] object? other) - { - if (other is DataTablePropertyDescriptor) - { - DataTablePropertyDescriptor descriptor = (DataTablePropertyDescriptor)other; - return (descriptor.Table == Table); - } - return false; - } + public override bool Equals([NotNullWhen(true)] object? other) => + other is DataTablePropertyDescriptor descriptor && + descriptor.Table == Table; public override int GetHashCode() => Table.GetHashCode(); diff --git a/src/libraries/System.Data.Common/src/System/Data/Filter/BinaryNode.cs b/src/libraries/System.Data.Common/src/System/Data/Filter/BinaryNode.cs index 6ace6e1629b390..0691bf567fe378 100644 --- a/src/libraries/System.Data.Common/src/System/Data/Filter/BinaryNode.cs +++ b/src/libraries/System.Data.Common/src/System/Data/Filter/BinaryNode.cs @@ -83,9 +83,8 @@ internal override ExpressionNode Optimize() if (_op == Operators.Is) { // only 'Is Null' or 'Is Not Null' are valid - if (_right is UnaryNode) + if (_right is UnaryNode un) { - UnaryNode un = (UnaryNode)_right; if (un._op != Operators.Not) { throw ExprException.InvalidIsSyntax(); diff --git a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLBinary.cs b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLBinary.cs index f6a45dbba5f2cb..d684a8a410b72e 100644 --- a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLBinary.cs +++ b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLBinary.cs @@ -338,10 +338,8 @@ public SqlGuid ToSqlGuid() // If object is not of same type, this method throws an ArgumentException. public int CompareTo(object? value) { - if (value is SqlBinary) + if (value is SqlBinary i) { - SqlBinary i = (SqlBinary)value; - return CompareTo(i); } throw ADP.WrongType(value!.GetType(), typeof(SqlBinary)); diff --git a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLBoolean.cs b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLBoolean.cs index d7b723f9f05f01..746e0ce021e06f 100644 --- a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLBoolean.cs +++ b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLBoolean.cs @@ -441,10 +441,8 @@ public SqlString ToSqlString() // If object is not of same type, this method throws an ArgumentException. public int CompareTo(object? value) { - if (value is SqlBoolean) + if (value is SqlBoolean i) { - SqlBoolean i = (SqlBoolean)value; - return CompareTo(i); } throw ADP.WrongType(value!.GetType(), typeof(SqlBoolean)); diff --git a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLByte.cs b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLByte.cs index 3dc5548ffed7a3..84a5abeb54fc0a 100644 --- a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLByte.cs +++ b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLByte.cs @@ -450,10 +450,8 @@ public SqlString ToSqlString() // If object is not of same type, this method throws an ArgumentException. public int CompareTo(object? value) { - if (value is SqlByte) + if (value is SqlByte i) { - SqlByte i = (SqlByte)value; - return CompareTo(i); } throw ADP.WrongType(value!.GetType(), typeof(SqlByte)); diff --git a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLDateTime.cs b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLDateTime.cs index 1edd44bedf3388..2b246f2d40c76e 100644 --- a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLDateTime.cs +++ b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLDateTime.cs @@ -597,10 +597,8 @@ public SqlString ToSqlString() // If object is not of same type, this method throws an ArgumentException. public int CompareTo(object? value) { - if (value is SqlDateTime) + if (value is SqlDateTime i) { - SqlDateTime i = (SqlDateTime)value; - return CompareTo(i); } throw ADP.WrongType(value!.GetType(), typeof(SqlDateTime)); diff --git a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLDouble.cs b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLDouble.cs index 4cc9ac4e321e0e..ed7eb544cb9fc7 100644 --- a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLDouble.cs +++ b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLDouble.cs @@ -366,10 +366,8 @@ public SqlString ToSqlString() // If object is not of same type, this method throws an ArgumentException. public int CompareTo(object? value) { - if (value is SqlDouble) + if (value is SqlDouble i) { - SqlDouble i = (SqlDouble)value; - return CompareTo(i); } throw ADP.WrongType(value!.GetType(), typeof(SqlDouble)); diff --git a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLGuid.cs b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLGuid.cs index 316706e0cc7df3..36c44d237f640b 100644 --- a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLGuid.cs +++ b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLGuid.cs @@ -259,10 +259,8 @@ public SqlBinary ToSqlBinary() // If object is not of same type, this method throws an ArgumentException. public int CompareTo(object? value) { - if (value is SqlGuid) + if (value is SqlGuid i) { - SqlGuid i = (SqlGuid)value; - return CompareTo(i); } throw ADP.WrongType(value!.GetType(), typeof(SqlGuid)); diff --git a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLInt16.cs b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLInt16.cs index d3879a06cf91b2..163974ba3baa3d 100644 --- a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLInt16.cs +++ b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLInt16.cs @@ -451,10 +451,8 @@ public SqlString ToSqlString() // If object is not of same type, this method throws an ArgumentException. public int CompareTo(object? value) { - if (value is SqlInt16) + if (value is SqlInt16 i) { - SqlInt16 i = (SqlInt16)value; - return CompareTo(i); } throw ADP.WrongType(value!.GetType(), typeof(SqlInt16)); diff --git a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLInt32.cs b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLInt32.cs index 8ce08e74e4403e..8bf98ce1b30f5d 100644 --- a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLInt32.cs +++ b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLInt32.cs @@ -466,10 +466,8 @@ public SqlString ToSqlString() // If object is not of same type, this method throws an ArgumentException. public int CompareTo(object? value) { - if (value is SqlInt32) + if (value is SqlInt32 i) { - SqlInt32 i = (SqlInt32)value; - return CompareTo(i); } throw ADP.WrongType(value!.GetType(), typeof(SqlInt32)); diff --git a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLInt64.cs b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLInt64.cs index 393945b0303957..6dcb0ae7d48221 100644 --- a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLInt64.cs +++ b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLInt64.cs @@ -525,10 +525,8 @@ public SqlString ToSqlString() // If object is not of same type, this method throws an ArgumentException. public int CompareTo(object? value) { - if (value is SqlInt64) + if (value is SqlInt64 i) { - SqlInt64 i = (SqlInt64)value; - return CompareTo(i); } throw ADP.WrongType(value!.GetType(), typeof(SqlInt64)); diff --git a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLMoney.cs b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLMoney.cs index 24f6a1432f0e1c..50b9403146e3c8 100644 --- a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLMoney.cs +++ b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLMoney.cs @@ -515,10 +515,8 @@ public SqlString ToSqlString() // If object is not of same type, this method throws an ArgumentException. public int CompareTo(object? value) { - if (value is SqlMoney) + if (value is SqlMoney i) { - SqlMoney i = (SqlMoney)value; - return CompareTo(i); } throw ADP.WrongType(value!.GetType(), typeof(SqlMoney)); diff --git a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLSingle.cs b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLSingle.cs index 5fa7562824e13d..e59897a89e12e5 100644 --- a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLSingle.cs +++ b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLSingle.cs @@ -376,10 +376,8 @@ public SqlString ToSqlString() // If object is not of same type, this method throws an ArgumentException. public int CompareTo(object? value) { - if (value is SqlSingle) + if (value is SqlSingle i) { - SqlSingle i = (SqlSingle)value; - return CompareTo(i); } throw ADP.WrongType(value!.GetType(), typeof(SqlSingle)); diff --git a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLString.cs b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLString.cs index 6b110831355528..5e9e2f53f028e6 100644 --- a/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLString.cs +++ b/src/libraries/System.Data.Common/src/System/Data/SQLTypes/SQLString.cs @@ -836,10 +836,8 @@ private void Print() { // If object is not of same type, this method throws an ArgumentException. public int CompareTo(object? value) { - if (value is SqlString) + if (value is SqlString i) { - SqlString i = (SqlString)value; - return CompareTo(i); } throw ADP.WrongType(value!.GetType(), typeof(SqlString)); diff --git a/src/libraries/System.Data.Common/src/System/Data/SimpleType.cs b/src/libraries/System.Data.Common/src/System/Data/SimpleType.cs index 655256d8e3fbdb..ab19e2e5d423ab 100644 --- a/src/libraries/System.Data.Common/src/System/Data/SimpleType.cs +++ b/src/libraries/System.Data.Common/src/System/Data/SimpleType.cs @@ -53,10 +53,8 @@ internal void LoadTypeValues(XmlSchemaSimpleType node) (node.Content is XmlSchemaSimpleTypeUnion)) throw ExceptionBuilder.SimpleTypeNotSupported(); - if (node.Content is XmlSchemaSimpleTypeRestriction) + if (node.Content is XmlSchemaSimpleTypeRestriction content) { - XmlSchemaSimpleTypeRestriction content = (XmlSchemaSimpleTypeRestriction)node.Content; - XmlSchemaSimpleType? ancestor = node.BaseXmlSchemaType as XmlSchemaSimpleType; if ((ancestor != null) && (ancestor.QualifiedName.Namespace != Keywords.XSDNS)) { diff --git a/src/libraries/System.Data.Common/src/System/Data/XMLSchema.cs b/src/libraries/System.Data.Common/src/System/Data/XMLSchema.cs index 0304f2522d24b3..3ec208f0257b66 100644 --- a/src/libraries/System.Data.Common/src/System/Data/XMLSchema.cs +++ b/src/libraries/System.Data.Common/src/System/Data/XMLSchema.cs @@ -186,9 +186,8 @@ private void CollectElementsAnnotations(XmlSchema schema, ArrayList schemaList) { _annotations!.Add((XmlSchemaAnnotation)item); } - if (item is XmlSchemaElement) + if (item is XmlSchemaElement elem) { - XmlSchemaElement elem = (XmlSchemaElement)item; _elements!.Add(elem); _elementsTable![elem.QualifiedName] = elem; } @@ -610,9 +609,8 @@ private static int DatasetElementCount(XmlSchemaObjectCollection elements) if (ct.ContentModel is XmlSchemaSimpleContent) { XmlSchemaAnnotated? cContent = ((XmlSchemaSimpleContent)(ct.ContentModel)).Content; - if (cContent is XmlSchemaSimpleContentExtension) + if (cContent is XmlSchemaSimpleContentExtension ccExtension) { - XmlSchemaSimpleContentExtension ccExtension = ((XmlSchemaSimpleContentExtension)cContent); if (HasAttributes(ccExtension.Attributes)) return null; } @@ -1058,9 +1056,8 @@ internal void HandleComplexType(XmlSchemaComplexType ct, DataTable table, ArrayL if (ct.ContentModel is XmlSchemaComplexContent) { XmlSchemaAnnotated? cContent = ((XmlSchemaComplexContent)(ct.ContentModel)).Content; - if (cContent is XmlSchemaComplexContentExtension) + if (cContent is XmlSchemaComplexContentExtension ccExtension) { - XmlSchemaComplexContentExtension ccExtension = ((XmlSchemaComplexContentExtension)cContent); if (!(ct.BaseXmlSchemaType is XmlSchemaComplexType && FromInference)) HandleAttributes(ccExtension.Attributes, table, isBase); @@ -1102,9 +1099,8 @@ internal void HandleComplexType(XmlSchemaComplexType ct, DataTable table, ArrayL { Debug.Assert(ct.ContentModel is XmlSchemaSimpleContent, "expected simpleContent or complexContent"); XmlSchemaAnnotated cContent = ((XmlSchemaSimpleContent)(ct.ContentModel)).Content!; - if (cContent is XmlSchemaSimpleContentExtension) + if (cContent is XmlSchemaSimpleContentExtension ccExtension) { - XmlSchemaSimpleContentExtension ccExtension = ((XmlSchemaSimpleContentExtension)cContent); HandleAttributes(ccExtension.Attributes, table, isBase); if (ct.BaseXmlSchemaType is XmlSchemaComplexType) { @@ -1537,15 +1533,13 @@ internal static string GetInstanceName(XmlSchemaAnnotated node) Debug.Assert((node is XmlSchemaElement) || (node is XmlSchemaAttribute), "GetInstanceName should only be called on attribute or elements"); - if (node is XmlSchemaElement) + if (node is XmlSchemaElement el) { - XmlSchemaElement el = (XmlSchemaElement)node; instanceName = el.Name ?? el.RefName.Name; } - else if (node is XmlSchemaAttribute) + else if (node is XmlSchemaAttribute attr) { - XmlSchemaAttribute el = (XmlSchemaAttribute)node; - instanceName = el.Name ?? el.RefName.Name; + instanceName = attr.Name ?? attr.RefName.Name; } Debug.Assert((instanceName != null) && (instanceName.Length != 0), "instanceName cannot be null or empty. There's an error in the XSD compiler"); diff --git a/src/libraries/System.Data.Common/src/System/Data/XmlDataLoader.cs b/src/libraries/System.Data.Common/src/System/Data/XmlDataLoader.cs index ca41c924bdf604..9fbc27600048bd 100644 --- a/src/libraries/System.Data.Common/src/System/Data/XmlDataLoader.cs +++ b/src/libraries/System.Data.Common/src/System/Data/XmlDataLoader.cs @@ -513,9 +513,8 @@ private void LoadRows(DataRow? parentRow, XmlNode parentElement) for (XmlNode? n = parentElement.FirstChild; n != null; n = n.NextSibling) { - if (n is XmlElement) + if (n is XmlElement e) { - XmlElement e = (XmlElement)n; object? schema = _nodeToSchemaMap!.GetSchemaForNode(e, FIgnoreNamespace(e)); if (schema != null && schema is DataTable) diff --git a/src/libraries/System.Data.Common/src/System/Data/xmlsaver.cs b/src/libraries/System.Data.Common/src/System/Data/xmlsaver.cs index c8d9513cf0361f..fa03eaaec61f0f 100644 --- a/src/libraries/System.Data.Common/src/System/Data/xmlsaver.cs +++ b/src/libraries/System.Data.Common/src/System/Data/xmlsaver.cs @@ -1204,13 +1204,9 @@ internal XmlElement HandleRelation(DataRelation rel, XmlDocument dc) { for (XmlNode? n = schema.FirstChild; n != null; n = n.NextSibling) { - if (n is XmlElement) + if (n is XmlElement e && e.GetAttribute(Keywords.NAME) == name) { - XmlElement e = (XmlElement)n; - if (e.GetAttribute(Keywords.NAME) == name) - { - return e; - } + return e; } } return null; @@ -1992,10 +1988,8 @@ internal XmlElement HandleTable(DataTable table, XmlDocument dc, XmlElement sche XmlElement? constraint; DataColumn[] fields; - if (constraints[i] is UniqueConstraint) + if (constraints[i] is UniqueConstraint unique) { - UniqueConstraint unique = (UniqueConstraint)constraints[i]; - if (IsAutoGenerated(unique)) continue; diff --git a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs index 582f20230507d4..0578552235e638 100644 --- a/src/libraries/System.Data.OleDb/src/OleDbConnection.cs +++ b/src/libraries/System.Data.OleDb/src/OleDbConnection.cs @@ -217,9 +217,8 @@ public void ResetState() if (IsOpen) { object? value = GetDataSourcePropertyValue(OleDbPropertySetGuid.DataSourceInfo, ODB.DBPROP_CONNECTIONSTATUS); - if (value is int) + if (value is int connectionStatus) { - int connectionStatus = (int)value; switch (connectionStatus) { case ODB.DBPROPVAL_CS_UNINITIALIZED: // provider closed on us diff --git a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/StoreCtx.cs b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/StoreCtx.cs index 4ad0ab90f05e63..74a269344ff1b0 100644 --- a/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/StoreCtx.cs +++ b/src/libraries/System.DirectoryServices.AccountManagement/src/System/DirectoryServices/AccountManagement/StoreCtx.cs @@ -374,9 +374,8 @@ private void BuildFilterSet(Principal p, string[] propertySet, QbeFilterDescript value.GetType().ToString()); // Build the right filter based on type of the property value - if (value is PrincipalValueCollection) + if (value is PrincipalValueCollection trackingList) { - PrincipalValueCollection trackingList = (PrincipalValueCollection)value; foreach (string s in trackingList.Inserted) { object filter = FilterFactory.CreateFilter(propertyName); @@ -384,11 +383,10 @@ private void BuildFilterSet(Principal p, string[] propertySet, QbeFilterDescript qbeFilterDescription.FiltersToApply.Add(filter); } } - else if (value is X509Certificate2Collection) + else if (value is X509Certificate2Collection certCollection) { // Since QBE filter objects are always unpersisted, any certs in the collection // must have been inserted by the application. - X509Certificate2Collection certCollection = (X509Certificate2Collection)value; foreach (X509Certificate2 cert in certCollection) { object filter = FilterFactory.CreateFilter(propertyName); diff --git a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/DirectoryEntry.cs b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/DirectoryEntry.cs index dcdea0d5993f53..78150496bbb98f 100644 --- a/src/libraries/System.DirectoryServices/src/System/DirectoryServices/DirectoryEntry.cs +++ b/src/libraries/System.DirectoryServices/src/System/DirectoryServices/DirectoryEntry.cs @@ -806,13 +806,9 @@ internal void FillCache(string propertyName) } catch (TargetInvocationException e) { - if (e.InnerException != null) + if (e.InnerException is COMException inner) { - if (e.InnerException is COMException) - { - COMException inner = (COMException)e.InnerException; - throw new TargetInvocationException(e.Message, COMExceptionHelper.CreateFormattedComException(inner)); - } + throw new TargetInvocationException(e.Message, COMExceptionHelper.CreateFormattedComException(inner)); } throw; @@ -843,13 +839,9 @@ internal void FillCache(string propertyName) } catch (TargetInvocationException e) { - if (e.InnerException != null) + if (e.InnerException is COMException inner) { - if (e.InnerException is COMException) - { - COMException inner = (COMException)e.InnerException; - throw new TargetInvocationException(e.Message, COMExceptionHelper.CreateFormattedComException(inner)); - } + throw new TargetInvocationException(e.Message, COMExceptionHelper.CreateFormattedComException(inner)); } throw; @@ -876,13 +868,9 @@ public void InvokeSet(string propertyName, params object?[]? args) } catch (TargetInvocationException e) { - if (e.InnerException != null) + if (e.InnerException is COMException inner) { - if (e.InnerException is COMException) - { - COMException inner = (COMException)e.InnerException; - throw new TargetInvocationException(e.Message, COMExceptionHelper.CreateFormattedComException(inner)); - } + throw new TargetInvocationException(e.Message, COMExceptionHelper.CreateFormattedComException(inner)); } throw; diff --git a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/InstructionList.cs b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/InstructionList.cs index 4b36ac253dc335..4e9725abb10d02 100644 --- a/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/InstructionList.cs +++ b/src/libraries/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/InstructionList.cs @@ -357,9 +357,8 @@ public void EmitLoad(object? value, Type? type) return; } - if (value is int) + if (value is int i) { - int i = (int)value; if (i >= PushIntMinCachedValue && i <= PushIntMaxCachedValue) { if (s_Ints == null) diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/AccessorBuilder.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/AccessorBuilder.cs index a2052d19972c7a..47b6f31ccd4215 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/AccessorBuilder.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/AccessorBuilder.cs @@ -95,9 +95,8 @@ public static Getter CreateGetter(MemberInfo memberInfo) Justification = "The call to MakeGenericMethod is safe due to the fact that FastInvokerBuilder.CreateSetterInternal is not annotated.")] public static Setter CreateSetter(MemberInfo memberInfo) { - if (memberInfo is PropertyInfo) + if (memberInfo is PropertyInfo propInfo) { - PropertyInfo propInfo = (PropertyInfo)memberInfo; if (propInfo.CanWrite) { Type declaringType = propInfo.DeclaringType!; @@ -141,9 +140,8 @@ public static Setter CreateSetter(MemberInfo memberInfo) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.NoSetMethodForProperty, propInfo.DeclaringType, propInfo.Name))); } } - else if (memberInfo is FieldInfo) + else if (memberInfo is FieldInfo fieldInfo) { - FieldInfo fieldInfo = (FieldInfo)memberInfo; return (ref object obj, object? val) => { fieldInfo.SetValue(obj, val); diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/ClassDataContract.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/ClassDataContract.cs index c90bc4a6a76aa7..f559f30703660f 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/ClassDataContract.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/ClassDataContract.cs @@ -960,10 +960,8 @@ private void ImportDataMembers() DataMember memberContract = new DataMember(member); - if (member is PropertyInfo) + if (member is PropertyInfo property) { - PropertyInfo property = (PropertyInfo)member; - MethodInfo? getMethod = property.GetMethod; if (getMethod != null && IsMethodOverriding(getMethod)) continue; diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/CodeGenerator.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/CodeGenerator.cs index 9902146707a277..0879bcde79bae3 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/CodeGenerator.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/CodeGenerator.cs @@ -609,9 +609,8 @@ private static bool IsStruct(Type objType) internal Type LoadMember(MemberInfo memberInfo) { Type? memberType; - if (memberInfo is FieldInfo) + if (memberInfo is FieldInfo fieldInfo) { - FieldInfo fieldInfo = (FieldInfo)memberInfo; memberType = fieldInfo.FieldType; if (fieldInfo.IsStatic) { @@ -637,9 +636,8 @@ internal Type LoadMember(MemberInfo memberInfo) Call(getMethod); } } - else if (memberInfo is MethodInfo) + else if (memberInfo is MethodInfo method) { - MethodInfo method = (MethodInfo)memberInfo; memberType = method.ReturnType; Call(method); } @@ -652,9 +650,8 @@ internal Type LoadMember(MemberInfo memberInfo) internal void StoreMember(MemberInfo memberInfo) { - if (memberInfo is FieldInfo) + if (memberInfo is FieldInfo fieldInfo) { - FieldInfo fieldInfo = (FieldInfo)memberInfo; if (fieldInfo.IsStatic) { if (_codeGenTrace != CodeGenTrace.None) diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/DataContract.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/DataContract.cs index c3db619138ee32..b654711af2d5ab 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/DataContract.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/DataContract.cs @@ -2173,19 +2173,16 @@ private static bool IsMemberVisibleInSerializationModule(MemberInfo member) if (!IsTypeVisibleInSerializationModule(member.DeclaringType!)) return false; - if (member is MethodInfo) + if (member is MethodInfo method) { - MethodInfo method = (MethodInfo)member; return (method.IsAssembly || method.IsFamilyOrAssembly); } - else if (member is FieldInfo) + else if (member is FieldInfo field) { - FieldInfo field = (FieldInfo)member; return (field.IsAssembly || field.IsFamilyOrAssembly) && IsTypeVisible(field.FieldType); } - else if (member is ConstructorInfo) + else if (member is ConstructorInfo constructor) { - ConstructorInfo constructor = (ConstructorInfo)member; return (constructor.IsAssembly || constructor.IsFamilyOrAssembly); } diff --git a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/SchemaExporter.cs b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/SchemaExporter.cs index d85097f17acb5a..8b6a976c1b23ad 100644 --- a/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/SchemaExporter.cs +++ b/src/libraries/System.Private.DataContractSerialization/src/System/Runtime/Serialization/SchemaExporter.cs @@ -90,9 +90,8 @@ private void ExportDataContract(DataContract dataContract) { XmlSchema schema = GetSchema(dataContract.StableName.Namespace); - if (dataContract is ClassDataContract) + if (dataContract is ClassDataContract classDataContract) { - ClassDataContract classDataContract = (ClassDataContract)dataContract; if (classDataContract.IsISerializable) ExportISerializableDataContract(classDataContract, schema); else diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/Preprocessor.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/Preprocessor.cs index 723ee9d6a9b481..4f737057a7eeb9 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/Preprocessor.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/Preprocessor.cs @@ -886,9 +886,8 @@ private void PreprocessRedefine(RedefineEntry redefineEntry) } } } - else if (items[i] is XmlSchemaAttributeGroup) + else if (items[i] is XmlSchemaAttributeGroup attributeGroup) { - XmlSchemaAttributeGroup attributeGroup = (XmlSchemaAttributeGroup)items[i]; PreprocessAttributeGroup(attributeGroup); attributeGroup.QualifiedName.SetNamespace(targetNS); //Since PreprocessAttributeGroup will use this.targetNamespace and that will be that of the root schema's if (redefine.AttributeGroups[attributeGroup.QualifiedName] != null) @@ -912,9 +911,8 @@ private void PreprocessRedefine(RedefineEntry redefineEntry) } } } - else if (items[i] is XmlSchemaComplexType) + else if (items[i] is XmlSchemaComplexType complexType) { - XmlSchemaComplexType complexType = (XmlSchemaComplexType)items[i]; PreprocessComplexType(complexType, false); complexType.QualifiedName.SetNamespace(targetNS); //Since PreprocessComplexType will use this.targetNamespace and that will be that of the root schema's if (redefine.SchemaTypes[complexType.QualifiedName] != null) @@ -942,9 +940,8 @@ private void PreprocessRedefine(RedefineEntry redefineEntry) } } } - else if (items[i] is XmlSchemaSimpleType) + else if (items[i] is XmlSchemaSimpleType simpleType) { - XmlSchemaSimpleType simpleType = (XmlSchemaSimpleType)items[i]; PreprocessSimpleType(simpleType, false); simpleType.QualifiedName.SetNamespace(targetNS); //Since PreprocessSimpleType will use this.targetNamespace and that will be that of the root schema's if (redefine.SchemaTypes[simpleType.QualifiedName] != null) @@ -1492,9 +1489,8 @@ private void PreprocessIdentityConstraint(XmlSchemaIdentityConstraint constraint valid = false; } - if (constraint is XmlSchemaKeyref) + if (constraint is XmlSchemaKeyref keyref) { - XmlSchemaKeyref keyref = (XmlSchemaKeyref)constraint; if (keyref.Refer.IsEmpty) { SendValidationEvent(SR.Sch_IdConstraintNoRefer, constraint); @@ -1570,9 +1566,8 @@ private void PreprocessSimpleType(XmlSchemaSimpleType simpleType, bool local) { SendValidationEvent(SR.Sch_NoSimpleTypeContent, simpleType); } - else if (simpleType.Content is XmlSchemaSimpleTypeRestriction) + else if (simpleType.Content is XmlSchemaSimpleTypeRestriction restriction) { - XmlSchemaSimpleTypeRestriction restriction = (XmlSchemaSimpleTypeRestriction)simpleType.Content; //SetParent SetParent(restriction, simpleType); for (int i = 0; i < restriction.Facets.Count; ++i) @@ -1602,9 +1597,8 @@ private void PreprocessSimpleType(XmlSchemaSimpleType simpleType, bool local) PreprocessAnnotation(restriction); //set parent of annotation child of simple type restriction ValidateIdAttribute(restriction); } - else if (simpleType.Content is XmlSchemaSimpleTypeList) + else if (simpleType.Content is XmlSchemaSimpleTypeList list) { - XmlSchemaSimpleTypeList list = (XmlSchemaSimpleTypeList)simpleType.Content; SetParent(list, simpleType); if (list.ItemType != null) @@ -1750,9 +1744,8 @@ private void PreprocessComplexType(XmlSchemaComplexType complexType, bool local) SetParent(content.Content, content); //simplecontent extension / restriction PreprocessAnnotation(content.Content); //annotation child of simple extension / restriction - if (content.Content is XmlSchemaSimpleContentExtension) + if (content.Content is XmlSchemaSimpleContentExtension contentExtension) { - XmlSchemaSimpleContentExtension contentExtension = (XmlSchemaSimpleContentExtension)content.Content; if (contentExtension.BaseTypeName.IsEmpty) { SendValidationEvent(SR.Sch_MissAttribute, "base", contentExtension); @@ -1809,9 +1802,8 @@ private void PreprocessComplexType(XmlSchemaComplexType complexType, bool local) SetParent(content.Content, content); //complexcontent extension / restriction PreprocessAnnotation(content.Content); //Annotation child of extension / restriction - if (content.Content is XmlSchemaComplexContentExtension) + if (content.Content is XmlSchemaComplexContentExtension contentExtension) { - XmlSchemaComplexContentExtension contentExtension = (XmlSchemaComplexContentExtension)content.Content; if (contentExtension.BaseTypeName.IsEmpty) { SendValidationEvent(SR.Sch_MissAttribute, "base", contentExtension); @@ -2002,9 +1994,8 @@ private void PreprocessParticle(XmlSchemaParticle particle) } } } - else if (particle is XmlSchemaGroupRef) + else if (particle is XmlSchemaGroupRef groupRef) { - XmlSchemaGroupRef groupRef = (XmlSchemaGroupRef)particle; if (groupRef.RefName.IsEmpty) { SendValidationEvent(SR.Sch_MissAttribute, "ref", groupRef); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaCollectionCompiler.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaCollectionCompiler.cs index 55900a6b3269c5..a7dcc6dc35bfe8 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaCollectionCompiler.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaCollectionCompiler.cs @@ -332,12 +332,10 @@ private static void CleanupComplexType(XmlSchemaComplexType complexType) { if (complexType.ContentModel != null) { //simpleContent or complexContent - if (complexType.ContentModel is XmlSchemaSimpleContent) + if (complexType.ContentModel is XmlSchemaSimpleContent simpleContent) { - XmlSchemaSimpleContent simpleContent = (XmlSchemaSimpleContent)complexType.ContentModel; - if (simpleContent.Content is XmlSchemaSimpleContentExtension) + if (simpleContent.Content is XmlSchemaSimpleContentExtension simpleExtension) { - XmlSchemaSimpleContentExtension simpleExtension = (XmlSchemaSimpleContentExtension)simpleContent.Content; CleanupAttributes(simpleExtension.Attributes); } else @@ -537,9 +535,8 @@ private void CompileSimpleType(XmlSchemaSimpleType simpleType) simpleType.IsProcessing = true; try { - if (simpleType.Content is XmlSchemaSimpleTypeList) + if (simpleType.Content is XmlSchemaSimpleTypeList list) { - XmlSchemaSimpleTypeList list = (XmlSchemaSimpleTypeList)simpleType.Content; XmlSchemaDatatype datatype; simpleType.SetBaseSchemaType(DatatypeImplementation.AnySimpleType); if (list.ItemTypeName.IsEmpty) @@ -568,9 +565,8 @@ private void CompileSimpleType(XmlSchemaSimpleType simpleType) simpleType.SetDatatype(datatype.DeriveByList(simpleType)); simpleType.SetDerivedBy(XmlSchemaDerivationMethod.List); } - else if (simpleType.Content is XmlSchemaSimpleTypeRestriction) + else if (simpleType.Content is XmlSchemaSimpleTypeRestriction restriction) { - XmlSchemaSimpleTypeRestriction restriction = (XmlSchemaSimpleTypeRestriction)simpleType.Content; XmlSchemaDatatype datatype; if (restriction.BaseTypeName.IsEmpty) { @@ -725,9 +721,8 @@ private void CompileComplexType(XmlSchemaComplexType complexType) complexType.IsProcessing = true; if (complexType.ContentModel != null) { //simpleContent or complexContent - if (complexType.ContentModel is XmlSchemaSimpleContent) + if (complexType.ContentModel is XmlSchemaSimpleContent simpleContent) { - XmlSchemaSimpleContent simpleContent = (XmlSchemaSimpleContent)complexType.ContentModel; complexType.SetContentType(XmlSchemaContentType.TextOnly); if (simpleContent.Content is XmlSchemaSimpleContentExtension) { @@ -2264,9 +2259,8 @@ private void CompileElement(XmlSchemaElement xe) if (decl == null) { Debug.Assert(xe.ElementSchemaType != null); - if (xe.ElementSchemaType is XmlSchemaComplexType) + if (xe.ElementSchemaType is XmlSchemaComplexType complexType) { - XmlSchemaComplexType complexType = (XmlSchemaComplexType)xe.ElementSchemaType; CompileComplexType(complexType); if (complexType.ElementDecl != null) { @@ -2274,9 +2268,8 @@ private void CompileElement(XmlSchemaElement xe) // decl.LocalElements = complexType.LocalElementDecls; } } - else if (xe.ElementSchemaType is XmlSchemaSimpleType) + else if (xe.ElementSchemaType is XmlSchemaSimpleType simpleType) { - XmlSchemaSimpleType simpleType = (XmlSchemaSimpleType)xe.ElementSchemaType; CompileSimpleType(simpleType); if (simpleType.ElementDecl != null) { @@ -2382,9 +2375,8 @@ private ContentValidator CompileComplexContent(XmlSchemaComplexType complexType) } } PushComplexType(complexType); - if (particle is XmlSchemaAll) + if (particle is XmlSchemaAll all) { - XmlSchemaAll all = (XmlSchemaAll)particle; AllElementsContentValidator contentValidator = new AllElementsContentValidator(complexType.ContentType, all.Items.Count, all.MinOccurs == decimal.Zero); for (int i = 0; i < all.Items.Count; ++i) { @@ -2459,9 +2451,8 @@ private void DumpContentModelTo(StringBuilder sb, XmlSchemaParticle particle) sb.Append(((XmlSchemaAny)particle!).NamespaceList!.ToString()); sb.Append('>'); } - else if (particle is XmlSchemaAll) + else if (particle is XmlSchemaAll all) { - XmlSchemaAll all = (XmlSchemaAll)particle; sb.Append('['); bool first = true; for (int i = 0; i < all.Items.Count; ++i) @@ -2483,9 +2474,8 @@ private void DumpContentModelTo(StringBuilder sb, XmlSchemaParticle particle) } sb.Append(']'); } - else if (particle is XmlSchemaGroupBase) + else if (particle is XmlSchemaGroupBase gb) { - XmlSchemaGroupBase gb = (XmlSchemaGroupBase)particle; sb.Append('('); string delimeter = (particle is XmlSchemaChoice) ? " | " : ", "; bool first = true; @@ -2533,14 +2523,12 @@ private void DumpContentModelTo(StringBuilder sb, XmlSchemaParticle particle) private void BuildParticleContentModel(ParticleContentValidator contentValidator, XmlSchemaParticle particle) { - if (particle is XmlSchemaElement) + if (particle is XmlSchemaElement element) { - XmlSchemaElement element = (XmlSchemaElement)particle; contentValidator.AddName(element.QualifiedName, element); } - else if (particle is XmlSchemaAny) + else if (particle is XmlSchemaAny any) { - XmlSchemaAny any = (XmlSchemaAny)particle; contentValidator.AddNamespaceList(any.NamespaceList!, any); } else if (particle is XmlSchemaGroupBase) @@ -2597,9 +2585,8 @@ private void BuildParticleContentModel(ParticleContentValidator contentValidator private void CompileParticleElements(XmlSchemaComplexType complexType, XmlSchemaParticle particle) { - if (particle is XmlSchemaElement) + if (particle is XmlSchemaElement localElement) { - XmlSchemaElement localElement = (XmlSchemaElement)particle; CompileElement(localElement); if (complexType.LocalElements[localElement.QualifiedName] == null) { diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaCollectionpreProcessor.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaCollectionpreProcessor.cs index 07bf38d05f56b6..f3f002d4530e33 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaCollectionpreProcessor.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaCollectionpreProcessor.cs @@ -178,10 +178,9 @@ private void LoadExternals(XmlSchema schema, XmlSchemaCollection? xsc) for (int j = 0; j < include.Schema.Includes.Count; ++j) { XmlSchemaExternal subInc = (XmlSchemaExternal)include.Schema.Includes[j]; - if (subInc is XmlSchemaImport) + if (subInc is XmlSchemaImport subImp) { - XmlSchemaImport subImp = (XmlSchemaImport)subInc; - subUri = subImp.BaseUri ?? (subImp.Schema != null && subImp.Schema.BaseUri != null ? subImp.Schema.BaseUri : null); + subUri = subImp.BaseUri ?? subImp.Schema?.BaseUri; if (subUri != null) { if (_schemaLocations![subUri] != null) @@ -478,9 +477,8 @@ private void Preprocess(XmlSchema schema, string? targetNamespace, Compositor co for (int i = 0; i < schema.Includes.Count; ++i) { XmlSchemaExternal include = (XmlSchemaExternal)schema.Includes[i]; - if (include is XmlSchemaRedefine) + if (include is XmlSchemaRedefine redefine) { - XmlSchemaRedefine redefine = (XmlSchemaRedefine)include; if (include.Schema != null) { PreprocessRedefine(redefine); @@ -543,39 +541,33 @@ private void Preprocess(XmlSchema schema, string? targetNamespace, Compositor co PreprocessAttribute(attribute); AddToTable(schema.Attributes, attribute.QualifiedName, attribute); } - else if (schema.Items[i] is XmlSchemaAttributeGroup) + else if (schema.Items[i] is XmlSchemaAttributeGroup attributeGroup) { - XmlSchemaAttributeGroup attributeGroup = (XmlSchemaAttributeGroup)schema.Items[i]; PreprocessAttributeGroup(attributeGroup); AddToTable(schema.AttributeGroups, attributeGroup.QualifiedName, attributeGroup); } - else if (schema.Items[i] is XmlSchemaComplexType) + else if (schema.Items[i] is XmlSchemaComplexType complexType) { - XmlSchemaComplexType complexType = (XmlSchemaComplexType)schema.Items[i]; PreprocessComplexType(complexType, false); AddToTable(schema.SchemaTypes, complexType.QualifiedName, complexType); } - else if (schema.Items[i] is XmlSchemaSimpleType) + else if (schema.Items[i] is XmlSchemaSimpleType simpleType) { - XmlSchemaSimpleType simpleType = (XmlSchemaSimpleType)schema.Items[i]; PreprocessSimpleType(simpleType, false); AddToTable(schema.SchemaTypes, simpleType.QualifiedName, simpleType); } - else if (schema.Items[i] is XmlSchemaElement) + else if (schema.Items[i] is XmlSchemaElement element) { - XmlSchemaElement element = (XmlSchemaElement)schema.Items[i]; PreprocessElement(element); AddToTable(schema.Elements, element.QualifiedName, element); } - else if (schema.Items[i] is XmlSchemaGroup) + else if (schema.Items[i] is XmlSchemaGroup group) { - XmlSchemaGroup group = (XmlSchemaGroup)schema.Items[i]; PreprocessGroup(group); AddToTable(schema.Groups, group.QualifiedName, group); } - else if (schema.Items[i] is XmlSchemaNotation) + else if (schema.Items[i] is XmlSchemaNotation notation) { - XmlSchemaNotation notation = (XmlSchemaNotation)schema.Items[i]; PreprocessNotation(notation); AddToTable(schema.Notations, notation.QualifiedName, notation); } @@ -620,9 +612,8 @@ private void PreprocessRedefine(XmlSchemaRedefine redefine) } } } - else if (redefine.Items[i] is XmlSchemaAttributeGroup) + else if (redefine.Items[i] is XmlSchemaAttributeGroup attributeGroup) { - XmlSchemaAttributeGroup attributeGroup = (XmlSchemaAttributeGroup)redefine.Items[i]; PreprocessAttributeGroup(attributeGroup); if (redefine.AttributeGroups[attributeGroup.QualifiedName] != null) { @@ -642,9 +633,8 @@ private void PreprocessRedefine(XmlSchemaRedefine redefine) } } } - else if (redefine.Items[i] is XmlSchemaComplexType) + else if (redefine.Items[i] is XmlSchemaComplexType complexType) { - XmlSchemaComplexType complexType = (XmlSchemaComplexType)redefine.Items[i]; PreprocessComplexType(complexType, false); if (redefine.SchemaTypes[complexType.QualifiedName] != null) { @@ -672,9 +662,8 @@ private void PreprocessRedefine(XmlSchemaRedefine redefine) } } } - else if (redefine.Items[i] is XmlSchemaSimpleType) + else if (redefine.Items[i] is XmlSchemaSimpleType simpleType) { - XmlSchemaSimpleType simpleType = (XmlSchemaSimpleType)redefine.Items[i]; PreprocessSimpleType(simpleType, false); if (redefine.SchemaTypes[simpleType.QualifiedName] != null) { @@ -1148,9 +1137,8 @@ private void PreprocessIdentityConstraint(XmlSchemaIdentityConstraint constraint SendValidationEvent(SR.Sch_IdConstraintNoFields, constraint); valid = false; } - if (constraint is XmlSchemaKeyref) + if (constraint is XmlSchemaKeyref keyref) { - XmlSchemaKeyref keyref = (XmlSchemaKeyref)constraint; if (keyref.Refer.IsEmpty) { SendValidationEvent(SR.Sch_IdConstraintNoRefer, constraint); @@ -1224,9 +1212,8 @@ private void PreprocessSimpleType(XmlSchemaSimpleType simpleType, bool local) { SendValidationEvent(SR.Sch_NoSimpleTypeContent, simpleType); } - else if (simpleType.Content is XmlSchemaSimpleTypeRestriction) + else if (simpleType.Content is XmlSchemaSimpleTypeRestriction restriction) { - XmlSchemaSimpleTypeRestriction restriction = (XmlSchemaSimpleTypeRestriction)simpleType.Content; //SetParent SetParent(restriction, simpleType); for (int i = 0; i < restriction.Facets.Count; ++i) @@ -1256,9 +1243,8 @@ private void PreprocessSimpleType(XmlSchemaSimpleType simpleType, bool local) PreprocessAnnotation(restriction); //set parent of annotation child of simple type restriction ValidateIdAttribute(restriction); } - else if (simpleType.Content is XmlSchemaSimpleTypeList) + else if (simpleType.Content is XmlSchemaSimpleTypeList list) { - XmlSchemaSimpleTypeList list = (XmlSchemaSimpleTypeList)simpleType.Content; SetParent(list, simpleType); if (list.ItemType != null) @@ -1402,9 +1388,8 @@ private void PreprocessComplexType(XmlSchemaComplexType complexType, bool local) SetParent(content.Content, content); //simplecontent extension / restriction PreprocessAnnotation(content.Content); //annotation child of simple extension / restriction - if (content.Content is XmlSchemaSimpleContentExtension) + if (content.Content is XmlSchemaSimpleContentExtension contentExtension) { - XmlSchemaSimpleContentExtension contentExtension = (XmlSchemaSimpleContentExtension)content.Content; if (contentExtension.BaseTypeName.IsEmpty) { SendValidationEvent(SR.Sch_MissAttribute, "base", contentExtension); @@ -1461,9 +1446,8 @@ private void PreprocessComplexType(XmlSchemaComplexType complexType, bool local) SetParent(content.Content, content); //complexcontent extension / restriction PreprocessAnnotation(content.Content); //Annotation child of extension / restriction - if (content.Content is XmlSchemaComplexContentExtension) + if (content.Content is XmlSchemaComplexContentExtension contentExtension) { - XmlSchemaComplexContentExtension contentExtension = (XmlSchemaComplexContentExtension)content.Content; if (contentExtension.BaseTypeName.IsEmpty) { SendValidationEvent(SR.Sch_MissAttribute, "base", contentExtension); @@ -1657,9 +1641,8 @@ private void PreprocessParticle(XmlSchemaParticle particle) } } } - else if (particle is XmlSchemaGroupRef) + else if (particle is XmlSchemaGroupRef groupRef) { - XmlSchemaGroupRef groupRef = (XmlSchemaGroupRef)particle; if (groupRef.RefName.IsEmpty) { SendValidationEvent(SR.Sch_MissAttribute, "ref", groupRef); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaSetCompiler.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaSetCompiler.cs index 7de4c7d56ef586..1a26274cb86d1e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaSetCompiler.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/SchemaSetCompiler.cs @@ -326,12 +326,10 @@ private void CleanupComplexType(XmlSchemaComplexType complexType) if (complexType.ContentModel != null) { //simpleContent or complexContent - if (complexType.ContentModel is XmlSchemaSimpleContent) + if (complexType.ContentModel is XmlSchemaSimpleContent simpleContent) { - XmlSchemaSimpleContent simpleContent = (XmlSchemaSimpleContent)complexType.ContentModel; - if (simpleContent.Content is XmlSchemaSimpleContentExtension) + if (simpleContent.Content is XmlSchemaSimpleContentExtension simpleExtension) { - XmlSchemaSimpleContentExtension simpleExtension = (XmlSchemaSimpleContentExtension)simpleContent.Content; CleanupAttributes(simpleExtension.Attributes); } else @@ -343,9 +341,8 @@ private void CleanupComplexType(XmlSchemaComplexType complexType) else { // complexType.ContentModel is XmlSchemaComplexContent XmlSchemaComplexContent complexContent = (XmlSchemaComplexContent)complexType.ContentModel; - if (complexContent.Content is XmlSchemaComplexContentExtension) + if (complexContent.Content is XmlSchemaComplexContentExtension complexExtension) { - XmlSchemaComplexContentExtension complexExtension = (XmlSchemaComplexContentExtension)complexContent.Content; CleanupParticle(complexExtension.Particle); CleanupAttributes(complexExtension.Attributes); } @@ -637,9 +634,8 @@ private void CompileSimpleType(XmlSchemaSimpleType simpleType) simpleType.IsProcessing = true; try { - if (simpleType.Content is XmlSchemaSimpleTypeList) + if (simpleType.Content is XmlSchemaSimpleTypeList list) { - XmlSchemaSimpleTypeList list = (XmlSchemaSimpleTypeList)simpleType.Content; XmlSchemaDatatype datatype; simpleType.SetBaseSchemaType(DatatypeImplementation.AnySimpleType); if (list.ItemTypeName.IsEmpty) @@ -670,9 +666,8 @@ private void CompileSimpleType(XmlSchemaSimpleType simpleType) simpleType.SetDatatype(datatype.DeriveByList(simpleType)); simpleType.SetDerivedBy(XmlSchemaDerivationMethod.List); } - else if (simpleType.Content is XmlSchemaSimpleTypeRestriction) + else if (simpleType.Content is XmlSchemaSimpleTypeRestriction restriction) { - XmlSchemaSimpleTypeRestriction restriction = (XmlSchemaSimpleTypeRestriction)simpleType.Content; XmlSchemaDatatype datatype; if (restriction.BaseTypeName.IsEmpty) { @@ -832,9 +827,8 @@ private void CompileComplexType(XmlSchemaComplexType complexType) { if (complexType.ContentModel != null) { //simpleContent or complexContent - if (complexType.ContentModel is XmlSchemaSimpleContent) + if (complexType.ContentModel is XmlSchemaSimpleContent simpleContent) { - XmlSchemaSimpleContent simpleContent = (XmlSchemaSimpleContent)complexType.ContentModel; complexType.SetContentType(XmlSchemaContentType.TextOnly); if (simpleContent.Content is XmlSchemaSimpleContentExtension) { @@ -1551,14 +1545,12 @@ private bool IsValidRestriction(XmlSchemaParticle derivedParticle, XmlSchemaPart { return false; } - if (derivedParticle is XmlSchemaElement) + if (derivedParticle is XmlSchemaElement derivedElem) { //check for derived element being head of substitutionGroup - XmlSchemaElement derivedElem = (XmlSchemaElement)derivedParticle; derivedParticle = CannonicalizeElement(derivedElem); } - if (baseParticle is XmlSchemaElement) + if (baseParticle is XmlSchemaElement baseElem) { - XmlSchemaElement baseElem = (XmlSchemaElement)baseParticle; XmlSchemaParticle newBaseParticle; newBaseParticle = CannonicalizeElement(baseElem); if (newBaseParticle is XmlSchemaChoice) @@ -2743,9 +2735,8 @@ private void CompileElement(XmlSchemaElement xe) if (decl == null) { Debug.Assert(xe.ElementSchemaType != null); - if (xe.ElementSchemaType is XmlSchemaComplexType) + if (xe.ElementSchemaType is XmlSchemaComplexType complexType) { - XmlSchemaComplexType complexType = (XmlSchemaComplexType)xe.ElementSchemaType; CompileComplexType(complexType); if (complexType.ElementDecl != null) { @@ -2753,9 +2744,8 @@ private void CompileElement(XmlSchemaElement xe) // decl.LocalElements = complexType.LocalElementDecls; } } - else if (xe.ElementSchemaType is XmlSchemaSimpleType) + else if (xe.ElementSchemaType is XmlSchemaSimpleType simpleType) { - XmlSchemaSimpleType simpleType = (XmlSchemaSimpleType)xe.ElementSchemaType; CompileSimpleType(simpleType); if (simpleType.ElementDecl != null) { @@ -2871,9 +2861,8 @@ private ContentValidator CompileComplexContent(XmlSchemaComplexType complexType) } } PushComplexType(complexType); - if (particle is XmlSchemaAll) + if (particle is XmlSchemaAll all) { - XmlSchemaAll all = (XmlSchemaAll)particle; AllElementsContentValidator contentValidator = new AllElementsContentValidator(complexType.ContentType, all.Items.Count, all.MinOccurs == decimal.Zero); for (int i = 0; i < all.Items.Count; ++i) { @@ -2931,9 +2920,8 @@ private ContentValidator CompileComplexContent(XmlSchemaComplexType complexType) private bool BuildParticleContentModel(ParticleContentValidator contentValidator, XmlSchemaParticle particle) { bool hasWildCard = false; - if (particle is XmlSchemaElement) + if (particle is XmlSchemaElement element) { - XmlSchemaElement element = (XmlSchemaElement)particle; contentValidator.AddName(element.QualifiedName, element); } else if (particle is XmlSchemaAny) @@ -2996,9 +2984,8 @@ private bool BuildParticleContentModel(ParticleContentValidator contentValidator private void CompileParticleElements(XmlSchemaComplexType complexType, XmlSchemaParticle particle) { - if (particle is XmlSchemaElement) + if (particle is XmlSchemaElement localElement) { - XmlSchemaElement localElement = (XmlSchemaElement)particle; CompileElement(localElement); if (complexType.LocalElements[localElement.QualifiedName] == null) { @@ -3025,9 +3012,8 @@ private void CompileParticleElements(XmlSchemaComplexType complexType, XmlSchema private void CompileParticleElements(XmlSchemaParticle particle) { //For checking redefined group particle derivation - if (particle is XmlSchemaElement) + if (particle is XmlSchemaElement localElement) { - XmlSchemaElement localElement = (XmlSchemaElement)particle; CompileElement(localElement); } else if (particle is XmlSchemaGroupBase) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidator.cs index 25bfa8dd5303f8..74c64a649c11ef 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Schema/XmlSchemaValidator.cs @@ -1614,9 +1614,8 @@ private void AddXsiAttributes(ArrayList attList) { if (_isRoot && _partialValidationType != null) { - if (_partialValidationType is XmlSchemaElement) + if (_partialValidationType is XmlSchemaElement element) { - XmlSchemaElement element = (XmlSchemaElement)_partialValidationType; if (elementName.Equals(element.QualifiedName)) { elementDecl = element.ElementDecl; @@ -1626,9 +1625,8 @@ private void AddXsiAttributes(ArrayList attList) SendValidationEvent(SR.Sch_SchemaElementNameMismatch, elementName.ToString(), element.QualifiedName.ToString()); } } - else if (_partialValidationType is XmlSchemaType) + else if (_partialValidationType is XmlSchemaType type) { //Element name is wildcard - XmlSchemaType type = (XmlSchemaType)_partialValidationType; elementDecl = type.ElementDecl; } else diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/CodeGenerator.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/CodeGenerator.cs index 7618fc1a9ca8b2..d0cfe8cb6b4dc6 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/CodeGenerator.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/CodeGenerator.cs @@ -537,9 +537,8 @@ internal Type LoadMember(object obj, MemberInfo memberInfo) internal Type LoadMember(MemberInfo memberInfo) { Type? memberType; - if (memberInfo is FieldInfo) + if (memberInfo is FieldInfo fieldInfo) { - FieldInfo fieldInfo = (FieldInfo)memberInfo; memberType = fieldInfo.FieldType; if (fieldInfo.IsStatic) { @@ -576,9 +575,8 @@ internal Type LoadMember(MemberInfo memberInfo) internal Type LoadMemberAddress(MemberInfo memberInfo) { Type? memberType; - if (memberInfo is FieldInfo) + if (memberInfo is FieldInfo fieldInfo) { - FieldInfo fieldInfo = (FieldInfo)memberInfo; memberType = fieldInfo.FieldType; if (fieldInfo.IsStatic) { @@ -618,9 +616,8 @@ internal Type LoadMemberAddress(MemberInfo memberInfo) [RequiresUnreferencedCode("calls GetPropertyMethodFromBaseType")] internal void StoreMember(MemberInfo memberInfo) { - if (memberInfo is FieldInfo) + if (memberInfo is FieldInfo fieldInfo) { - FieldInfo fieldInfo = (FieldInfo)memberInfo; if (fieldInfo.IsStatic) { _ilGen!.Emit(OpCodes.Stsfld, fieldInfo); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/ImportContext.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/ImportContext.cs index 9499f3243a041c..aac4e7ca97eb2b 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/ImportContext.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/ImportContext.cs @@ -328,9 +328,8 @@ internal void Depends(XmlSchemaObject? item, ArrayList refs) XmlSchemaParticle? particle = null; XmlSchemaObjectCollection? attributes = null; - if (item is XmlSchemaComplexType) + if (item is XmlSchemaComplexType ct) { - XmlSchemaComplexType ct = (XmlSchemaComplexType)item; if (ct.ContentModel != null) { XmlSchemaContent? content = ct.ContentModel.Content; @@ -339,27 +338,24 @@ internal void Depends(XmlSchemaObject? item, ArrayList refs) baseName = ((XmlSchemaComplexContentRestriction)content).BaseTypeName; attributes = ((XmlSchemaComplexContentRestriction)content).Attributes; } - else if (content is XmlSchemaSimpleContentRestriction) + else if (content is XmlSchemaSimpleContentRestriction restriction) { - XmlSchemaSimpleContentRestriction restriction = (XmlSchemaSimpleContentRestriction)content; if (restriction.BaseType != null) baseType = restriction.BaseType; else baseName = restriction.BaseTypeName; attributes = restriction.Attributes; } - else if (content is XmlSchemaComplexContentExtension) + else if (content is XmlSchemaComplexContentExtension complex) { - XmlSchemaComplexContentExtension extension = (XmlSchemaComplexContentExtension)content; - attributes = extension.Attributes; - particle = extension.Particle; - baseName = extension.BaseTypeName; + attributes = complex.Attributes; + particle = complex.Particle; + baseName = complex.BaseTypeName; } - else if (content is XmlSchemaSimpleContentExtension) + else if (content is XmlSchemaSimpleContentExtension simple) { - XmlSchemaSimpleContentExtension extension = (XmlSchemaSimpleContentExtension)content; - attributes = extension.Attributes; - baseName = extension.BaseTypeName; + attributes = simple.Attributes; + baseName = simple.BaseTypeName; } } else @@ -367,9 +363,8 @@ internal void Depends(XmlSchemaObject? item, ArrayList refs) attributes = ct.Attributes; particle = ct.Particle; } - if (particle is XmlSchemaGroupRef) + if (particle is XmlSchemaGroupRef refGroup) { - XmlSchemaGroupRef refGroup = (XmlSchemaGroupRef)particle; particle = ((XmlSchemaGroup)_schemas.Find(refGroup.RefName, typeof(XmlSchemaGroup), false)!).Particle; } else if (particle is XmlSchemaGroupBase) @@ -377,18 +372,16 @@ internal void Depends(XmlSchemaObject? item, ArrayList refs) particle = (XmlSchemaGroupBase)particle; } } - else if (item is XmlSchemaSimpleType) + else if (item is XmlSchemaSimpleType simpleType) { - XmlSchemaSimpleType simpleType = (XmlSchemaSimpleType)item; XmlSchemaSimpleTypeContent? content = simpleType.Content; if (content is XmlSchemaSimpleTypeRestriction) { baseType = ((XmlSchemaSimpleTypeRestriction)content).BaseType; baseName = ((XmlSchemaSimpleTypeRestriction)content).BaseTypeName; } - else if (content is XmlSchemaSimpleTypeList) + else if (content is XmlSchemaSimpleTypeList list) { - XmlSchemaSimpleTypeList list = (XmlSchemaSimpleTypeList)content; if (list.ItemTypeName != null && !list.ItemTypeName.IsEmpty) baseName = list.ItemTypeName; if (list.ItemType != null) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SchemaObjectWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SchemaObjectWriter.cs index 2d9e6b10224eac..7beb27220cc2b3 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SchemaObjectWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SchemaObjectWriter.cs @@ -95,23 +95,20 @@ internal static XmlQualifiedName NameOf(XmlSchemaObject? o) { return ((XmlSchemaNotation)o).QualifiedName; } - else if (o is XmlSchemaSequence) + else if (o is XmlSchemaSequence s) { - XmlSchemaSequence s = (XmlSchemaSequence)o; if (s.Items.Count == 0) return new XmlQualifiedName(".sequence", Namespace(o)); return NameOf(s.Items[0]); } - else if (o is XmlSchemaAll) + else if (o is XmlSchemaAll a) { - XmlSchemaAll a = (XmlSchemaAll)o; if (a.Items.Count == 0) return new XmlQualifiedName(".all", Namespace(o)); return NameOf(a.Items); } - else if (o is XmlSchemaChoice) + else if (o is XmlSchemaChoice c) { - XmlSchemaChoice c = (XmlSchemaChoice)o; if (c.Items.Count == 0) return new XmlQualifiedName(".choice", Namespace(o)); return NameOf(c.Items); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapReflectionImporter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapReflectionImporter.cs index cb81d6e8c0c095..ac42ce01c5cedd 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapReflectionImporter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/SoapReflectionImporter.cs @@ -508,9 +508,8 @@ private void SetArrayMappingType(ArrayMapping mapping) TypeMapping? existingMapping = (TypeMapping?)_types[uniqueName, ns]; while (existingMapping != null) { - if (existingMapping is ArrayMapping) + if (existingMapping is ArrayMapping arrayMapping) { - ArrayMapping arrayMapping = (ArrayMapping)existingMapping; if (AccessorMapping.ElementsMatch(arrayMapping.Elements, mapping.Elements)) { break; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Types.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Types.cs index 5f0ee4a7931f65..2289e3cdaf57c4 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Types.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/Types.cs @@ -1379,9 +1379,8 @@ internal static PropertyInfo GetDefaultIndexer( { for (int i = 0; i < defaultMembers.Length; i++) { - if (defaultMembers[i] is PropertyInfo) + if (defaultMembers[i] is PropertyInfo defaultProp) { - PropertyInfo defaultProp = (PropertyInfo)defaultMembers[i]; if (defaultProp.DeclaringType != t) continue; if (!defaultProp.CanRead) continue; MethodInfo getMethod = defaultProp.GetMethod!; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlAttributes.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlAttributes.cs index 0a0cbd06498674..d34aa9fd4de81d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlAttributes.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlAttributes.cs @@ -95,9 +95,8 @@ public XmlAttributes(ICustomAttributeProvider provider) { _xmlArrayItems.Add((XmlArrayItemAttribute)attrs[i]); } - else if (attrs[i] is XmlAnyElementAttribute) + else if (attrs[i] is XmlAnyElementAttribute any) { - XmlAnyElementAttribute any = (XmlAnyElementAttribute)attrs[i]; if ((any.Name == null || any.Name.Length == 0) && any.GetNamespaceSpecified() && any.Namespace == null) { // ignore duplicate wildcards diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlReflectionImporter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlReflectionImporter.cs index 9d6998aba7e72f..6f4cdfe205a4b4 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlReflectionImporter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlReflectionImporter.cs @@ -1067,9 +1067,8 @@ private void SetArrayMappingType(ArrayMapping mapping, string? defaultNs, Type t TypeMapping? existingMapping = (TypeMapping?)_types[uniqueName, ns]; while (existingMapping != null) { - if (existingMapping is ArrayMapping) + if (existingMapping is ArrayMapping arrayMapping) { - ArrayMapping arrayMapping = (ArrayMapping)existingMapping; if (AccessorMapping.ElementsMatch(arrayMapping.Elements, mapping.Elements)) { break; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemaExporter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemaExporter.cs index 69a156058d0d5d..c3b75d73ad7b3e 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemaExporter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemaExporter.cs @@ -119,9 +119,8 @@ private static bool IsAnyType(XmlSchemaType schemaType, bool mixed, bool unbound { if (complexType.IsMixed != mixed) return false; - if (complexType.Particle is XmlSchemaSequence) + if (complexType.Particle is XmlSchemaSequence sequence) { - XmlSchemaSequence sequence = (XmlSchemaSequence)complexType.Particle; if (sequence.Items.Count == 1 && sequence.Items[0] is XmlSchemaAny) { XmlSchemaAny any = (XmlSchemaAny)sequence.Items[0]; @@ -286,16 +285,14 @@ private void AddSchemaItem(XmlSchemaObject item, string? ns, string? referencing schema = AddSchema(ns); } - if (item is XmlSchemaElement) + if (item is XmlSchemaElement e) { - XmlSchemaElement e = (XmlSchemaElement)item; if (e.Form == XmlSchemaForm.Unqualified) throw new InvalidOperationException(SR.Format(SR.XmlIllegalForm, e.Name)); e.Form = XmlSchemaForm.None; } - else if (item is XmlSchemaAttribute) + else if (item is XmlSchemaAttribute a) { - XmlSchemaAttribute a = (XmlSchemaAttribute)item; if (a.Form == XmlSchemaForm.Unqualified) throw new InvalidOperationException(SR.Format(SR.XmlIllegalForm, a.Name)); a.Form = XmlSchemaForm.None; @@ -344,9 +341,8 @@ private bool SchemaContainsItem(XmlSchemaObject item, string ns) { foreach (object item in schema.Includes) { - if (item is XmlSchemaImport) + if (item is XmlSchemaImport import) { - XmlSchemaImport import = (XmlSchemaImport)item; if (NamespacesEqual(import.Namespace, ns)) { return import; @@ -380,9 +376,8 @@ private void ExportElementMapping(XmlSchemaElement element, Mapping mapping, str { if (mapping is ArrayMapping) ExportArrayMapping((ArrayMapping)mapping, ns, element); - else if (mapping is PrimitiveMapping) + else if (mapping is PrimitiveMapping pm) { - PrimitiveMapping pm = (PrimitiveMapping)mapping; if (pm.IsAnonymousType) { element.SchemaType = ExportAnonymousPrimitiveMapping(pm); @@ -723,9 +718,8 @@ private void ExportAttributeAccessor(XmlSchemaComplexType type, AttributeAccesso XmlSchemaComplexContentExtension extension = (XmlSchemaComplexContentExtension)content; extension.AnyAttribute = new XmlSchemaAnyAttribute(); } - else if (content is XmlSchemaComplexContentRestriction) + else if (content is XmlSchemaComplexContentRestriction restriction) { - XmlSchemaComplexContentRestriction restriction = (XmlSchemaComplexContentRestriction)content; restriction.AnyAttribute = new XmlSchemaAnyAttribute(); } else if (type.ContentModel.Content is XmlSchemaSimpleContentExtension) @@ -772,9 +766,8 @@ private void ExportAttributeAccessor(XmlSchemaComplexType type, AttributeAccesso attributes.Add(refAttribute); AddSchemaImport(accessor.Namespace, ns); } - if (accessor.Mapping is PrimitiveMapping) + if (accessor.Mapping is PrimitiveMapping pm) { - PrimitiveMapping pm = (PrimitiveMapping)accessor.Mapping; if (pm.IsList) { // create local simple type for the list-like attributes @@ -884,10 +877,8 @@ private void ExportElementAccessor(XmlSchemaGroupBase group, ElementAccessor acc if (value == null || value == DBNull.Value) return null; - if (mapping is EnumMapping) + if (mapping is EnumMapping em) { - EnumMapping em = (EnumMapping)mapping; - #if DEBUG // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe if (value.GetType() != typeof(string)) throw new InvalidOperationException(SR.Format(SR.XmlInternalErrorDetails, SR.Format(SR.XmlInvalidDefaultValue, value, value.GetType().FullName))); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemaImporter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemaImporter.cs index 7c7c3b6648c086..02356883d39fe4 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemaImporter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemaImporter.cs @@ -384,9 +384,8 @@ internal override void ImportDerivedTypes(XmlQualifiedName baseName) XmlSchemas.Preprocess(schema); foreach (object item in schema.SchemaTypes.Values) { - if (item is XmlSchemaType) + if (item is XmlSchemaType type) { - XmlSchemaType type = (XmlSchemaType)item; if (type.DerivedFrom == baseName && TypesInUse[type.Name, schema.TargetNamespace] == null) { ImportType(type.QualifiedName, typeof(TypeMapping), null, TypeFlags.CanBeElementValue, false); @@ -697,19 +696,17 @@ private TypeItems GetTypeItems(XmlSchemaType type) if (ct.ContentModel != null) { XmlSchemaContent? content = ct.ContentModel.Content; - if (content is XmlSchemaComplexContentExtension) + if (content is XmlSchemaComplexContentExtension complex) { - XmlSchemaComplexContentExtension extension = (XmlSchemaComplexContentExtension)content; - items.Attributes = extension.Attributes; - items.AnyAttribute = extension.AnyAttribute; - particle = extension.Particle; + items.Attributes = complex.Attributes; + items.AnyAttribute = complex.AnyAttribute; + particle = complex.Particle; } - else if (content is XmlSchemaSimpleContentExtension) + else if (content is XmlSchemaSimpleContentExtension simple) { - XmlSchemaSimpleContentExtension extension = (XmlSchemaSimpleContentExtension)content; - items.Attributes = extension.Attributes; - items.AnyAttribute = extension.AnyAttribute; - items.baseSimpleType = extension.BaseTypeName; + items.Attributes = simple.Attributes; + items.AnyAttribute = simple.AnyAttribute; + items.baseSimpleType = simple.BaseTypeName; } } else @@ -718,9 +715,8 @@ private TypeItems GetTypeItems(XmlSchemaType type) items.AnyAttribute = ct.AnyAttribute; particle = ct.Particle; } - if (particle is XmlSchemaGroupRef) + if (particle is XmlSchemaGroupRef refGroup) { - XmlSchemaGroupRef refGroup = (XmlSchemaGroupRef)particle; items.Particle = FindGroup(refGroup.RefName).Particle; items.IsUnbounded = particle.IsMultipleOccurrence; } @@ -898,9 +894,8 @@ private bool GatherGroupChoices(XmlSchemaGroup group, NameTable choiceElements, [RequiresUnreferencedCode("Calls ImportAny")] private bool GatherGroupChoices(XmlSchemaParticle? particle, NameTable choiceElements, string identifier, string? ns, ref bool needExplicitOrder, bool allowDuplicates) { - if (particle is XmlSchemaGroupRef) + if (particle is XmlSchemaGroupRef refGroup) { - XmlSchemaGroupRef refGroup = (XmlSchemaGroupRef)particle; if (!refGroup.RefName.IsEmpty) { AddReference(refGroup.RefName, GroupsInUse, SR.XmlCircularGroupReference); @@ -912,9 +907,8 @@ private bool GatherGroupChoices(XmlSchemaParticle? particle, NameTable choiceEle RemoveReference(refGroup.RefName, GroupsInUse); } } - else if (particle is XmlSchemaGroupBase) + else if (particle is XmlSchemaGroupBase group) { - XmlSchemaGroupBase group = (XmlSchemaGroupBase)particle; bool groupRepeats = group.IsMultipleOccurrence; XmlSchemaAny? any = null; bool duplicateElements = false; @@ -937,9 +931,8 @@ private bool GatherGroupChoices(XmlSchemaParticle? particle, NameTable choiceEle any = (XmlSchemaAny)item; } } - else if (item is XmlSchemaElement) + else if (item is XmlSchemaElement element) { - XmlSchemaElement element = (XmlSchemaElement)item; XmlSchemaElement? headElement = GetTopLevelElement(element); if (headElement != null) { @@ -1002,9 +995,8 @@ private static void AddScopeElements(INameScope? scope, ElementAccessor[] elemen [RequiresUnreferencedCode("calls ImportChoiceGroup")] private void ImportGroupMembers(XmlSchemaParticle? particle, string identifier, CodeIdentifiers members, CodeIdentifiers membersScope, INameScope elementsScope, string? ns, bool groupRepeats, ref bool mixed, ref bool needExplicitOrder, bool allowDuplicates, bool allowUnboundedElements) { - if (particle is XmlSchemaGroupRef) + if (particle is XmlSchemaGroupRef refGroup) { - XmlSchemaGroupRef refGroup = (XmlSchemaGroupRef)particle; if (!refGroup.RefName.IsEmpty) { AddReference(refGroup.RefName, GroupsInUse, SR.XmlCircularGroupReference); @@ -1012,10 +1004,8 @@ private void ImportGroupMembers(XmlSchemaParticle? particle, string identifier, RemoveReference(refGroup.RefName, GroupsInUse); } } - else if (particle is XmlSchemaGroupBase) + else if (particle is XmlSchemaGroupBase group) { - XmlSchemaGroupBase group = (XmlSchemaGroupBase)particle; - if (group.IsMultipleOccurrence) groupRepeats = true; @@ -1061,9 +1051,8 @@ private XmlSchemaElement[] GetEquivalentElements(XmlSchemaElement element) for (int j = 0; j < schema.Items.Count; j++) { object item = schema.Items[j]; - if (item is XmlSchemaElement) + if (item is XmlSchemaElement equivalentElement) { - XmlSchemaElement equivalentElement = (XmlSchemaElement)item; if (!equivalentElement.IsAbstract && equivalentElement.SubstitutionGroup.Namespace == schema.TargetNamespace && equivalentElement.SubstitutionGroup.Name == element.Name) @@ -1269,9 +1258,8 @@ private ElementAccessor[] ImportAny(XmlSchemaAny any, bool makeElement, string? arrayMapping.TypeName = identifier; arrayMapping.Namespace = ns; - if (item is XmlSchemaChoice) + if (item is XmlSchemaChoice choice) { - XmlSchemaChoice choice = (XmlSchemaChoice)item; if (!choice.IsMultipleOccurrence) return null; bool needExplicitOrder = false; @@ -1506,9 +1494,8 @@ private static bool KeepXmlnsDeclarations(XmlSchemaType type, out string? xmlnsM { foreach (XmlNode? node in nodes) { - if (node is XmlElement) + if (node is XmlElement e) { - XmlElement e = (XmlElement)node; if (e.Name == "keepNamespaceDeclarations") { if (e.LastNode is XmlText) @@ -1651,9 +1638,8 @@ private AttributeAccessor ImportSpecialAttribute(XmlQualifiedName name, string i if (mapping != null) return mapping; - if (dataType.Content is XmlSchemaSimpleTypeRestriction) + if (dataType.Content is XmlSchemaSimpleTypeRestriction restriction) { - XmlSchemaSimpleTypeRestriction restriction = (XmlSchemaSimpleTypeRestriction)dataType.Content; foreach (object o in restriction.Facets) { if (o is XmlSchemaEnumerationFacet) @@ -1676,10 +1662,9 @@ private AttributeAccessor ImportSpecialAttribute(XmlQualifiedName name, string i } else if (dataType.Content is XmlSchemaSimpleTypeList || dataType.Content is XmlSchemaSimpleTypeUnion) { - if (dataType.Content is XmlSchemaSimpleTypeList) + // check if we have enumeration list + if (dataType.Content is XmlSchemaSimpleTypeList list) { - // check if we have enumeration list - XmlSchemaSimpleTypeList list = (XmlSchemaSimpleTypeList)dataType.Content; if (list.ItemType != null) { mapping = ImportDataType(list.ItemType, typeNs, identifier, null, flags, true); @@ -1733,9 +1718,8 @@ private AttributeAccessor ImportSpecialAttribute(XmlQualifiedName name, string i CodeIdentifiers constants = new CodeIdentifiers(); XmlSchemaSimpleTypeContent? content = dataType.Content; - if (content is XmlSchemaSimpleTypeRestriction) + if (content is XmlSchemaSimpleTypeRestriction restriction) { - XmlSchemaSimpleTypeRestriction restriction = (XmlSchemaSimpleTypeRestriction)content; for (int i = 0; i < restriction.Facets.Count; i++) { object facet = restriction.Facets[i]; @@ -1860,9 +1844,8 @@ internal static XmlQualifiedName BaseTypeName(XmlSchemaSimpleType dataType) { return ((XmlSchemaSimpleTypeRestriction)content).BaseTypeName; } - else if (content is XmlSchemaSimpleTypeList) + else if (content is XmlSchemaSimpleTypeList list) { - XmlSchemaSimpleTypeList list = (XmlSchemaSimpleTypeList)content; if (list.ItemTypeName != null && !list.ItemTypeName.IsEmpty) return list.ItemTypeName; if (list.ItemType != null) diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemas.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemas.cs index d47f7384f8a847..239f647073a23d 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemas.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSchemas.cs @@ -324,9 +324,8 @@ public static bool IsDataSet(XmlSchema schema) { foreach (XmlSchemaObject o in schema.Items) { - if (o is XmlSchemaElement) + if (o is XmlSchemaElement e) { - XmlSchemaElement e = (XmlSchemaElement)o; if (e.UnhandledAttributes != null) { foreach (XmlAttribute a in e.UnhandledAttributes) @@ -491,9 +490,8 @@ internal static XmlQualifiedName GetParentName(XmlSchemaObject item) { while (item.Parent != null) { - if (item.Parent is XmlSchemaType) + if (item.Parent is XmlSchemaType type) { - XmlSchemaType type = (XmlSchemaType)item.Parent; if (type.Name != null && type.Name.Length != 0) { return type.QualifiedName; @@ -536,9 +534,8 @@ internal static XmlQualifiedName GetParentName(XmlSchemaObject item) { item = SR.Format(SR.XmlSchemaNamedItem, ns, "group", ((XmlSchemaGroup)o).Name, details); } - else if (o is XmlSchemaElement) + else if (o is XmlSchemaElement e) { - XmlSchemaElement e = ((XmlSchemaElement)o); if (e.Name == null || e.Name.Length == 0) { XmlQualifiedName parentName = XmlSchemas.GetParentName(o); @@ -558,9 +555,8 @@ internal static XmlQualifiedName GetParentName(XmlSchemaObject item) { item = SR.Format(SR.XmlSchemaNamedItem, ns, "attributeGroup", ((XmlSchemaAttributeGroup)o).Name, details); } - else if (o is XmlSchemaAttribute) + else if (o is XmlSchemaAttribute a) { - XmlSchemaAttribute a = ((XmlSchemaAttribute)o); if (a.Name == null || a.Name.Length == 0) { XmlQualifiedName parentName = XmlSchemas.GetParentName(o); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReader.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReader.cs index e9a9a7a997e73b..f5f4dfbb2183e9 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReader.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReader.cs @@ -1252,9 +1252,8 @@ private void UnknownNode(XmlNode? unknownNode, object? o, string? qnames) private void GetCurrentPosition(out int lineNumber, out int linePosition) { - if (Reader is IXmlLineInfo) + if (Reader is IXmlLineInfo lineInfo) { - IXmlLineInfo lineInfo = (IXmlLineInfo)Reader; lineNumber = lineInfo.LineNumber; linePosition = lineInfo.LinePosition; } @@ -3096,18 +3095,18 @@ private void WriteEnumAndArrayTypes() { if (m.IsSoap) continue; - if (m is EnumMapping) + + if (m is EnumMapping enumMapping) { - EnumMapping mapping = (EnumMapping)m; Writer.Write("if ("); - WriteQNameEqual("xsiType", mapping.TypeName, mapping.Namespace); + WriteQNameEqual("xsiType", enumMapping.TypeName, enumMapping.Namespace); Writer.WriteLine(") {"); Writer.Indent++; Writer.WriteLine("Reader.ReadStartElement();"); - string? methodName = ReferenceMapping(mapping); + string? methodName = ReferenceMapping(enumMapping); #if DEBUG // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe - if (methodName == null) throw new InvalidOperationException(SR.Format(SR.XmlInternalErrorMethod, mapping.TypeDesc!.Name)); + if (methodName == null) throw new InvalidOperationException(SR.Format(SR.XmlInternalErrorMethod, enumMapping.TypeDesc!.Name)); #endif Writer.Write("object e = "); Writer.Write(methodName); @@ -3117,22 +3116,21 @@ private void WriteEnumAndArrayTypes() Writer.Indent--; Writer.WriteLine("}"); } - else if (m is ArrayMapping) + else if (m is ArrayMapping arrayMapping) { - ArrayMapping mapping = (ArrayMapping)m; - if (mapping.TypeDesc!.HasDefaultConstructor) + if (arrayMapping.TypeDesc!.HasDefaultConstructor) { Writer.Write("if ("); - WriteQNameEqual("xsiType", mapping.TypeName, mapping.Namespace); + WriteQNameEqual("xsiType", arrayMapping.TypeName, arrayMapping.Namespace); Writer.WriteLine(") {"); Writer.Indent++; MemberMapping memberMapping = new MemberMapping(); - memberMapping.TypeDesc = mapping.TypeDesc; - memberMapping.Elements = mapping.Elements; + memberMapping.TypeDesc = arrayMapping.TypeDesc; + memberMapping.Elements = arrayMapping.Elements; Member member = new Member(this, "a", "z", 0, memberMapping); - TypeDesc td = mapping.TypeDesc; - string fullTypeName = mapping.TypeDesc.CSharpName; + TypeDesc td = arrayMapping.TypeDesc; + string fullTypeName = arrayMapping.TypeDesc.CSharpName; if (td.UseReflection) { if (td.IsArray) @@ -3143,7 +3141,7 @@ private void WriteEnumAndArrayTypes() else Writer.Write(fullTypeName); Writer.Write(" a = "); - if (mapping.TypeDesc.IsValueType) + if (arrayMapping.TypeDesc.IsValueType) { Writer.Write(RaCodeGen.GetStringForCreateInstance(fullTypeName, td.UseReflection, false, false)); Writer.WriteLine(";"); @@ -3151,7 +3149,7 @@ private void WriteEnumAndArrayTypes() else Writer.WriteLine("null;"); - WriteArray(member.Source, member.ArrayName, mapping, false, false, -1); + WriteArray(member.Source, member.ArrayName, arrayMapping, false, false, -1); Writer.WriteLine("return a;"); Writer.Indent--; Writer.WriteLine("}"); @@ -3803,10 +3801,8 @@ private void WriteAttribute(Member member) { AttributeAccessor attribute = member.Mapping.Attribute!; - if (attribute.Mapping is SpecialMapping) + if (attribute.Mapping is SpecialMapping special) { - SpecialMapping special = (SpecialMapping)attribute.Mapping; - if (special.TypeDesc!.Kind == TypeKind.Attribute) { WriteSourceBegin(member.ArraySource); @@ -4084,9 +4080,8 @@ private void WriteText(Member member) { TextAccessor text = member.Mapping.Text!; - if (text.Mapping is SpecialMapping) + if (text.Mapping is SpecialMapping special) { - SpecialMapping special = (SpecialMapping)text.Mapping; WriteSourceBeginTyped(member.ArraySource, special.TypeDesc); switch (special.TypeDesc!.Kind) { @@ -4814,9 +4809,8 @@ private void WriteElement(string source, string? arrayName, string? choiceSource Writer.WriteLine(";"); } } - else if (element.Mapping is SpecialMapping) + else if (element.Mapping is SpecialMapping special) { - SpecialMapping special = (SpecialMapping)element.Mapping; switch (special.TypeDesc!.Kind) { case TypeKind.Node: diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReaderILGen.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReaderILGen.cs index 3f52cefcef674c..34cc8e81b8bb7f 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReaderILGen.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReaderILGen.cs @@ -1192,11 +1192,10 @@ private void WriteEnumAndArrayTypes() { foreach (Mapping m in scope.TypeMappings) { - if (m is EnumMapping) + if (m is EnumMapping enumMapping) { - EnumMapping mapping = (EnumMapping)m; ilg.InitElseIf(); - WriteQNameEqual("xsiType", mapping.TypeName, mapping.Namespace); + WriteQNameEqual("xsiType", enumMapping.TypeName, enumMapping.Namespace); ilg.AndIf(); MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod( "get_Reader", @@ -1211,16 +1210,16 @@ private void WriteEnumAndArrayTypes() ilg.Ldarg(0); ilg.Call(XmlSerializationReader_get_Reader); ilg.Call(XmlReader_ReadStartElement); - string? methodName = ReferenceMapping(mapping); + string? methodName = ReferenceMapping(enumMapping); #if DEBUG // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe - if (methodName == null) throw new InvalidOperationException(SR.Format(SR.XmlInternalErrorMethod, mapping.TypeDesc!.Name)); + if (methodName == null) throw new InvalidOperationException(SR.Format(SR.XmlInternalErrorMethod, enumMapping.TypeDesc!.Name)); #endif LocalBuilder eLoc = ilg.DeclareOrGetLocal(typeof(object), "e"); MethodBuilder methodBuilder = EnsureMethodBuilder(typeBuilder, methodName!, CodeGenerator.PrivateMethodAttributes, - mapping.TypeDesc!.Type, + enumMapping.TypeDesc!.Type, new Type[] { typeof(string) } ); MethodInfo XmlSerializationReader_CollapseWhitespace = typeof(XmlSerializationReader).GetMethod( @@ -1254,25 +1253,24 @@ private void WriteEnumAndArrayTypes() ilg.Br(ilg.ReturnLabel); // Caller own calling ilg.EndIf(); } - else if (m is ArrayMapping) + else if (m is ArrayMapping arrayMapping) { - ArrayMapping mapping = (ArrayMapping)m; - if (mapping.TypeDesc!.HasDefaultConstructor) + if (arrayMapping.TypeDesc!.HasDefaultConstructor) { ilg.InitElseIf(); - WriteQNameEqual("xsiType", mapping.TypeName, mapping.Namespace); + WriteQNameEqual("xsiType", arrayMapping.TypeName, arrayMapping.Namespace); ilg.AndIf(); ilg.EnterScope(); MemberMapping memberMapping = new MemberMapping(); - memberMapping.TypeDesc = mapping.TypeDesc; - memberMapping.Elements = mapping.Elements; + memberMapping.TypeDesc = arrayMapping.TypeDesc; + memberMapping.Elements = arrayMapping.Elements; string aVar = "a"; string zVar = "z"; Member member = new Member(this, aVar, zVar, 0, memberMapping); - TypeDesc td = mapping.TypeDesc; - LocalBuilder aLoc = ilg.DeclareLocal(mapping.TypeDesc.Type!, aVar); - if (mapping.TypeDesc.IsValueType) + TypeDesc td = arrayMapping.TypeDesc; + LocalBuilder aLoc = ilg.DeclareLocal(arrayMapping.TypeDesc.Type!, aVar); + if (arrayMapping.TypeDesc.IsValueType) { ReflectionAwareILGen.ILGenForCreateInstance(ilg, td.Type!, false, false); } @@ -1280,7 +1278,7 @@ private void WriteEnumAndArrayTypes() ilg.Load(null); ilg.Stloc(aLoc); - WriteArray(member.Source, member.ArrayName, mapping, false, false, -1, 0); + WriteArray(member.Source, member.ArrayName, arrayMapping, false, false, -1, 0); ilg.Ldloc(aLoc); ilg.Stloc(ilg.ReturnLocal); ilg.Br(ilg.ReturnLabel); @@ -2066,10 +2064,8 @@ private void WriteAttribute(Member member) { AttributeAccessor attribute = member.Mapping.Attribute!; - if (attribute.Mapping is SpecialMapping) + if (attribute.Mapping is SpecialMapping special) { - SpecialMapping special = (SpecialMapping)attribute.Mapping; - if (special.TypeDesc!.Kind == TypeKind.Attribute) { WriteSourceBegin(member.ArraySource); @@ -2354,9 +2350,8 @@ private void WriteText(Member member) { TextAccessor text = member.Mapping.Text!; - if (text.Mapping is SpecialMapping) + if (text.Mapping is SpecialMapping special) { - SpecialMapping special = (SpecialMapping)text.Mapping; WriteSourceBeginTyped(member.ArraySource, special.TypeDesc); switch (special.TypeDesc!.Kind) { @@ -3215,9 +3210,8 @@ private void WriteElement(string source, string? arrayName, string? choiceSource // 'If' begins in checkForNull above ilg.EndIf(); } - else if (element.Mapping is SpecialMapping) + else if (element.Mapping is SpecialMapping special) { - SpecialMapping special = (SpecialMapping)element.Mapping; switch (special.TypeDesc!.Kind) { case TypeKind.Node: diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriter.cs index bcdfd587ac7f7b..57620778c55176 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriter.cs @@ -3431,9 +3431,8 @@ private void WriteMember(string source, AttributeAccessor attribute, TypeDesc me [RequiresUnreferencedCode("calls WritePrimitive")] private void WriteAttribute(string source, AttributeAccessor attribute, string parent) { - if (attribute.Mapping is SpecialMapping) + if (attribute.Mapping is SpecialMapping special) { - SpecialMapping special = (SpecialMapping)attribute.Mapping; if (special.TypeDesc!.Kind == TypeKind.Attribute || special.TypeDesc.CanBeAttributeValue) { Writer.Write("WriteXmlAttribute("); @@ -3848,24 +3847,22 @@ private void WriteElements(string source, string? enumSource, ElementAccessor[] private void WriteText(string source, TextAccessor text) { - if (text.Mapping is PrimitiveMapping) + if (text.Mapping is PrimitiveMapping primitive) { - PrimitiveMapping mapping = (PrimitiveMapping)text.Mapping; Writer.Write("WriteValue("); - if (text.Mapping is EnumMapping) + if (text.Mapping is EnumMapping enumMapping) { - WriteEnumValue((EnumMapping)text.Mapping, source); + WriteEnumValue(enumMapping, source); } else { - WritePrimitiveValue(mapping.TypeDesc!, source, false); + WritePrimitiveValue(primitive.TypeDesc!, source, false); } Writer.WriteLine(");"); } - else if (text.Mapping is SpecialMapping) + else if (text.Mapping is SpecialMapping simple) { - SpecialMapping mapping = (SpecialMapping)text.Mapping; - switch (mapping.TypeDesc!.Kind) + switch (simple.TypeDesc!.Kind) { case TypeKind.Node: Writer.Write(source); @@ -3906,10 +3903,9 @@ private void WriteElement(string source, ElementAccessor element, string arrayNa Writer.WriteLine("}"); } } - else if (element.Mapping is ArrayMapping) + else if (element.Mapping is ArrayMapping arrayMapping) { - ArrayMapping mapping = (ArrayMapping)element.Mapping; - if (mapping.IsSoap) + if (arrayMapping.IsSoap) { Writer.Write("WritePotentiallyReferencingElement("); WriteQuotedCSharpString(name); @@ -3920,7 +3916,7 @@ private void WriteElement(string source, ElementAccessor element, string arrayNa if (!writeAccessor) { Writer.Write(", "); - Writer.Write(RaCodeGen.GetStringForTypeof(mapping.TypeDesc!.CSharpName, mapping.TypeDesc.UseReflection)); + Writer.Write(RaCodeGen.GetStringForTypeof(arrayMapping.TypeDesc!.CSharpName, arrayMapping.TypeDesc.UseReflection)); Writer.Write(", true, "); } else @@ -3932,20 +3928,20 @@ private void WriteElement(string source, ElementAccessor element, string arrayNa } else if (element.IsUnbounded) { - TypeDesc td = mapping.TypeDesc!.CreateArrayTypeDesc(); + TypeDesc td = arrayMapping.TypeDesc!.CreateArrayTypeDesc(); string fullTypeName = td.CSharpName; string elementArrayName = $"el{arrayName}"; string arrayIndex = $"c{elementArrayName}"; Writer.WriteLine("{"); Writer.Indent++; - WriteArrayLocalDecl(fullTypeName, elementArrayName, source, mapping.TypeDesc); + WriteArrayLocalDecl(fullTypeName, elementArrayName, source, arrayMapping.TypeDesc); if (element.IsNullable) { WriteNullCheckBegin(elementArrayName, element); } else { - if (mapping.TypeDesc.IsNullable) + if (arrayMapping.TypeDesc.IsNullable) { Writer.Write("if ("); Writer.Write(elementArrayName); @@ -3993,17 +3989,17 @@ private void WriteElement(string source, ElementAccessor element, string arrayNa } else { - string fullTypeName = mapping.TypeDesc!.CSharpName; + string fullTypeName = arrayMapping.TypeDesc!.CSharpName; Writer.WriteLine("{"); Writer.Indent++; - WriteArrayLocalDecl(fullTypeName, arrayName, source, mapping.TypeDesc); + WriteArrayLocalDecl(fullTypeName, arrayName, source, arrayMapping.TypeDesc); if (element.IsNullable) { WriteNullCheckBegin(arrayName, element); } else { - if (mapping.TypeDesc.IsNullable) + if (arrayMapping.TypeDesc.IsNullable) { Writer.Write("if ("); Writer.Write(arrayName); @@ -4013,7 +4009,7 @@ private void WriteElement(string source, ElementAccessor element, string arrayNa Writer.Indent++; } WriteStartElement(name, ns, false); - WriteArrayItems(mapping.ElementsSortedByDerivation!, null, null, mapping.TypeDesc, arrayName, null); + WriteArrayItems(arrayMapping.ElementsSortedByDerivation!, null, null, arrayMapping.TypeDesc, arrayName, null); WriteEndElement(); Writer.Indent--; Writer.WriteLine("}"); @@ -4042,24 +4038,21 @@ private void WriteElement(string source, ElementAccessor element, string arrayNa WritePrimitive("WriteElementString", name, ns, element.Default, source, element.Mapping, false, true, element.IsNullable); } } - else if (element.Mapping is PrimitiveMapping) + else if (element.Mapping is PrimitiveMapping primitiveMapping) { - PrimitiveMapping mapping = (PrimitiveMapping)element.Mapping; - if (mapping.TypeDesc == QnameTypeDesc) - WriteQualifiedNameElement(name, ns, element.Default, source, element.IsNullable, mapping.IsSoap, mapping); + if (primitiveMapping.TypeDesc == QnameTypeDesc) + WriteQualifiedNameElement(name, ns, element.Default, source, element.IsNullable, primitiveMapping.IsSoap, primitiveMapping); else { - string suffixNullable = mapping.IsSoap ? "Encoded" : "Literal"; - string suffixRaw = mapping.TypeDesc!.XmlEncodingNotRequired ? "Raw" : ""; + string suffixNullable = primitiveMapping.IsSoap ? "Encoded" : "Literal"; + string suffixRaw = primitiveMapping.TypeDesc!.XmlEncodingNotRequired ? "Raw" : ""; WritePrimitive(element.IsNullable ? ("WriteNullableString" + suffixNullable + suffixRaw) : ("WriteElementString" + suffixRaw), - name, ns, element.Default, source, mapping, mapping.IsSoap, true, element.IsNullable); + name, ns, element.Default, source, primitiveMapping, primitiveMapping.IsSoap, true, element.IsNullable); } } - else if (element.Mapping is StructMapping) + else if (element.Mapping is StructMapping structMapping) { - StructMapping mapping = (StructMapping)element.Mapping; - - if (mapping.IsSoap) + if (structMapping.IsSoap) { Writer.Write("WritePotentiallyReferencingElement("); WriteQuotedCSharpString(name); @@ -4070,7 +4063,7 @@ private void WriteElement(string source, ElementAccessor element, string arrayNa if (!writeAccessor) { Writer.Write(", "); - Writer.Write(RaCodeGen.GetStringForTypeof(mapping.TypeDesc!.CSharpName, mapping.TypeDesc.UseReflection)); + Writer.Write(RaCodeGen.GetStringForTypeof(structMapping.TypeDesc!.CSharpName, structMapping.TypeDesc.UseReflection)); Writer.Write(", true, "); } else @@ -4081,11 +4074,11 @@ private void WriteElement(string source, ElementAccessor element, string arrayNa } else { - string? methodName = ReferenceMapping(mapping); + string? methodName = ReferenceMapping(structMapping); #if DEBUG // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe - if (methodName == null) throw new InvalidOperationException(SR.Format(SR.XmlInternalErrorMethod, mapping.TypeDesc!.Name) + Environment.StackTrace); + if (methodName == null) throw new InvalidOperationException(SR.Format(SR.XmlInternalErrorMethod, structMapping.TypeDesc!.Name) + Environment.StackTrace); #endif Writer.Write(methodName); Writer.Write("("); @@ -4099,7 +4092,7 @@ private void WriteElement(string source, ElementAccessor element, string arrayNa } Writer.Write(", "); Writer.Write(source); - if (mapping.TypeDesc!.IsNullable) + if (structMapping.TypeDesc!.IsNullable) { Writer.Write(", "); WriteValue(element.IsNullable); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriterILGen.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriterILGen.cs index 18ab8b6e1481ee..df965008c18f32 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriterILGen.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriterILGen.cs @@ -1368,9 +1368,8 @@ private void WriteMember(SourceInfo source, AttributeAccessor attribute, TypeDes [RequiresUnreferencedCode("calls WritePrimitive")] private void WriteAttribute(SourceInfo source, AttributeAccessor attribute, string parent) { - if (attribute.Mapping is SpecialMapping) + if (attribute.Mapping is SpecialMapping special) { - SpecialMapping special = (SpecialMapping)attribute.Mapping; if (special.TypeDesc!.Kind == TypeKind.Attribute || special.TypeDesc.CanBeAttributeValue) { System.Diagnostics.Debug.Assert(parent == "o" || parent == "p"); @@ -1864,9 +1863,8 @@ private void WriteElements(SourceInfo source, string? enumSource, ElementAccesso [RequiresUnreferencedCode("calls Load")] private void WriteText(SourceInfo source, TextAccessor text) { - if (text.Mapping is PrimitiveMapping) + if (text.Mapping is PrimitiveMapping primitiveMapping) { - PrimitiveMapping mapping = (PrimitiveMapping)text.Mapping; Type argType; ilg.Ldarg(0); if (text.Mapping is EnumMapping) @@ -1875,7 +1873,7 @@ private void WriteText(SourceInfo source, TextAccessor text) } else { - WritePrimitiveValue(mapping.TypeDesc!, source, out argType); + WritePrimitiveValue(primitiveMapping.TypeDesc!, source, out argType); } MethodInfo XmlSerializationWriter_WriteValue = typeof(XmlSerializationWriter).GetMethod( "WriteValue", @@ -1884,10 +1882,9 @@ private void WriteText(SourceInfo source, TextAccessor text) )!; ilg.Call(XmlSerializationWriter_WriteValue); } - else if (text.Mapping is SpecialMapping) + else if (text.Mapping is SpecialMapping specialMapping) { - SpecialMapping mapping = (SpecialMapping)text.Mapping; - switch (mapping.TypeDesc!.Kind) + switch (specialMapping.TypeDesc!.Kind) { case TypeKind.Node: MethodInfo WriteTo = source.Type!.GetMethod( @@ -1946,9 +1943,8 @@ private void WriteElement(SourceInfo source, ElementAccessor element, string arr } ilg.EndIf(); } - else if (element.Mapping is ArrayMapping) + else if (element.Mapping is ArrayMapping arrayMapping) { - ArrayMapping mapping = (ArrayMapping)element.Mapping; if (element.IsUnbounded) { throw Globals.NotSupported("Unreachable: IsUnbounded is never set true!"); @@ -1956,15 +1952,15 @@ private void WriteElement(SourceInfo source, ElementAccessor element, string arr else { ilg.EnterScope(); - string fullTypeName = mapping.TypeDesc!.CSharpName; - WriteArrayLocalDecl(fullTypeName, arrayName, source, mapping.TypeDesc); + string fullTypeName = arrayMapping.TypeDesc!.CSharpName; + WriteArrayLocalDecl(fullTypeName, arrayName, source, arrayMapping.TypeDesc); if (element.IsNullable) { WriteNullCheckBegin(arrayName, element); } else { - if (mapping.TypeDesc.IsNullable) + if (arrayMapping.TypeDesc.IsNullable) { ilg.Ldloc(ilg.GetLocal(arrayName)); ilg.Load(null); @@ -1972,7 +1968,7 @@ private void WriteElement(SourceInfo source, ElementAccessor element, string arr } } WriteStartElement(name, ns, false); - WriteArrayItems(mapping.ElementsSortedByDerivation!, null, null, mapping.TypeDesc, arrayName, null); + WriteArrayItems(arrayMapping.ElementsSortedByDerivation!, null, null, arrayMapping.TypeDesc, arrayName, null); WriteEndElement(); if (element.IsNullable) { @@ -1980,7 +1976,7 @@ private void WriteElement(SourceInfo source, ElementAccessor element, string arr } else { - if (mapping.TypeDesc.IsNullable) + if (arrayMapping.TypeDesc.IsNullable) { ilg.EndIf(); } @@ -1992,27 +1988,26 @@ private void WriteElement(SourceInfo source, ElementAccessor element, string arr { WritePrimitive("WriteElementString", name, ns, element.Default, source, element.Mapping, false, true, element.IsNullable); } - else if (element.Mapping is PrimitiveMapping) + else if (element.Mapping is PrimitiveMapping primitiveMapping) { - PrimitiveMapping mapping = (PrimitiveMapping)element.Mapping; - if (mapping.TypeDesc == QnameTypeDesc) - WriteQualifiedNameElement(name, ns, GetConvertedDefaultValue(source.Type, element.Default), source, element.IsNullable, mapping); + if (primitiveMapping.TypeDesc == QnameTypeDesc) + { + WriteQualifiedNameElement(name, ns, GetConvertedDefaultValue(source.Type, element.Default), source, element.IsNullable, primitiveMapping); + } else { - string suffixRaw = mapping.TypeDesc!.XmlEncodingNotRequired ? "Raw" : ""; + string suffixRaw = primitiveMapping.TypeDesc!.XmlEncodingNotRequired ? "Raw" : ""; WritePrimitive(element.IsNullable ? ("WriteNullableStringLiteral" + suffixRaw) : ("WriteElementString" + suffixRaw), - name, ns, GetConvertedDefaultValue(source.Type, element.Default), source, mapping, false, true, element.IsNullable); + name, ns, GetConvertedDefaultValue(source.Type, element.Default), source, primitiveMapping, false, true, element.IsNullable); } } - else if (element.Mapping is StructMapping) + else if (element.Mapping is StructMapping structMapping) { - StructMapping mapping = (StructMapping)element.Mapping; - - string? methodName = ReferenceMapping(mapping); + string? methodName = ReferenceMapping(structMapping); #if DEBUG // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe - if (methodName == null) throw new InvalidOperationException(SR.Format(SR.XmlInternalErrorMethod, mapping.TypeDesc!.Name)); + if (methodName == null) throw new InvalidOperationException(SR.Format(SR.XmlInternalErrorMethod, structMapping.TypeDesc!.Name)); #endif List argTypes = new List(); ilg.Ldarg(0); @@ -2020,9 +2015,9 @@ private void WriteElement(SourceInfo source, ElementAccessor element, string arr argTypes.Add(typeof(string)); ilg.Ldstr(GetCSharpString(ns)); argTypes.Add(typeof(string)); - source.Load(mapping.TypeDesc!.Type); - argTypes.Add(mapping.TypeDesc.Type!); - if (mapping.TypeDesc.IsNullable) + source.Load(structMapping.TypeDesc!.Type); + argTypes.Add(structMapping.TypeDesc.Type!); + if (structMapping.TypeDesc.IsNullable) { ilg.Ldc(element.IsNullable); argTypes.Add(typeof(bool)); diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializer.cs b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializer.cs index cc50d72f09a71d..dc048410ebd7c8 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializer.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializer.cs @@ -489,9 +489,8 @@ private XmlMapping GetMapping() if (e is TargetInvocationException) e = e.InnerException; - if (xmlReader is IXmlLineInfo) + if (xmlReader is IXmlLineInfo lineInfo) { - IXmlLineInfo lineInfo = (IXmlLineInfo)xmlReader; throw new InvalidOperationException(SR.Format(SR.XmlSerializeErrorDetails, lineInfo.LineNumber.ToString(CultureInfo.InvariantCulture), lineInfo.LinePosition.ToString(CultureInfo.InvariantCulture)), e); } else diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilXmlWriter.cs b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilXmlWriter.cs index 670aff81778bbe..7946d52b56a2d6 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilXmlWriter.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Xsl/QIL/QilXmlWriter.cs @@ -153,10 +153,8 @@ protected override QilNode VisitChildren(QilNode node) this.writer.WriteValue(Convert.ToString(((QilLiteral)node).Value, CultureInfo.InvariantCulture)); return node; } - else if (node is QilReference) + else if (node is QilReference reference) { - QilReference reference = (QilReference)node; - // Write the generated identifier for this iterator this.writer.WriteAttributeString("id", _ngen.NameOf(node)); From 1b87ff9e352c1caa466572c74df84e0ffe9cda37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Fri, 17 Jun 2022 21:17:51 +0900 Subject: [PATCH 190/337] Fix failure building two libraries tests (#70881) Microsoft.CSharp was hitting an issue due to a vararg constructor. We don't support varargs. They shouldn't make it into the dependency graph. We are already checking in many places. We were erroneously thinking a vararg constructor with no mandatory arguments is a default constructor. Runtime.InteropServices were crashing because we got a MulticastDelegate type into a codepath that expects a MulticastDelegate descendant. --- src/coreclr/tools/Common/TypeSystem/Ecma/EcmaType.cs | 7 ++++++- .../Compiler/Dataflow/ReflectionMethodBodyScanner.cs | 2 +- .../tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs | 2 ++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaType.cs b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaType.cs index 073cb7a4fdfb2b..2b3b625db32d1a 100644 --- a/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaType.cs +++ b/src/coreclr/tools/Common/TypeSystem/Ecma/EcmaType.cs @@ -374,7 +374,12 @@ public override MethodDesc GetDefaultConstructor() && stringComparer.Equals(methodDefinition.Name, ".ctor")) { var method = (EcmaMethod)_module.GetObject(handle); - if (method.Signature.Length != 0) + MethodSignature sig = method.Signature; + + if (sig.Length != 0) + continue; + + if ((sig.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask) == MethodSignatureFlags.CallingConventionVarargs) continue; return method; diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs index 4343e5352da3bc..18c5b082f60fec 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/Dataflow/ReflectionMethodBodyScanner.cs @@ -625,7 +625,7 @@ public override bool HandleCall(MethodIL callingMethodBody, MethodDesc calledMet && !systemTypeValue.RepresentedType.Type.IsGenericDefinition && !systemTypeValue.RepresentedType.Type.ContainsSignatureVariables(treatGenericParameterLikeSignatureVariable: true)) { - if (systemTypeValue.RepresentedType.Type.IsDefType) + if (systemTypeValue.RepresentedType.Type.IsDelegate) { _reflectionMarker.Dependencies.Add(_factory.DelegateMarshallingData((DefType)systemTypeValue.RepresentedType.Type), "Marshal API"); } 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 a5f1ce07c3c220..0f4dded3fe585e 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs @@ -264,6 +264,8 @@ private void ImportCall(ILOpcode opcode, int token) var method = (MethodDesc)_canonMethodIL.GetObject(token); _compilation.TypeSystemContext.EnsureLoadableMethod(method); + if ((method.Signature.Flags & MethodSignatureFlags.UnmanagedCallingConventionMask) == MethodSignatureFlags.CallingConventionVarargs) + ThrowHelper.ThrowBadImageFormatException(); _compilation.NodeFactory.MetadataManager.GetDependenciesDueToAccess(ref _dependencies, _compilation.NodeFactory, _canonMethodIL, method); From 5fc5c68d8a9f1352ae1c4f92769a15d60e5516f3 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Fri, 17 Jun 2022 10:19:07 -0400 Subject: [PATCH 191/337] Use hash/hmac one shots in NTLM (#70857) Co-authored-by: Stephen Toub --- .../System/Net/NTAuthentication.Managed.cs | 31 ++++++------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/src/libraries/Common/src/System/Net/NTAuthentication.Managed.cs b/src/libraries/Common/src/System/Net/NTAuthentication.Managed.cs index d3ed0a07df98f3..16e9ee17745e2b 100644 --- a/src/libraries/Common/src/System/Net/NTAuthentication.Managed.cs +++ b/src/libraries/Common/src/System/Net/NTAuthentication.Managed.cs @@ -444,14 +444,10 @@ private static void makeNtlm2Hash(string domain, string userName, ReadOnlySpan hashBuffer) { IntPtr cbtData = _channelBinding.DangerousGetHandle(); int cbtDataSize = _channelBinding.Size; - - using (var md5 = IncrementalHash.CreateHash(HashAlgorithmName.MD5)) - { - md5.AppendData(new Span((void *)cbtData, cbtDataSize)); - md5.GetHashAndReset(hashBuffer); - } + int written = MD5.HashData(new Span((void*)cbtData, cbtDataSize), hashBuffer); + Debug.Assert(written == MD5.HashSizeInBytes); } else { - hashBuffer.Fill(0); + hashBuffer.Clear(); } } @@ -716,12 +708,9 @@ private static byte[] DeriveKey(ReadOnlySpan exportedSessionKey, ReadOnlyS Debug.Assert(flags.HasFlag(Flags.NegotiateSign) && flags.HasFlag(Flags.NegotiateKeyExchange)); // Derive session base key - Span sessionBaseKey = stackalloc byte[16]; - using (var hmacSessionKey = IncrementalHash.CreateHMAC(HashAlgorithmName.MD5, ntlm2hash)) - { - hmacSessionKey.AppendData(responseAsSpan.Slice(response.NtChallengeResponse.PayloadOffset, 16)); - hmacSessionKey.GetHashAndReset(sessionBaseKey); - } + Span sessionBaseKey = stackalloc byte[HMACMD5.HashSizeInBytes]; + int sessionKeyWritten = HMACMD5.HashData(ntlm2hash, responseAsSpan.Slice(response.NtChallengeResponse.PayloadOffset, 16), sessionBaseKey); + Debug.Assert(sessionKeyWritten == HMACMD5.HashSizeInBytes); // Encrypt exportedSessionKey with sessionBaseKey using (RC4 rc4 = new RC4(sessionBaseKey)) From a78211bef436e634f8bbdc25de78ecde97764d9e Mon Sep 17 00:00:00 2001 From: Joni Aromaa Date: Fri, 17 Jun 2022 18:00:45 +0300 Subject: [PATCH 192/337] Unpin locals, attempt 2 (#70655) Contributes to #40553 --- src/coreclr/jit/compiler.h | 2 + src/coreclr/jit/gentree.h | 5 +++ src/coreclr/jit/lclvars.cpp | 78 +++++++++++++++++++++++-------------- 3 files changed, 55 insertions(+), 30 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index e8cc613d7a19a8..b864a9a0f566e3 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -614,6 +614,8 @@ class LclVarDsc unsigned char lvSingleDefDisqualifyReason = 'H'; #endif + unsigned char lvAllDefsAreNoGc : 1; // For pinned locals: true if all defs of this local are no-gc + #if FEATURE_MULTIREG_ARGS regNumber lvRegNumForSlot(unsigned slotNum) { diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index ff72fae3378d16..8ef60e8a524d68 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -1104,6 +1104,11 @@ struct GenTree return true; } + bool IsNotGcDef() const + { + return IsIntegralConst(0) || IsLocalAddrExpr(); + } + // LIR flags // These helper methods, along with the flag values they manipulate, are defined in lir.h // diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index 53a601b068a284..b17b288a29486c 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -4234,49 +4234,57 @@ void Compiler::lvaMarkLclRefs(GenTree* tree, BasicBlock* block, Statement* stmt, /* Is this an assignment to a local variable? */ - if (op1->gtOper == GT_LCL_VAR && op2->gtType != TYP_BOOL) + if (op1->gtOper == GT_LCL_VAR) { - /* Only simple assignments allowed for booleans */ + LclVarDsc* varDsc = lvaGetDesc(op1->AsLclVarCommon()); - if (tree->gtOper != GT_ASG) + if (varDsc->lvPinned && varDsc->lvAllDefsAreNoGc) { - goto NOT_BOOL; + if (!op2->IsNotGcDef()) + { + varDsc->lvAllDefsAreNoGc = false; + } } - /* Is the RHS clearly a boolean value? */ - - switch (op2->gtOper) + if (op2->gtType != TYP_BOOL) { - unsigned lclNum; + /* Only simple assignments allowed for booleans */ - case GT_CNS_INT: + if (tree->gtOper != GT_ASG) + { + goto NOT_BOOL; + } - if (op2->AsIntCon()->gtIconVal == 0) - { - break; - } - if (op2->AsIntCon()->gtIconVal == 1) - { - break; - } + /* Is the RHS clearly a boolean value? */ - // Not 0 or 1, fall through .... - FALLTHROUGH; + switch (op2->gtOper) + { + case GT_CNS_INT: - default: + if (op2->AsIntCon()->gtIconVal == 0) + { + break; + } + if (op2->AsIntCon()->gtIconVal == 1) + { + break; + } - if (op2->OperIsCompare()) - { - break; - } + // Not 0 or 1, fall through .... + FALLTHROUGH; - NOT_BOOL: + default: - lclNum = op1->AsLclVarCommon()->GetLclNum(); - noway_assert(lclNum < lvaCount); + if (op2->OperIsCompare()) + { + break; + } - lvaTable[lclNum].lvIsBoolean = false; - break; + NOT_BOOL: + + varDsc->lvIsBoolean = false; + break; + } } } } @@ -4331,7 +4339,8 @@ void Compiler::lvaMarkLclRefs(GenTree* tree, BasicBlock* block, Statement* stmt, { if (lvaVarAddrExposed(lclNum)) { - varDsc->lvIsBoolean = false; + varDsc->lvIsBoolean = false; + varDsc->lvAllDefsAreNoGc = false; } if (tree->gtOper == GT_LCL_FLD) @@ -4803,6 +4812,8 @@ void Compiler::lvaComputeRefCounts(bool isRecompute, bool setSlotNumbers) { varDsc->lvSingleDef = varDsc->lvIsParam; varDsc->lvSingleDefRegCandidate = varDsc->lvIsParam; + + varDsc->lvAllDefsAreNoGc = (varDsc->lvImplicitlyReferenced == false); } } @@ -4921,6 +4932,13 @@ void Compiler::lvaComputeRefCounts(bool isRecompute, bool setSlotNumbers) varDsc->lvImplicitlyReferenced = 1; } } + + if (varDsc->lvPinned && varDsc->lvAllDefsAreNoGc) + { + varDsc->lvPinned = 0; + + JITDUMP("V%02u was unpinned as all def candidates were local.\n", lclNum); + } } } From 6d6a373824df45eb1121097945ff0bac4c009385 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Fri, 17 Jun 2022 08:43:13 -0700 Subject: [PATCH 193/337] Replace a few instances of PtrToStructure with more efficient marshalling (#70866) --- .../Windows/Crypt32/Interop.FindOidInfo.cs | 22 ++-- .../Windows/Crypt32/Interop.HashIdAlg.cs | 21 ++-- .../IpHlpApi/Interop.NetworkInformation.cs | 103 ++++++++++-------- .../Diagnostics/FileVersionInfo.Windows.cs | 4 +- .../SystemIPInterfaceProperties.cs | 4 +- .../SystemIPv4InterfaceProperties.cs | 7 +- .../SystemNetworkInterface.cs | 25 ++--- .../SystemUnicastIPAddressInformation.cs | 12 +- .../src/System/Security/Principal/SID.cs | 4 +- 9 files changed, 101 insertions(+), 101 deletions(-) diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.FindOidInfo.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.FindOidInfo.cs index 8733d4190875e1..79e97016686b3d 100644 --- a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.FindOidInfo.cs +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.FindOidInfo.cs @@ -48,7 +48,7 @@ internal enum CryptOidInfoKeyType : int CRYPT_OID_INFO_CNG_SIGN_KEY = 6, } - internal static CRYPT_OID_INFO FindOidInfo(CryptOidInfoKeyType keyType, string key, OidGroup group, bool fallBackToAllGroups) + internal static unsafe CRYPT_OID_INFO FindOidInfo(CryptOidInfoKeyType keyType, string key, OidGroup group, bool fallBackToAllGroups) { const OidGroup CRYPT_OID_DISABLE_SEARCH_DS_FLAG = unchecked((OidGroup)0x80000000); Debug.Assert(key != null); @@ -75,28 +75,28 @@ internal static CRYPT_OID_INFO FindOidInfo(CryptOidInfoKeyType keyType, string k if (!OidGroupWillNotUseActiveDirectory(group)) { OidGroup localGroup = group | CRYPT_OID_DISABLE_SEARCH_DS_FLAG; - IntPtr localOidInfo = CryptFindOIDInfo(keyType, rawKey, localGroup); - if (localOidInfo != IntPtr.Zero) + CRYPT_OID_INFO* localOidInfo = CryptFindOIDInfo(keyType, rawKey, localGroup); + if (localOidInfo != null) { - return Marshal.PtrToStructure(localOidInfo); + return *localOidInfo; } } // Attempt to query with a specific group, to make try to avoid an AD lookup if possible - IntPtr fullOidInfo = CryptFindOIDInfo(keyType, rawKey, group); - if (fullOidInfo != IntPtr.Zero) + CRYPT_OID_INFO* fullOidInfo = CryptFindOIDInfo(keyType, rawKey, group); + if (fullOidInfo != null) { - return Marshal.PtrToStructure(fullOidInfo); + return *fullOidInfo; } if (fallBackToAllGroups && group != OidGroup.All) { // Finally, for compatibility with previous runtimes, if we have a group specified retry the // query with no group - IntPtr allGroupOidInfo = CryptFindOIDInfo(keyType, rawKey, OidGroup.All); - if (allGroupOidInfo != IntPtr.Zero) + CRYPT_OID_INFO* allGroupOidInfo = CryptFindOIDInfo(keyType, rawKey, OidGroup.All); + if (allGroupOidInfo != null) { - return Marshal.PtrToStructure(allGroupOidInfo); + return *allGroupOidInfo; } } @@ -125,6 +125,6 @@ private static bool OidGroupWillNotUseActiveDirectory(OidGroup group) } [LibraryImport(Interop.Libraries.Crypt32)] - private static partial IntPtr CryptFindOIDInfo(CryptOidInfoKeyType dwKeyType, IntPtr pvKey, OidGroup group); + private static unsafe partial CRYPT_OID_INFO* CryptFindOIDInfo(CryptOidInfoKeyType dwKeyType, IntPtr pvKey, OidGroup group); } } diff --git a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.HashIdAlg.cs b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.HashIdAlg.cs index 4d5110c158487b..d7dfe86c3c3faf 100644 --- a/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.HashIdAlg.cs +++ b/src/libraries/Common/src/Interop/Windows/Crypt32/Interop.HashIdAlg.cs @@ -13,23 +13,18 @@ internal static partial class Crypt32 /// Version used for a buffer containing a scalar integer (not an IntPtr) /// [LibraryImport(Libraries.Crypt32)] - private static unsafe partial IntPtr CryptFindOIDInfo(CryptOidInfoKeyType dwKeyType, int* pvKey, OidGroup group); + private static unsafe partial CRYPT_OID_INFO* CryptFindOIDInfo(CryptOidInfoKeyType dwKeyType, void* pvKey, OidGroup group); - public static CRYPT_OID_INFO FindAlgIdOidInfo(Interop.BCrypt.ECC_CURVE_ALG_ID_ENUM algId) + public static unsafe CRYPT_OID_INFO FindAlgIdOidInfo(Interop.BCrypt.ECC_CURVE_ALG_ID_ENUM algId) { - int intAlgId = (int)algId; - IntPtr fullOidInfo; - unsafe - { - fullOidInfo = CryptFindOIDInfo( - CryptOidInfoKeyType.CRYPT_OID_INFO_ALGID_KEY, - &intAlgId, - OidGroup.HashAlgorithm); - } + CRYPT_OID_INFO* fullOidInfo = CryptFindOIDInfo( + CryptOidInfoKeyType.CRYPT_OID_INFO_ALGID_KEY, + &algId, + OidGroup.HashAlgorithm); - if (fullOidInfo != IntPtr.Zero) + if (fullOidInfo != null) { - return Marshal.PtrToStructure(fullOidInfo); + return *fullOidInfo; } // Otherwise the lookup failed. diff --git a/src/libraries/Common/src/Interop/Windows/IpHlpApi/Interop.NetworkInformation.cs b/src/libraries/Common/src/Interop/Windows/IpHlpApi/Interop.NetworkInformation.cs index 11b32ab4ef4bb9..3f0cd7444fdf45 100644 --- a/src/libraries/Common/src/Interop/Windows/IpHlpApi/Interop.NetworkInformation.cs +++ b/src/libraries/Common/src/Interop/Windows/IpHlpApi/Interop.NetworkInformation.cs @@ -76,24 +76,22 @@ internal IPAddress MarshalIPAddress() // IP_ADAPTER_WINS_SERVER_ADDRESS // IP_ADAPTER_GATEWAY_ADDRESS [StructLayout(LayoutKind.Sequential)] - internal struct IpAdapterAddress + internal unsafe struct IpAdapterAddress { internal uint length; internal AdapterAddressFlags flags; - internal IntPtr next; + internal IpAdapterAddress* next; internal IpSocketAddress address; internal static InternalIPAddressCollection MarshalIpAddressCollection(IntPtr ptr) { InternalIPAddressCollection addressList = new InternalIPAddressCollection(); - while (ptr != IntPtr.Zero) + IpAdapterAddress* pIpAdapterAddress = (IpAdapterAddress*)ptr; + while (pIpAdapterAddress != null) { - IpAdapterAddress addressStructure = Marshal.PtrToStructure(ptr); - IPAddress address = addressStructure.address.MarshalIPAddress(); - addressList.InternalAdd(address); - - ptr = addressStructure.next; + addressList.InternalAdd(pIpAdapterAddress->address.MarshalIPAddress()); + pIpAdapterAddress = pIpAdapterAddress->next; } return addressList; @@ -103,13 +101,12 @@ internal static IPAddressInformationCollection MarshalIpAddressInformationCollec { IPAddressInformationCollection addressList = new IPAddressInformationCollection(); - while (ptr != IntPtr.Zero) + IpAdapterAddress* pIpAdapterAddress = (IpAdapterAddress*)ptr; + while (pIpAdapterAddress != null) { - IpAdapterAddress addressStructure = Marshal.PtrToStructure(ptr); - IPAddress address = addressStructure.address.MarshalIPAddress(); - addressList.InternalAdd(new SystemIPAddressInformation(address, addressStructure.flags)); - - ptr = addressStructure.next; + addressList.InternalAdd(new SystemIPAddressInformation( + pIpAdapterAddress->address.MarshalIPAddress(), pIpAdapterAddress->flags)); + pIpAdapterAddress = pIpAdapterAddress->next; } return addressList; @@ -117,11 +114,11 @@ internal static IPAddressInformationCollection MarshalIpAddressInformationCollec } [StructLayout(LayoutKind.Sequential)] - internal struct IpAdapterUnicastAddress + internal unsafe struct IpAdapterUnicastAddress { internal uint length; internal AdapterAddressFlags flags; - internal IntPtr next; + internal IpAdapterUnicastAddress* next; internal IpSocketAddress address; internal PrefixOrigin prefixOrigin; internal SuffixOrigin suffixOrigin; @@ -132,37 +129,59 @@ internal struct IpAdapterUnicastAddress internal byte prefixLength; } - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - internal struct IpAdapterAddresses + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct IpAdapterAddresses { internal const int MAX_ADAPTER_ADDRESS_LENGTH = 8; internal uint length; internal uint index; - internal IntPtr next; + internal IpAdapterAddresses* next; - // Needs to be ANSI. - [MarshalAs(UnmanagedType.LPStr)] - internal string AdapterName; + private IntPtr _adapterName; // ANSI string + internal string AdapterName => Marshal.PtrToStringAnsi(_adapterName)!; internal IntPtr firstUnicastAddress; internal IntPtr firstAnycastAddress; internal IntPtr firstMulticastAddress; internal IntPtr firstDnsServerAddress; - internal string dnsSuffix; - internal string description; - internal string friendlyName; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_ADAPTER_ADDRESS_LENGTH)] - internal byte[] address; - internal uint addressLength; + private IntPtr _dnsSuffix; + internal string DnsSuffix => Marshal.PtrToStringUni(_dnsSuffix)!; + + private IntPtr _description; + internal string Description => Marshal.PtrToStringUni(_description)!; + + private IntPtr _friendlyName; + internal string FriendlyName => Marshal.PtrToStringUni(_friendlyName)!; + + private fixed byte _address[MAX_ADAPTER_ADDRESS_LENGTH]; + private uint _addressLength; + internal byte[] Address + { + get + { + fixed (byte* pAddress = _address) + return new ReadOnlySpan(pAddress, (int)_addressLength).ToArray(); + } + } + internal AdapterFlags flags; internal uint mtu; internal NetworkInterfaceType type; internal OperationalStatus operStatus; internal uint ipv6Index; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] - internal uint[] zoneIndices; + + private fixed uint _zoneIndices[16]; + internal uint[] ZoneIndices + { + get + { + fixed (uint* pZoneIndices = _zoneIndices) + return new ReadOnlySpan(pZoneIndices, 16).ToArray(); + } + } + internal IntPtr firstPrefix; internal ulong transmitLinkSpeed; @@ -174,13 +193,11 @@ internal struct IpAdapterAddresses internal ulong luid; internal IpSocketAddress dhcpv4Server; internal uint compartmentId; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] - internal byte[] networkGuid; + internal fixed byte networkGuid[16]; internal InterfaceConnectionType connectionType; internal InterfaceTunnelType tunnelType; internal IpSocketAddress dhcpv6Server; // Never available in Windows. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 130)] - internal byte[] dhcpv6ClientDuid; + internal fixed byte dhcpv6ClientDuid[130]; internal uint dhcpv6ClientDuidLength; internal uint dhcpV6Iaid; @@ -211,11 +228,11 @@ internal enum InterfaceTunnelType : int /// /// IP_PER_ADAPTER_INFO - per-adapter IP information such as DNS server list. /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + [StructLayout(LayoutKind.Sequential)] internal struct IpPerAdapterInfo { - internal bool autoconfigEnabled; - internal bool autoconfigActive; + internal uint autoconfigEnabled; + internal uint autoconfigActive; internal IntPtr currentDnsServer; /* IpAddressList* */ internal IpAddrString dnsServerList; }; @@ -224,14 +241,12 @@ internal struct IpPerAdapterInfo /// Store an IP address with its corresponding subnet mask, /// both as dotted decimal strings. /// - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] - internal struct IpAddrString + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct IpAddrString { - internal IntPtr Next; /* struct _IpAddressList* */ - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] - internal string IpAddress; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] - internal string IpMask; + internal IpAddrString* Next; /* struct _IpAddressList* */ + internal fixed byte IpAddress[16]; + internal fixed byte IpMask[16]; internal uint Context; } diff --git a/src/libraries/System.Diagnostics.FileVersionInfo/src/System/Diagnostics/FileVersionInfo.Windows.cs b/src/libraries/System.Diagnostics.FileVersionInfo/src/System/Diagnostics/FileVersionInfo.Windows.cs index 4b575173e1fa6a..fa5234bde62dec 100644 --- a/src/libraries/System.Diagnostics.FileVersionInfo/src/System/Diagnostics/FileVersionInfo.Windows.cs +++ b/src/libraries/System.Diagnostics.FileVersionInfo/src/System/Diagnostics/FileVersionInfo.Windows.cs @@ -68,11 +68,11 @@ private static string ConvertTo8DigitHex(uint value) return value.ToString("X8"); } - private static Interop.Version.VS_FIXEDFILEINFO GetFixedFileInfo(IntPtr memPtr) + private static unsafe Interop.Version.VS_FIXEDFILEINFO GetFixedFileInfo(IntPtr memPtr) { if (Interop.Version.VerQueryValue(memPtr, "\\", out IntPtr memRef, out _)) { - return (Interop.Version.VS_FIXEDFILEINFO)Marshal.PtrToStructure(memRef); + return *(Interop.Version.VS_FIXEDFILEINFO*)memRef; } return default; diff --git a/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemIPInterfaceProperties.cs b/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemIPInterfaceProperties.cs index 6d261115b1eec4..fbdd43df85ca24 100644 --- a/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemIPInterfaceProperties.cs +++ b/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemIPInterfaceProperties.cs @@ -29,7 +29,7 @@ internal sealed class SystemIPInterfaceProperties : IPInterfaceProperties internal SystemIPInterfaceProperties(in Interop.IpHlpApi.FIXED_INFO fixedInfo, in Interop.IpHlpApi.IpAdapterAddresses ipAdapterAddresses) { _adapterFlags = ipAdapterAddresses.flags; - _dnsSuffix = ipAdapterAddresses.dnsSuffix; + _dnsSuffix = ipAdapterAddresses.DnsSuffix; _dnsEnabled = fixedInfo.enableDns; _dynamicDnsEnabled = ((ipAdapterAddresses.flags & Interop.IpHlpApi.AdapterFlags.DnsEnabled) > 0); @@ -64,7 +64,7 @@ internal SystemIPInterfaceProperties(in Interop.IpHlpApi.FIXED_INFO fixedInfo, i if ((_adapterFlags & Interop.IpHlpApi.AdapterFlags.IPv6Enabled) != 0) { _ipv6Properties = new SystemIPv6InterfaceProperties(ipAdapterAddresses.ipv6Index, - ipAdapterAddresses.mtu, ipAdapterAddresses.zoneIndices); + ipAdapterAddresses.mtu, ipAdapterAddresses.ZoneIndices); } } diff --git a/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemIPv4InterfaceProperties.cs b/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemIPv4InterfaceProperties.cs index 7c455b47b455b4..e96e1cdb59e8c5 100644 --- a/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemIPv4InterfaceProperties.cs +++ b/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemIPv4InterfaceProperties.cs @@ -91,11 +91,10 @@ private unsafe void GetPerAdapterInfo(uint index) result = Interop.IpHlpApi.GetPerAdapterInfo(index, buffer, &size); if (result == Interop.IpHlpApi.ERROR_SUCCESS) { - Interop.IpHlpApi.IpPerAdapterInfo ipPerAdapterInfo = - Marshal.PtrToStructure(buffer); + Interop.IpHlpApi.IpPerAdapterInfo* ipPerAdapterInfo = (Interop.IpHlpApi.IpPerAdapterInfo*)buffer; - _autoConfigEnabled = ipPerAdapterInfo.autoconfigEnabled; - _autoConfigActive = ipPerAdapterInfo.autoconfigActive; + _autoConfigEnabled = ipPerAdapterInfo->autoconfigEnabled != 0; + _autoConfigActive = ipPerAdapterInfo->autoconfigActive != 0; } } finally diff --git a/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemNetworkInterface.cs b/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemNetworkInterface.cs index ed806788ae92d1..e04e9e62742795 100644 --- a/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemNetworkInterface.cs +++ b/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemNetworkInterface.cs @@ -15,7 +15,6 @@ internal sealed class SystemNetworkInterface : NetworkInterface private readonly string _id; private readonly string _description; private readonly byte[] _physicalAddress; - private readonly uint _addressLength; private readonly NetworkInterfaceType _type; private readonly OperationalStatus _operStatus; private readonly long _speed; @@ -110,14 +109,12 @@ internal static unsafe NetworkInterface[] GetNetworkInterfaces() if (result == Interop.IpHlpApi.ERROR_SUCCESS) { // Linked list of interfaces. - IntPtr ptr = buffer; - while (ptr != IntPtr.Zero) + Interop.IpHlpApi.IpAdapterAddresses* adapterAddresses = (Interop.IpHlpApi.IpAdapterAddresses*)buffer; + while (adapterAddresses != null) { // Traverse the list, marshal in the native structures, and create new NetworkInterfaces. - Interop.IpHlpApi.IpAdapterAddresses adapterAddresses = Marshal.PtrToStructure(ptr); - interfaceList.Add(new SystemNetworkInterface(in fixedInfo, in adapterAddresses)); - - ptr = adapterAddresses.next; + interfaceList.Add(new SystemNetworkInterface(in fixedInfo, in *adapterAddresses)); + adapterAddresses = adapterAddresses->next; } } } @@ -146,12 +143,11 @@ internal SystemNetworkInterface(in Interop.IpHlpApi.FIXED_INFO fixedInfo, in Int { // Store the common API information. _id = ipAdapterAddresses.AdapterName; - _name = ipAdapterAddresses.friendlyName; - _description = ipAdapterAddresses.description; + _name = ipAdapterAddresses.FriendlyName; + _description = ipAdapterAddresses.Description; _index = ipAdapterAddresses.index; - _physicalAddress = ipAdapterAddresses.address; - _addressLength = ipAdapterAddresses.addressLength; + _physicalAddress = ipAdapterAddresses.Address; _type = ipAdapterAddresses.type; _operStatus = ipAdapterAddresses.operStatus; @@ -172,12 +168,7 @@ internal SystemNetworkInterface(in Interop.IpHlpApi.FIXED_INFO fixedInfo, in Int public override PhysicalAddress GetPhysicalAddress() { - byte[] newAddr = new byte[_addressLength]; - - // Buffer.BlockCopy only supports int while addressLength is uint (see IpAdapterAddresses). - // Will throw OverflowException if addressLength > Int32.MaxValue. - Buffer.BlockCopy(_physicalAddress, 0, newAddr, 0, checked((int)_addressLength)); - return new PhysicalAddress(newAddr); + return new PhysicalAddress(_physicalAddress); } public override NetworkInterfaceType NetworkInterfaceType { get { return _type; } } diff --git a/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemUnicastIPAddressInformation.cs b/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemUnicastIPAddressInformation.cs index e9ed56ff453fe2..774d3f2246328a 100644 --- a/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemUnicastIPAddressInformation.cs +++ b/src/libraries/System.Net.NetworkInformation/src/System/Net/NetworkInformation/SystemUnicastIPAddressInformation.cs @@ -20,7 +20,7 @@ internal sealed class SystemUnicastIPAddressInformation : UnicastIPAddressInform private readonly uint _preferredLifetime; private readonly byte _prefixLength; - internal SystemUnicastIPAddressInformation(Interop.IpHlpApi.IpAdapterUnicastAddress adapterAddress) + internal SystemUnicastIPAddressInformation(in Interop.IpHlpApi.IpAdapterUnicastAddress adapterAddress) { IPAddress ipAddress = adapterAddress.address.MarshalIPAddress(); _innerInfo = new SystemIPAddressInformation(ipAddress, adapterAddress.flags); @@ -135,15 +135,15 @@ public override long DhcpLeaseLifetime } // Helper method that marshals the address information into the classes. - internal static UnicastIPAddressInformationCollection MarshalUnicastIpAddressInformationCollection(IntPtr ptr) + internal static unsafe UnicastIPAddressInformationCollection MarshalUnicastIpAddressInformationCollection(IntPtr ptr) { UnicastIPAddressInformationCollection addressList = new UnicastIPAddressInformationCollection(); - while (ptr != IntPtr.Zero) + Interop.IpHlpApi.IpAdapterUnicastAddress* pIpAdapterAddress = (Interop.IpHlpApi.IpAdapterUnicastAddress*)ptr; + while (pIpAdapterAddress != null) { - Interop.IpHlpApi.IpAdapterUnicastAddress addr = Marshal.PtrToStructure(ptr); - addressList.InternalAdd(new SystemUnicastIPAddressInformation(addr)); - ptr = addr.next; + addressList.InternalAdd(new SystemUnicastIPAddressInformation(in *pIpAdapterAddress)); + pIpAdapterAddress = pIpAdapterAddress->next; } return addressList; diff --git a/src/libraries/System.Security.Principal.Windows/src/System/Security/Principal/SID.cs b/src/libraries/System.Security.Principal.Windows/src/System/Security/Principal/SID.cs index 5fc23483f435a2..8b16387ca2274f 100644 --- a/src/libraries/System.Security.Principal.Windows/src/System/Security/Principal/SID.cs +++ b/src/libraries/System.Security.Principal.Windows/src/System/Security/Principal/SID.cs @@ -1034,8 +1034,8 @@ private static unsafe IdentityReferenceCollection TranslateToNTAccounts(Identity for (int i = 0; i < rdl.Entries; i++) { - Interop.LSA_TRUST_INFORMATION ti = (Interop.LSA_TRUST_INFORMATION)Marshal.PtrToStructure(new IntPtr((long)rdl.Domains + i * Marshal.SizeOf())); - ReferencedDomains[i] = Marshal.PtrToStringUni(ti.Name.Buffer, ti.Name.Length / sizeof(char)); + Interop.LSA_TRUST_INFORMATION* ti = (Interop.LSA_TRUST_INFORMATION*)rdl.Domains + i; + ReferencedDomains[i] = Marshal.PtrToStringUni(ti->Name.Buffer, ti->Name.Length / sizeof(char)); } Interop.LSA_TRANSLATED_NAME[] translatedNames = new Interop.LSA_TRANSLATED_NAME[sourceSids.Count]; From 5df4473a007fed1b49538ce6e7950ae60b4864a6 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Fri, 17 Jun 2022 10:30:12 -0700 Subject: [PATCH 194/337] Fix for timer scheduling happening on the incorrect thread when wasm threading is enabled (#70863) --- src/mono/mono/mini/mini-wasm.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/mono/mono/mini/mini-wasm.c b/src/mono/mono/mini/mini-wasm.c index 1647bea603da0f..67a282256c95bc 100644 --- a/src/mono/mono/mini/mini-wasm.c +++ b/src/mono/mono/mini/mini-wasm.c @@ -11,6 +11,12 @@ #include #include +#ifdef HOST_BROWSER +#ifndef DISABLE_THREADS +#include +#endif +#endif + static int mono_wasm_debug_level = 0; #ifndef DISABLE_JIT @@ -617,7 +623,13 @@ void mono_wasm_set_timeout (int timeout) { #ifdef HOST_BROWSER - mono_set_timeout (timeout); +#ifndef DISABLE_THREADS + if (!mono_threads_wasm_is_browser_thread ()) { + mono_threads_wasm_async_run_in_main_thread_vi ((void (*)(gpointer))mono_wasm_set_timeout, GINT_TO_POINTER(timeout)); + return; + } +#endif + mono_set_timeout (timeout); #endif } From 41d9c1cc0dca16743a54971930e81d60777af746 Mon Sep 17 00:00:00 2001 From: Eduardo Velarde <32459232+eduardo-vp@users.noreply.github.com> Date: Fri, 17 Jun 2022 10:56:23 -0700 Subject: [PATCH 195/337] Add event to capture min/max threads (#70063) Event ThreadPoolMinMaxThreads added. Parameters are: ushort MinWorkerThreads ushort MaxWorkerThreads ushort MinIOCompletionThreads ushort MaxIOCompletionThreads ushort ClrInstanceID It is fired in the ThreadPool constructor and in the SetMinThreads/SetMaxThreads functions. --- ....PortableThreadPool.NativeSinks.CoreCLR.cs | 4 + src/coreclr/gc/env/etmdummy.h | 1 + src/coreclr/vm/ClrEtwAll.man | 35 ++++++- src/coreclr/vm/nativeeventsource.cpp | 10 ++ src/coreclr/vm/nativeeventsource.h | 1 + src/coreclr/vm/qcallentrypoints.cpp | 1 + ...ntSource.PortableThreadPool.NativeSinks.cs | 17 ++++ ...veRuntimeEventSource.PortableThreadPool.cs | 39 ++++++++ .../System/Threading/PortableThreadPool.cs | 28 ++++++ .../tests/ThreadPoolTests.cs | 92 +++++++++++++++++++ ...rce.PortableThreadPool.NativeSinks.Mono.cs | 4 + src/mono/mono/component/event_pipe-stub.c | 20 ++++ src/mono/mono/component/event_pipe.c | 1 + src/mono/mono/component/event_pipe.h | 9 ++ src/mono/mono/eventpipe/ep-rt-mono.c | 18 ++++ src/mono/mono/eventpipe/ep-rt-mono.h | 8 ++ .../mono/eventpipe/gen-eventing-event-inc.lst | 1 + src/mono/mono/metadata/icall-decl.h | 1 + src/mono/mono/metadata/icall-def.h | 1 + src/mono/mono/metadata/icall-eventpipe.c | 29 ++++++ 20 files changed, 319 insertions(+), 1 deletion(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Eventing/NativeRuntimeEventSource.PortableThreadPool.NativeSinks.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Eventing/NativeRuntimeEventSource.PortableThreadPool.NativeSinks.CoreCLR.cs index f833134f370be8..cbf6e4665e78ce 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Eventing/NativeRuntimeEventSource.PortableThreadPool.NativeSinks.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Diagnostics/Eventing/NativeRuntimeEventSource.PortableThreadPool.NativeSinks.CoreCLR.cs @@ -24,6 +24,10 @@ internal sealed partial class NativeRuntimeEventSource : EventSource [LibraryImport(RuntimeHelpers.QCall)] internal static partial void LogThreadPoolWorkerThreadWait(uint ActiveWorkerThreadCount, uint RetiredWorkerThreadCount, ushort ClrInstanceID); + [NonEvent] + [LibraryImport(RuntimeHelpers.QCall)] + internal static partial void LogThreadPoolMinMaxThreads(ushort MinWorkerThreads, ushort MaxWorkerThreads, ushort MinIOCompletionThreads, ushort MaxIOCompletionThreads, ushort ClrInstanceID); + [NonEvent] [LibraryImport(RuntimeHelpers.QCall)] internal static partial void LogThreadPoolWorkerThreadAdjustmentSample(double Throughput, ushort ClrInstanceID); diff --git a/src/coreclr/gc/env/etmdummy.h b/src/coreclr/gc/env/etmdummy.h index 556372127577a9..575e3067cf89a1 100644 --- a/src/coreclr/gc/env/etmdummy.h +++ b/src/coreclr/gc/env/etmdummy.h @@ -78,6 +78,7 @@ #define FireEtwThreadPoolWorkerThreadAdjustmentAdjustment(AverageThroughput, NewWorkerThreadCount, Reason, ClrInstanceID) 0 #define FireEtwThreadPoolWorkerThreadAdjustmentStats(Duration, Throughput, ThreadWave, ThroughputWave, ThroughputErrorEstimate, AverageThroughputErrorEstimate, ThroughputRatio, Confidence, NewControlSetting, NewThreadWaveMagnitude, ClrInstanceID) 0 #define FireEtwThreadPoolWorkerThreadWait(ActiveWorkerThreadCount, RetiredWorkerThreadCount, ClrInstanceID) 0 +#define FireEtwThreadPoolMinMaxThreads (MinWorkerThreads, MaxWorkerThreads, MinIOCompletionThreads, MaxIOCompletionThreads, ClrInstanceID) 0 #define FireEtwThreadPoolWorkingThreadCount(Count, ClrInstanceID) 0 #define FireEtwThreadPoolEnqueue(WorkID, ClrInstanceID) 0 #define FireEtwThreadPoolDequeue(WorkID, ClrInstanceID) 0 diff --git a/src/coreclr/vm/ClrEtwAll.man b/src/coreclr/vm/ClrEtwAll.man index a55dec687c9620..761d650be7e51d 100644 --- a/src/coreclr/vm/ClrEtwAll.man +++ b/src/coreclr/vm/ClrEtwAll.man @@ -446,7 +446,13 @@ - + + + + + @@ -1579,6 +1585,24 @@ + +