From f4b1d3c3f86cf4835fb96740ec671bc0ac45c2d9 Mon Sep 17 00:00:00 2001 From: "Stephen A. Imhoff" Date: Fri, 17 Jul 2020 18:58:35 -0700 Subject: [PATCH 001/458] Correct test to account for PLINQ Zip unordered behavior (#39553) --- .../tests/QueryOperators/ZipTests.cs | 48 ++++++++++++++----- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/src/libraries/System.Linq.Parallel/tests/QueryOperators/ZipTests.cs b/src/libraries/System.Linq.Parallel/tests/QueryOperators/ZipTests.cs index 9e6446f538ed7e..c952169b8c37f2 100644 --- a/src/libraries/System.Linq.Parallel/tests/QueryOperators/ZipTests.cs +++ b/src/libraries/System.Linq.Parallel/tests/QueryOperators/ZipTests.cs @@ -56,15 +56,27 @@ public static void Zip_Unordered(int leftCount, int rightCount) { ParallelQuery leftQuery = UnorderedSources.Default(leftCount); ParallelQuery rightQuery = UnorderedSources.Default(leftCount, rightCount); - IntegerRangeSet seen = new IntegerRangeSet(0, Math.Min(leftCount, rightCount)); + IntegerRangeSet seen_left = new IntegerRangeSet(0, leftCount); + IntegerRangeSet seen_right = new IntegerRangeSet(leftCount, rightCount); + var expected_seen = Math.Min(leftCount, rightCount); foreach (var pair in leftQuery.Zip(rightQuery, (x, y) => KeyValuePair.Create(x, y))) { - // For unordered collections the pairing isn't actually guaranteed, but an effect of the implementation. - // If this test starts failing it should be updated, and possibly mentioned in release notes. - Assert.Equal(pair.Key + leftCount, pair.Value); - seen.Add(pair.Key); + // Can only validate about whether the elements have been previously seen, not anything about the order. + seen_left.Add(pair.Key); + seen_right.Add(pair.Value); + } + + // Zip truncates the longer collection, but which elements it leaves off is undefined when unordered. + Assert.Equal(expected_seen, seen_left.Count(kv => kv.Value)); + Assert.Equal(expected_seen, seen_right.Count(kv => kv.Value)); + if (leftCount <= rightCount) + { + seen_left.AssertComplete(); + } + if (rightCount <= leftCount) + { + seen_right.AssertComplete(); } - seen.AssertComplete(); } [Fact] @@ -106,16 +118,28 @@ public static void Zip_Unordered_NotPipelined(int leftCount, int rightCount) { ParallelQuery leftQuery = UnorderedSources.Default(leftCount); ParallelQuery rightQuery = UnorderedSources.Default(leftCount, rightCount); - IntegerRangeSet seen = new IntegerRangeSet(0, Math.Min(leftCount, rightCount)); + IntegerRangeSet seen_left = new IntegerRangeSet(0, leftCount); + IntegerRangeSet seen_right = new IntegerRangeSet(leftCount, rightCount); + var expected_seen = Math.Min(leftCount, rightCount); Assert.All(leftQuery.Zip(rightQuery, (x, y) => KeyValuePair.Create(x, y)).ToList(), pair => { - // For unordered collections the pairing isn't actually guaranteed, but an effect of the implementation. - // If this test starts failing it should be updated, and possibly mentioned in release notes. - Assert.Equal(pair.Key + leftCount, pair.Value); - seen.Add(pair.Key); + // Can only validate about whether the elements have been previously seen, not anything about the order. + seen_left.Add(pair.Key); + seen_right.Add(pair.Value); }); - seen.AssertComplete(); + + // Zip truncates the longer collection, but which elements it leaves off is undefined when unordered. + Assert.Equal(expected_seen, seen_left.Count(kv => kv.Value)); + Assert.Equal(expected_seen, seen_right.Count(kv => kv.Value)); + if (leftCount <= rightCount) + { + seen_left.AssertComplete(); + } + if (rightCount <= leftCount) + { + seen_right.AssertComplete(); + } } [Fact] From 406061553100bca30484265aaeacfa69686150cd Mon Sep 17 00:00:00 2001 From: Mike McLaughlin Date: Fri, 17 Jul 2020 19:40:55 -0700 Subject: [PATCH 002/458] Add breaking change version DAC API (ISOSDacInterface9 interface) (#39567) GetBreakingChangeVersion(int* version) Used in SOS to check if any of the runtime data structures it depends on has changed. Issue: https://github.com/dotnet/runtime/issues/27309 --- src/coreclr/src/debug/daccess/daccess.cpp | 4 + src/coreclr/src/debug/daccess/dacimpl.h | 6 +- src/coreclr/src/debug/daccess/request.cpp | 9 ++ src/coreclr/src/inc/sospriv.idl | 15 ++++ .../src/pal/prebuilt/idl/sospriv_i.cpp | 18 +++- src/coreclr/src/pal/prebuilt/inc/sospriv.h | 90 ++++++++++++++++++- 6 files changed, 135 insertions(+), 7 deletions(-) diff --git a/src/coreclr/src/debug/daccess/daccess.cpp b/src/coreclr/src/debug/daccess/daccess.cpp index 1e40f07a5c5e2c..e999ec866f7d04 100644 --- a/src/coreclr/src/debug/daccess/daccess.cpp +++ b/src/coreclr/src/debug/daccess/daccess.cpp @@ -3293,6 +3293,10 @@ ClrDataAccess::QueryInterface(THIS_ { ifaceRet = static_cast(this); } + else if (IsEqualIID(interfaceId, __uuidof(ISOSDacInterface9))) + { + ifaceRet = static_cast(this); + } else { *iface = NULL; diff --git a/src/coreclr/src/debug/daccess/dacimpl.h b/src/coreclr/src/debug/daccess/dacimpl.h index efbd19da6f1a58..c0809924bc3e1d 100644 --- a/src/coreclr/src/debug/daccess/dacimpl.h +++ b/src/coreclr/src/debug/daccess/dacimpl.h @@ -840,7 +840,8 @@ class ClrDataAccess public ISOSDacInterface5, public ISOSDacInterface6, public ISOSDacInterface7, - public ISOSDacInterface8 + public ISOSDacInterface8, + public ISOSDacInterface9 { public: ClrDataAccess(ICorDebugDataTarget * pTarget, ICLRDataTarget * pLegacyTarget=0); @@ -1205,6 +1206,9 @@ class ClrDataAccess virtual HRESULT STDMETHODCALLTYPE GetAssemblyLoadContext(CLRDATA_ADDRESS methodTable, CLRDATA_ADDRESS* assemblyLoadContext); + // ISOSDacInterface9 + virtual HRESULT STDMETHODCALLTYPE GetBreakingChangeVersion(int* pVersion); + // // ClrDataAccess. // diff --git a/src/coreclr/src/debug/daccess/request.cpp b/src/coreclr/src/debug/daccess/request.cpp index b9a589fd609fa3..4c6671149bee12 100644 --- a/src/coreclr/src/debug/daccess/request.cpp +++ b/src/coreclr/src/debug/daccess/request.cpp @@ -4732,3 +4732,12 @@ HRESULT ClrDataAccess::GetAssemblyLoadContext(CLRDATA_ADDRESS methodTable, CLRDA SOSDacLeave(); return hr; } + +HRESULT ClrDataAccess::GetBreakingChangeVersion(int* pVersion) +{ + if (pVersion == nullptr) + return E_INVALIDARG; + + *pVersion = SOS_BREAKING_CHANGE_VERSION; + return S_OK; +} diff --git a/src/coreclr/src/inc/sospriv.idl b/src/coreclr/src/inc/sospriv.idl index d5a5913f736fe5..770d5b56f749cc 100644 --- a/src/coreclr/src/inc/sospriv.idl +++ b/src/coreclr/src/inc/sospriv.idl @@ -409,3 +409,18 @@ interface ISOSDacInterface8 : IUnknown HRESULT GetAssemblyLoadContext(CLRDATA_ADDRESS methodTable, CLRDATA_ADDRESS* assemblyLoadContext); } + +// Increment anytime there is a change in the data structures that SOS depends on like +// stress log structs (StressMsg, StressLogChunck, ThreadStressLog, etc), exception +// stack traces (StackTraceElement), the PredefinedTlsSlots enums, etc. +cpp_quote("#define SOS_BREAKING_CHANGE_VERSION 1") + +[ + object, + local, + uuid(4eca42d8-7e7b-4c8a-a116-7bfbf6929267) +] +interface ISOSDacInterface9 : IUnknown +{ + HRESULT GetBreakingChangeVersion(int* pVersion); +} diff --git a/src/coreclr/src/pal/prebuilt/idl/sospriv_i.cpp b/src/coreclr/src/pal/prebuilt/idl/sospriv_i.cpp index 993737f7a0b358..ee2cd1d82010b3 100644 --- a/src/coreclr/src/pal/prebuilt/idl/sospriv_i.cpp +++ b/src/coreclr/src/pal/prebuilt/idl/sospriv_i.cpp @@ -1,6 +1,3 @@ -// 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 IIDs and CLSIDs */ @@ -8,7 +5,17 @@ /* link this file in with the server and any clients */ - /* File created by MIDL compiler version 8.00.0613 */ + /* File created by MIDL compiler version 8.01.0622 */ +/* at Mon Jan 18 19:14:07 2038 + */ +/* Compiler settings for C:/ssd/runtime/src/coreclr/src/inc/sospriv.idl: + Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.01.0622 + protocol : dce , 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( ) */ #pragma warning( disable: 4049 ) /* more than 64k source lines */ @@ -95,6 +102,9 @@ MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface7,0xc1020dde,0xfe98,0x4536,0xa5,0x3b,0 MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface8,0xc12f35a9,0xe55c,0x4520,0xa8,0x94,0xb3,0xdc,0x51,0x65,0xdf,0xce); + +MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface9,0x4eca42d8,0x7e7b,0x4c8a,0xa1,0x16,0x7b,0xfb,0xf6,0x92,0x92,0x67); + #undef MIDL_DEFINE_GUID #ifdef __cplusplus diff --git a/src/coreclr/src/pal/prebuilt/inc/sospriv.h b/src/coreclr/src/pal/prebuilt/inc/sospriv.h index d76eac0ead666f..6fe59addcfe218 100644 --- a/src/coreclr/src/pal/prebuilt/inc/sospriv.h +++ b/src/coreclr/src/pal/prebuilt/inc/sospriv.h @@ -2644,7 +2644,7 @@ EXTERN_C const IID IID_ISOSDacInterface8; #define ISOSDacInterface8_GetFinalizationFillPointersSvr(This,heapAddr,cFillPointers,pFinalizationFillPointers,pNeeded) \ ( (This)->lpVtbl -> GetFinalizationFillPointersSvr(This,heapAddr,cFillPointers,pFinalizationFillPointers,pNeeded) ) -#define ISOSDacInterface8_GetAssemblyLoadContext(This,methodTable,assemblyLoadContext) \ +#define ISOSDacInterface8_GetAssemblyLoadContext(This,methodTable,assemblyLoadContext) \ ( (This)->lpVtbl -> GetAssemblyLoadContext(This,methodTable,assemblyLoadContext) ) #endif /* COBJMACROS */ @@ -2658,6 +2658,93 @@ EXTERN_C const IID IID_ISOSDacInterface8; #endif /* __ISOSDacInterface8_INTERFACE_DEFINED__ */ +/* interface __MIDL_itf_sospriv_0000_0012 */ +/* [local] */ + +#define SOS_BREAKING_CHANGE_VERSION 1 + + +extern RPC_IF_HANDLE __MIDL_itf_sospriv_0000_0012_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_sospriv_0000_0012_v0_0_s_ifspec; + +#ifndef __ISOSDacInterface9_INTERFACE_DEFINED__ +#define __ISOSDacInterface9_INTERFACE_DEFINED__ + +/* interface ISOSDacInterface9 */ +/* [uuid][local][object] */ + + +EXTERN_C const IID IID_ISOSDacInterface9; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("4eca42d8-7e7b-4c8a-a116-7bfbf6929267") + ISOSDacInterface9 : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetBreakingChangeVersion( + int *pVersion) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ISOSDacInterface9Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ISOSDacInterface9 * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ISOSDacInterface9 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ISOSDacInterface9 * This); + + HRESULT ( STDMETHODCALLTYPE *GetBreakingChangeVersion )( + ISOSDacInterface9 * This, + int *pVersion); + + END_INTERFACE + } ISOSDacInterface9Vtbl; + + interface ISOSDacInterface9 + { + CONST_VTBL struct ISOSDacInterface9Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ISOSDacInterface9_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ISOSDacInterface9_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ISOSDacInterface9_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ISOSDacInterface9_GetBreakingChangeVersion(This,pVersion) \ + ( (This)->lpVtbl -> GetBreakingChangeVersion(This,pVersion) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + +#endif /* __ISOSDacInterface9_INTERFACE_DEFINED__ */ + + /* Additional Prototypes for ALL interfaces */ /* end of Additional Prototypes */ @@ -2668,4 +2755,3 @@ EXTERN_C const IID IID_ISOSDacInterface8; #endif - From 328fc0f9863fac35d5cfc342ba3dbd453bfb7e51 Mon Sep 17 00:00:00 2001 From: monojenkins Date: Sat, 18 Jul 2020 00:15:55 -0400 Subject: [PATCH 003/458] Remove some non-unicode characters from source code (#39527) I've been noticing some C compiler warnings during build of dotnet/runtime. ``` C:\Users\gotos\source\repos\runtime\src\mono\mono\mini\mini-runtime.c(1920,1): warning C4819: The file contains a character that cannot be represented in the current code page (949). Save the file in Unicode format to prevent data loss [C:\Users\gotos\source\repos\runtime\src\mono\msvc\libmono-dynamic.vcxproj] C:\Users\gotos\source\repos\runtime\src\mono\mono\mini\method-to-ir.c(5337,1): warning C4819: The file contains a character that cannot be represented in the current code page (949). Save the file in Unicode format to prevent data loss [C:\Users\gotos\source\repos\runtime\src\mono\msvc\libmono-dynamic.vcxproj] ``` Apparently there are some smart quotes and a zero-width space (Why?!) in some of Mono's source code. This PR removes those needless unicode characters. I hope that opening a PR here will result in the changed code being mirrored to dotnet/runtime repo as well? Co-authored-by: Gnbrkm41 --- src/mono/mono/mini/method-to-ir.c | 4 ++-- src/mono/mono/mini/mini-runtime.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mono/mono/mini/method-to-ir.c b/src/mono/mono/mini/method-to-ir.c index efcecb831ab9f1..56f2eca3b8cdf4 100644 --- a/src/mono/mono/mini/method-to-ir.c +++ b/src/mono/mono/mini/method-to-ir.c @@ -5497,9 +5497,9 @@ is_supported_tailcall (MonoCompile *cfg, const guint8 *ip, MonoMethod *method, M // http://www.mono-project.com/docs/advanced/runtime/docs/generic-sharing/ // // 1. Non-generic non-static methods of reference types have access to the - // RGCTX via the “this” argument (this->vtable->rgctx). + // RGCTX via the "this" argument (this->vtable->rgctx). // 2. a Non-generic static methods of reference types and b. non-generic methods - // of value types need to be passed a pointer to the caller’s class’s VTable in the MONO_ARCH_RGCTX_REG register. + // of value types need to be passed a pointer to the caller's class's VTable in the MONO_ARCH_RGCTX_REG register. // 3. Generic methods need to be passed a pointer to the MRGCTX in the MONO_ARCH_RGCTX_REG register // // That is what vtable_arg is here (always?). diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index c180d303d4d22a..53ef84742998e6 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -2014,7 +2014,7 @@ mono_enable_jit_dump (void) add_file_header_info (&header); if (perf_dump_file) { fwrite (&header, sizeof (header), 1, perf_dump_file); - //This informs perf of the presence of the jitdump file and support for the feature.​ + //This informs perf of the presence of the jitdump file and support for the feature. perf_dump_mmap_addr = mmap (NULL, sizeof (header), PROT_READ | PROT_EXEC, MAP_PRIVATE, fileno (perf_dump_file), 0); } From 177d6f1a0bfdc853ae9ffeef4be99ff984c4f5dd Mon Sep 17 00:00:00 2001 From: Levi Broderick Date: Fri, 17 Jul 2020 21:18:59 -0700 Subject: [PATCH 004/458] Implement IComparable on Rune (#39541) --- .../src/Resources/Strings.resx | 3 +++ .../src/System/Text/Rune.cs | 20 +++++++++++++++++-- .../System.Runtime/ref/System.Runtime.cs | 3 ++- .../tests/System/Text/RuneTests.cs | 20 ++++++++++++++++++- .../System.Utf8String.Experimental.Rune.cs | 3 ++- .../src/Resources/Strings.resx | 3 +++ 6 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx index 982f0b8e4a2100..5628d08e87fd3b 100644 --- a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx +++ b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx @@ -3766,6 +3766,9 @@ Object must be of type Half. + + Object must be of type Rune. + BinaryFormatter serialization and deserialization are disabled within this application. See https://aka.ms/binaryformatter for more information. diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Rune.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Rune.cs index f7dfd4c2c595d6..f2e1aa0c14acb2 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Rune.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Rune.cs @@ -17,7 +17,7 @@ namespace System.Text /// assuming that the underlying instance is well-formed. /// [DebuggerDisplay("{DebuggerDisplay,nq}")] - public readonly struct Rune : IComparable, IEquatable + public readonly struct Rune : IComparable, IComparable, IEquatable { internal const int MaxUtf16CharsPerRune = 2; // supplementary plane code points are encoded as 2 UTF-16 code units internal const int MaxUtf8BytesPerRune = 4; // supplementary plane code points are encoded as 4 UTF-8 code units @@ -269,7 +269,7 @@ private static Rune ChangeCaseCultureAware(Rune rune, CultureInfo culture, bool } #endif - public int CompareTo(Rune other) => _value.CompareTo(other._value); + public int CompareTo(Rune other) => this.Value - other.Value; // values don't span entire 32-bit domain; won't integer overflow /// /// Decodes the at the beginning of the provided UTF-16 source buffer. @@ -1437,5 +1437,21 @@ public static Rune ToUpperInvariant(Rune value) return ChangeCaseCultureAware(value, CultureInfo.InvariantCulture, toUpper: true); #endif } + + /// + int IComparable.CompareTo(object? obj) + { + if (obj is null) + { + return 1; // non-null ("this") always sorts after null + } + + if (obj is Rune other) + { + return this.CompareTo(other); + } + + throw new ArgumentException(SR.Arg_MustBeRune); + } } } diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 75def9c62e0750..8140f3c8fa4de2 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -10588,7 +10588,7 @@ public enum NormalizationForm FormKC = 5, FormKD = 6, } - public readonly partial struct Rune : System.IComparable, System.IEquatable + public readonly partial struct Rune : System.IComparable, System.IComparable, System.IEquatable { private readonly int _dummyPrimitive; public Rune(char ch) { throw null; } @@ -10653,6 +10653,7 @@ public enum NormalizationForm public bool TryEncodeToUtf16(System.Span destination, out int charsWritten) { throw null; } public bool TryEncodeToUtf8(System.Span destination, out int bytesWritten) { throw null; } public static bool TryGetRuneAt(string input, int index, out System.Text.Rune value) { throw null; } + int System.IComparable.CompareTo(object? obj) { throw null; } } public sealed partial class StringBuilder : System.Runtime.Serialization.ISerializable { diff --git a/src/libraries/System.Runtime/tests/System/Text/RuneTests.cs b/src/libraries/System.Runtime/tests/System/Text/RuneTests.cs index 0f97b57102f44b..3c897871e54336 100644 --- a/src/libraries/System.Runtime/tests/System/Text/RuneTests.cs +++ b/src/libraries/System.Runtime/tests/System/Text/RuneTests.cs @@ -157,6 +157,7 @@ public static void CompareTo_And_ComparisonOperators(int first, int other, int e Rune b = new Rune(other); Assert.Equal(expectedSign, Math.Sign(a.CompareTo(b))); + Assert.Equal(expectedSign, Math.Sign(((IComparable)a).CompareTo(b))); Assert.Equal(expectedSign < 0, a < b); Assert.Equal(expectedSign <= 0, a <= b); Assert.Equal(expectedSign > 0, a > b); @@ -474,7 +475,24 @@ public static void Operators_And_CompareTo(uint scalarValueLeft, uint scalarValu Assert.Equal(scalarValueLeft <= scalarValueRight, left <= right); Assert.Equal(scalarValueLeft > scalarValueRight, left > right); Assert.Equal(scalarValueLeft >= scalarValueRight, left >= right); - Assert.Equal(scalarValueLeft.CompareTo(scalarValueRight), left.CompareTo(right)); + Assert.Equal(Math.Sign(scalarValueLeft.CompareTo(scalarValueRight)), Math.Sign(left.CompareTo(right))); + Assert.Equal(Math.Sign(((IComparable)scalarValueLeft).CompareTo(scalarValueRight)), Math.Sign(((IComparable)left).CompareTo(right))); + } + + [Theory] + [InlineData(0)] + [InlineData(0x10FFFF)] + public static void NonGenericCompareTo_NonNullAlwaysGreaterThanNull(uint scalarValue) + { + Assert.Equal(1, Math.Sign(((IComparable)new Rune(scalarValue)).CompareTo(null))); + } + + [Fact] + public static void NonGenericCompareTo_GivenNonRuneArgument_ThrowsArgumentException() + { + IComparable rune = new Rune(0); + + Assert.Throws(() => rune.CompareTo(0 /* int32 */)); } [Fact] diff --git a/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.Rune.cs b/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.Rune.cs index e3b4d3eb518bbb..da7e4be0f23403 100644 --- a/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.Rune.cs +++ b/src/libraries/System.Utf8String.Experimental/ref/System.Utf8String.Experimental.Rune.cs @@ -6,7 +6,7 @@ namespace System.Text { - public readonly partial struct Rune : System.IComparable, System.IEquatable + public readonly partial struct Rune : System.IComparable, System.IComparable, System.IEquatable { private readonly int _dummyPrimitive; public Rune(char ch) { throw null; } @@ -71,5 +71,6 @@ namespace System.Text public bool TryEncodeToUtf16(System.Span destination, out int charsWritten) { throw null; } public bool TryEncodeToUtf8(System.Span destination, out int bytesWritten) { throw null; } public static bool TryGetRuneAt(string input, int index, out System.Text.Rune value) { throw null; } + int IComparable.CompareTo(object? obj) { throw null; } } } diff --git a/src/libraries/System.Utf8String.Experimental/src/Resources/Strings.resx b/src/libraries/System.Utf8String.Experimental/src/Resources/Strings.resx index a02a1757a69029..3d5159021118a3 100644 --- a/src/libraries/System.Utf8String.Experimental/src/Resources/Strings.resx +++ b/src/libraries/System.Utf8String.Experimental/src/Resources/Strings.resx @@ -165,4 +165,7 @@ The input buffer contained ill-formed UTF-8 data. + + Object must be of type Rune. + \ No newline at end of file From 1d12f2b9bab2787ce8130145f67ec4a5df72e102 Mon Sep 17 00:00:00 2001 From: Matt Kotsenas Date: Fri, 17 Jul 2020 21:22:36 -0700 Subject: [PATCH 005/458] Remove unused local variables and methods from System.Drawing.Common (#39551) * Remove unused local variables and methods from System.Drawing.Common Remove unused locals, and update a few unit tests that has no asserts. * Revert adding asserts in tests Since the tests run across different printer hardware they can't take a dependency on the default printer settings. Revert adding asserts in these cases so the tests still verify that the properties don't throw. --- .../tests/BufferedGraphicsTests.cs | 2 - .../Drawing2D/GraphicsPathIteratorTests.cs | 1 - .../System.Drawing.Common/tests/FontTests.cs | 2 +- .../tests/GraphicsTests.cs | 69 +++++++++---------- .../tests/Graphics_DrawBezierTests.cs | 4 +- .../tests/Graphics_DrawLineTests.cs | 4 +- .../tests/Imaging/ColorMatrixTests.cs | 2 +- .../tests/mono/System.Drawing/BitmapTests.cs | 16 ----- .../mono/System.Drawing/GraphicsTests.cs | 10 --- 9 files changed, 39 insertions(+), 71 deletions(-) diff --git a/src/libraries/System.Drawing.Common/tests/BufferedGraphicsTests.cs b/src/libraries/System.Drawing.Common/tests/BufferedGraphicsTests.cs index bdb250e0bb4668..de5d15ed02cb94 100644 --- a/src/libraries/System.Drawing.Common/tests/BufferedGraphicsTests.cs +++ b/src/libraries/System.Drawing.Common/tests/BufferedGraphicsTests.cs @@ -72,8 +72,6 @@ public void Render_ParameterlessWithTargetGraphics_Success() [ConditionalFact(Helpers.IsDrawingSupported)] public void Render_ParameterlessWithNullTargetGraphics_Success() { - Color color = Color.FromArgb(255, 0, 0, 0); - using (var context = new BufferedGraphicsContext()) using (var image = new Bitmap(3, 3)) using (Graphics graphics = Graphics.FromImage(image)) diff --git a/src/libraries/System.Drawing.Common/tests/Drawing2D/GraphicsPathIteratorTests.cs b/src/libraries/System.Drawing.Common/tests/Drawing2D/GraphicsPathIteratorTests.cs index 4e820c12115525..45ae21bbe2ec1c 100644 --- a/src/libraries/System.Drawing.Common/tests/Drawing2D/GraphicsPathIteratorTests.cs +++ b/src/libraries/System.Drawing.Common/tests/Drawing2D/GraphicsPathIteratorTests.cs @@ -251,7 +251,6 @@ public void Rewind_Success() gp.StartFigure(); gp.AddLine(20, 21, 22, 23); gp.AddBezier(5, 6, 7, 8, 9, 10, 11, 12); - byte[] types = new byte[] { 0, 3, 3, 3, 1, 33, 0, 1 }; using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp)) { diff --git a/src/libraries/System.Drawing.Common/tests/FontTests.cs b/src/libraries/System.Drawing.Common/tests/FontTests.cs index c314b21c6708d0..067ff89a7be6e8 100644 --- a/src/libraries/System.Drawing.Common/tests/FontTests.cs +++ b/src/libraries/System.Drawing.Common/tests/FontTests.cs @@ -714,7 +714,7 @@ public void FromLogFont_UnblittableStruct() using (var image = new Bitmap(10, 10)) using (Graphics graphics = Graphics.FromImage(image)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { var logFont = new UnblittableLOGFONT diff --git a/src/libraries/System.Drawing.Common/tests/GraphicsTests.cs b/src/libraries/System.Drawing.Common/tests/GraphicsTests.cs index 5b558c7dad251d..ea823989bceb6e 100644 --- a/src/libraries/System.Drawing.Common/tests/GraphicsTests.cs +++ b/src/libraries/System.Drawing.Common/tests/GraphicsTests.cs @@ -63,7 +63,7 @@ public void GetHdc_NotReleased_ThrowsInvalidOperationException() using (var bitmap = new Bitmap(10, 10)) using (Graphics graphics = Graphics.FromImage(bitmap)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.GetHdc()); @@ -416,7 +416,7 @@ public void CompositingMode_GetSetWhenBusy_ThrowsInvalidOperationException() using (var image = new Bitmap(10, 10)) using (Graphics graphics = Graphics.FromImage(image)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.CompositingMode); @@ -510,7 +510,7 @@ public void CompositingQuality_GetSetWhenBusy_ThrowsInvalidOperationException() using (var image = new Bitmap(10, 10)) using (Graphics graphics = Graphics.FromImage(image)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.CompositingQuality); @@ -573,7 +573,7 @@ public void DpiX_GetWhenBusy_ThrowsInvalidOperationException() using (var image = new Bitmap(10, 10)) using (Graphics graphics = Graphics.FromImage(image)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.DpiX); @@ -604,7 +604,7 @@ public void DpiY_GetWhenBusy_ThrowsInvalidOperationException() using (var image = new Bitmap(10, 10)) using (Graphics graphics = Graphics.FromImage(image)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.DpiX); @@ -656,7 +656,7 @@ public void Flush_Busy_ThrowsInvalidOperationException() using (var image = new Bitmap(10, 10)) using (Graphics graphics = Graphics.FromImage(image)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.Flush()); @@ -730,7 +730,7 @@ public void InterpolationMode_GetSetWhenBusy_ThrowsInvalidOperationException() using (var image = new Bitmap(10, 10)) using (Graphics graphics = Graphics.FromImage(image)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.InterpolationMode); @@ -792,7 +792,7 @@ public void PageScale_GetSetWhenBusy_ThrowsInvalidOperationException() using (var image = new Bitmap(10, 10)) using (Graphics graphics = Graphics.FromImage(image)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.PageScale); @@ -864,7 +864,7 @@ public void PageUnit_GetSetWhenBusy_ThrowsInvalidOperationException() using (var image = new Bitmap(10, 10)) using (Graphics graphics = Graphics.FromImage(image)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.PageUnit); @@ -935,7 +935,7 @@ public void PixelOffsetMode_GetSetWhenBusy_ThrowsInvalidOperationException() using (var image = new Bitmap(10, 10)) using (Graphics graphics = Graphics.FromImage(image)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.PixelOffsetMode); @@ -1004,7 +1004,6 @@ public static IEnumerable RenderingOrigin_TestData() [MemberData(nameof(RenderingOrigin_TestData))] public void RenderingOrigin_SetToCustom_RendersExpected(Point renderingOrigin, Color[][] expectedRendering) { - Color empty = Color.FromArgb(255, 0, 0, 0); Color red = Color.FromArgb(Color.Red.ToArgb()); using (var image = new Bitmap(3, 3)) @@ -1026,7 +1025,7 @@ public void RenderingOrigin_GetSetWhenBusy_ThrowsInvalidOperationException() using (var image = new Bitmap(10, 10)) using (Graphics graphics = Graphics.FromImage(image)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.RenderingOrigin); @@ -1097,7 +1096,7 @@ public void SmoothingMode_GetSetWhenBusy_ThrowsInvalidOperationException() using (var image = new Bitmap(10, 10)) using (Graphics graphics = Graphics.FromImage(image)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.SmoothingMode); @@ -1156,7 +1155,7 @@ public void TextContrast_GetSetWhenBusy_ThrowsInvalidOperationException() using (var image = new Bitmap(10, 10)) using (Graphics graphics = Graphics.FromImage(image)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.TextContrast); @@ -1218,7 +1217,7 @@ public void TextRenderingHint_GetSetWhenBusy_ThrowsInvalidOperationException() using (var image = new Bitmap(10, 10)) using (Graphics graphics = Graphics.FromImage(image)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.TextRenderingHint); @@ -1315,7 +1314,7 @@ public void Transform_GetSetWhenBusy_ThrowsInvalidOperationException() using (Graphics graphics = Graphics.FromImage(image)) using (var matrix = new Matrix()) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.Transform); @@ -1364,7 +1363,7 @@ public void ResetTransform_Busy_ThrowsInvalidOperationException() using (var image = new Bitmap(10, 10)) using (Graphics graphics = Graphics.FromImage(image)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.ResetTransform()); @@ -1483,7 +1482,7 @@ public void MultiplyTransform_Busy_ThrowsInvalidOperationException() using (Graphics graphics = Graphics.FromImage(image)) using (var matrix = new Matrix()) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.MultiplyTransform(matrix)); @@ -1570,7 +1569,7 @@ public void TranslateTransform_Busy_ThrowsInvalidOperationException() using (var image = new Bitmap(10, 10)) using (Graphics graphics = Graphics.FromImage(image)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.TranslateTransform(0, 0)); @@ -1664,7 +1663,7 @@ public void ScaleTransform_Busy_ThrowsInvalidOperationException() using (var image = new Bitmap(10, 10)) using (Graphics graphics = Graphics.FromImage(image)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.ScaleTransform(0, 0)); @@ -1751,7 +1750,7 @@ public void RotateTransform_Busy_ThrowsInvalidOperationException() using (var image = new Bitmap(10, 10)) using (Graphics graphics = Graphics.FromImage(image)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.RotateTransform(0)); @@ -1814,8 +1813,6 @@ public void CopyFromScreen_OutOfRange_DoesNotAffectGraphics(int sourceX, int sou [InlineData(1, 1, 2, 2, 3, 3)] public void CopyFromScreen_ValidRange_AffectsGraphics(int sourceX, int sourceY, int destinationX, int destinationY, int width, int height) { - Size screenSize = Helpers.GetHWndRect(IntPtr.Zero).Size; - Color color = Color.FromArgb(2, 3, 4); using (var image = new Bitmap(10, 10)) using (Graphics graphics = Graphics.FromImage(image)) @@ -1934,7 +1931,7 @@ public void CopyFromScreen_Busy_ThrowsInvalidOperationException() using (var image = new Bitmap(10, 10)) using (Graphics graphics = Graphics.FromImage(image)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.CopyFromScreen(0, 0, 0, 0, Size.Empty)); @@ -2198,7 +2195,7 @@ public void TransformPoints_Busy_ThrowsInvalidOperationException() using (var image = new Bitmap(10, 10)) using (Graphics graphics = Graphics.FromImage(image)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.TransformPoints(CoordinateSpace.Page, CoordinateSpace.Page, new Point[] { Point.Empty })); @@ -2250,7 +2247,7 @@ public void GetNearestColor_Busy_ThrowsInvalidOperationException() using (var image = new Bitmap(10, 10)) using (Graphics graphics = Graphics.FromImage(image)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.GetNearestColor(Color.Red)); @@ -2344,7 +2341,7 @@ public void DrawArc_Busy_ThrowsInvalidOperationException() using (Graphics graphics = Graphics.FromImage(image)) using (var pen = new Pen(Color.Red)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.DrawArc(pen, new Rectangle(0, 0, 1, 1), 0, 90)); @@ -2412,7 +2409,7 @@ public void DrawRectangle_Busy_ThrowsInvalidOperationException() using (Graphics graphics = Graphics.FromImage(image)) using (var pen = new Pen(Color.Red)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.DrawRectangle(pen, new Rectangle(0, 0, 1, 1))); @@ -2498,7 +2495,7 @@ public void DrawRectangles_Busy_ThrowsInvalidOperationException() using (Graphics graphics = Graphics.FromImage(image)) using (var pen = new Pen(Color.Red)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.DrawRectangles(pen, new Rectangle[2])); @@ -2563,7 +2560,7 @@ public void DrawEllipse_Busy_ThrowsInvalidOperationException() using (Graphics graphics = Graphics.FromImage(image)) using (var pen = new Pen(Color.Red)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.DrawEllipse(pen, new Rectangle(0, 0, 1, 1))); @@ -2661,7 +2658,7 @@ public void DrawPie_Busy_ThrowsInvalidOperationException() using (Graphics graphics = Graphics.FromImage(image)) using (var pen = new Pen(Color.Red)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.DrawPie(pen, new Rectangle(0, 0, 1, 1), 0, 90)); @@ -2751,7 +2748,7 @@ public void DrawPolygon_Busy_ThrowsInvalidOperationException() using (Graphics graphics = Graphics.FromImage(image)) using (var pen = new Pen(Color.Red)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.DrawPolygon(pen, new Point[2])); @@ -2837,7 +2834,7 @@ public void DrawPath_Busy_ThrowsInvalidOperationException() using (var pen = new Pen(Color.Red)) using (var graphicsPath = new GraphicsPath()) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.DrawPath(pen, graphicsPath)); @@ -2961,7 +2958,7 @@ public void DrawCurve_Busy_ThrowsInvalidOperationException() using (Graphics graphics = Graphics.FromImage(image)) using (var pen = new Pen(Color.Red)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.DrawCurve(pen, new Point[2])); @@ -3066,7 +3063,7 @@ public void DrawClosedCurve_Busy_ThrowsInvalidOperationException() using (Graphics graphics = Graphics.FromImage(image)) using (var pen = new Pen(Color.Red)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.DrawClosedCurve(pen, new Point[3])); @@ -3125,7 +3122,7 @@ public void Clear_Busy_ThrowsInvalidOperationException() using (Graphics graphics = Graphics.FromImage(image)) using (var pen = new Pen(Color.Red)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.Clear(Color.Red)); diff --git a/src/libraries/System.Drawing.Common/tests/Graphics_DrawBezierTests.cs b/src/libraries/System.Drawing.Common/tests/Graphics_DrawBezierTests.cs index ea8d68a3533444..c822db2a9d15b2 100644 --- a/src/libraries/System.Drawing.Common/tests/Graphics_DrawBezierTests.cs +++ b/src/libraries/System.Drawing.Common/tests/Graphics_DrawBezierTests.cs @@ -101,7 +101,7 @@ public void DrawBezier_Busy_ThrowsInvalidOperationException() using (Graphics graphics = Graphics.FromImage(image)) using (var pen = new Pen(Color.Red)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.DrawBezier(pen, 1, 2, 3, 4, 5, 6, 7, 8)); @@ -190,7 +190,7 @@ public void DrawBeziers_Busy_ThrowsInvalidOperationException() using (Graphics graphics = Graphics.FromImage(image)) using (var pen = new Pen(Color.Red)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.DrawBeziers(pen, new Point[2])); diff --git a/src/libraries/System.Drawing.Common/tests/Graphics_DrawLineTests.cs b/src/libraries/System.Drawing.Common/tests/Graphics_DrawLineTests.cs index aa5da3fca26bad..e25d506eb84b99 100644 --- a/src/libraries/System.Drawing.Common/tests/Graphics_DrawLineTests.cs +++ b/src/libraries/System.Drawing.Common/tests/Graphics_DrawLineTests.cs @@ -76,7 +76,7 @@ public void DrawLine_Busy_ThrowsInvalidOperationException() using (Graphics graphics = Graphics.FromImage(image)) using (var pen = new Pen(Color.Red)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.DrawLine(pen, Point.Empty, Point.Empty)); @@ -166,7 +166,7 @@ public void DrawLines_Busy_ThrowsInvalidOperationException() using (Graphics graphics = Graphics.FromImage(image)) using (var pen = new Pen(Color.Red)) { - IntPtr hdc = graphics.GetHdc(); + graphics.GetHdc(); try { Assert.Throws(() => graphics.DrawLines(pen, new Point[2])); diff --git a/src/libraries/System.Drawing.Common/tests/Imaging/ColorMatrixTests.cs b/src/libraries/System.Drawing.Common/tests/Imaging/ColorMatrixTests.cs index cf12d3f1825431..35d706af8fda4b 100644 --- a/src/libraries/System.Drawing.Common/tests/Imaging/ColorMatrixTests.cs +++ b/src/libraries/System.Drawing.Common/tests/Imaging/ColorMatrixTests.cs @@ -155,7 +155,7 @@ public void AccessToNotExistingElement_ThrowsIndexOutOfRangeException() new float[] { 4.0f, 4.1f, 4.2f, 4.3f, 4.4f, 4.5f }, new float[] { 5.0f, 5.1f, 5.2f, 5.3f, 5.4f, 5.5f } }); - Assert.Throws(() => { var x = cm[5, 5]; }); + Assert.Throws(() => _ = cm[5, 5]); } [ConditionalFact(Helpers.IsDrawingSupported)] diff --git a/src/libraries/System.Drawing.Common/tests/mono/System.Drawing/BitmapTests.cs b/src/libraries/System.Drawing.Common/tests/mono/System.Drawing/BitmapTests.cs index e48c366b75565c..4fecd70d8a0d2f 100644 --- a/src/libraries/System.Drawing.Common/tests/mono/System.Drawing/BitmapTests.cs +++ b/src/libraries/System.Drawing.Common/tests/mono/System.Drawing/BitmapTests.cs @@ -528,8 +528,6 @@ public void Rotate() [PlatformSpecific(TestPlatforms.AnyUnix)] public void Rotate1bit4bit(string file, RotateFlipType type, string md5) { - StringBuilder md5s = new StringBuilder(); - using (Bitmap bmp = new Bitmap(Helpers.GetTestBitmapPath(file))) { Assert.Equal(md5, RotateIndexedBmp(bmp, type)); @@ -887,20 +885,6 @@ public void BmpDataStride1() } } - private Stream Serialize(object o) - { - MemoryStream ms = new MemoryStream(); - IFormatter formatter = new BinaryFormatter(); - formatter.Serialize(ms, o); - ms.Position = 0; - return ms; - } - - private object Deserialize(Stream s) - { - return new BinaryFormatter().Deserialize(s); - } - static int[] palette1 = { -16777216, -1, diff --git a/src/libraries/System.Drawing.Common/tests/mono/System.Drawing/GraphicsTests.cs b/src/libraries/System.Drawing.Common/tests/mono/System.Drawing/GraphicsTests.cs index ac36387e5b0335..756e860a2a644e 100644 --- a/src/libraries/System.Drawing.Common/tests/mono/System.Drawing/GraphicsTests.cs +++ b/src/libraries/System.Drawing.Common/tests/mono/System.Drawing/GraphicsTests.cs @@ -687,15 +687,6 @@ public void Clip_RotateTransform_BoundsChange() } } - private void CheckBoundsInt(string msg, RectangleF bounds, int x, int y, int w, int h) - { - // currently bounds are rounded at 8 pixels (FIXME - we can go down to 1 pixel) - AssertEquals(msg + ".X", x, bounds.X, -1); - AssertEquals(msg + ".Y", y, bounds.Y, -1); - AssertEquals(msg + ".Width", w, bounds.Width, -1); - AssertEquals(msg + ".Height", h, bounds.Height, -1); - } - [ConditionalFact(Helpers.IsDrawingSupported)] public void Clip_ScaleTransform_NoBoundsChange() { @@ -777,7 +768,6 @@ public void TranslateTransform_Order() } } - static Point[] SmallCurve = new Point[3] { new Point(0, 0), new Point(15, 5), new Point(5, 15) }; static PointF[] SmallCurveF = new PointF[3] { new PointF(0, 0), new PointF(15, 5), new PointF(5, 15) }; static Point[] TooSmallCurve = new Point[2] { new Point(0, 0), new Point(15, 5) }; From 1f62294e4c8186f324d50843d0e7c131b48df493 Mon Sep 17 00:00:00 2001 From: Matt Kotsenas Date: Fri, 17 Jul 2020 21:26:06 -0700 Subject: [PATCH 006/458] Remove unused locals in System.IO.FileSystem.* (#39552) * Remove unused locals in System.IO.FileSystem.AccessControl * Removed unused locals in System.IO.FileSystem.DriveInfo * Remove unused locals and methods in System.IO.FileSystem --- .../tests/FileSystemAclExtensionsTests.cs | 4 +- .../tests/FileSystemSecurityTests.cs | 4 +- .../src/System/IO/DriveInfo.Windows.cs | 10 +-- .../tests/Directory/EnumerableAPIs.cs | 8 +-- .../tests/Directory/Exists.cs | 10 +-- .../Directory/GetFileSystemEntries_str_str.cs | 2 +- .../GetFileSystemEntries_str_str_so.cs | 2 +- .../tests/Directory/SetCurrentDirectory.cs | 2 - .../System.IO.FileSystem/tests/File/Exists.cs | 2 +- .../tests/File/ReadWriteAllBytes.cs | 1 - .../tests/File/ReadWriteAllBytesAsync.cs | 1 - .../tests/File/ReadWriteAllText.cs | 2 - .../tests/File/ReadWriteAllTextAsync.cs | 2 - .../tests/FileInfo/GetSetTimes.cs | 3 - .../tests/FileStream/CopyToAsync.cs | 2 +- .../tests/FileStream/Dispose.cs | 2 +- .../tests/FileStream/SafeFileHandle.cs | 2 +- .../tests/FileStream/WriteAsync.cs | 2 +- .../tests/PortedCommon/CommonUtilities.cs | 71 ------------------- 19 files changed, 25 insertions(+), 107 deletions(-) diff --git a/src/libraries/System.IO.FileSystem.AccessControl/tests/FileSystemAclExtensionsTests.cs b/src/libraries/System.IO.FileSystem.AccessControl/tests/FileSystemAclExtensionsTests.cs index b5dd1f492fd588..431e8e4154e22c 100644 --- a/src/libraries/System.IO.FileSystem.AccessControl/tests/FileSystemAclExtensionsTests.cs +++ b/src/libraries/System.IO.FileSystem.AccessControl/tests/FileSystemAclExtensionsTests.cs @@ -478,7 +478,7 @@ public void DirectorySecurity_CreateDirectory_DirectoryAlreadyExists() string path = Path.Combine(directory.Path, "createMe"); DirectorySecurity basicSecurity = new DirectorySecurity(); - DirectoryInfo basicDirInfo = basicSecurity.CreateDirectory(path); + basicSecurity.CreateDirectory(path); Assert.True(Directory.Exists(path)); @@ -534,7 +534,7 @@ private void Verify_DirectorySecurity_CreateDirectory(DirectorySecurity expected using var directory = new TempDirectory(); string path = Path.Combine(directory.Path, "createMe"); - DirectoryInfo createdInfo = expectedSecurity.CreateDirectory(path); + expectedSecurity.CreateDirectory(path); Assert.True(Directory.Exists(path)); diff --git a/src/libraries/System.IO.FileSystem.AccessControl/tests/FileSystemSecurityTests.cs b/src/libraries/System.IO.FileSystem.AccessControl/tests/FileSystemSecurityTests.cs index 922604febf6991..b2730208c0e8f7 100644 --- a/src/libraries/System.IO.FileSystem.AccessControl/tests/FileSystemSecurityTests.cs +++ b/src/libraries/System.IO.FileSystem.AccessControl/tests/FileSystemSecurityTests.cs @@ -423,7 +423,7 @@ public void DirNotFound_DirectorySecurity() // - NetCore: a valid name because long paths are correctly handled, and non-existent, as expected AssertExtensions.Throws(() => { - var security = new DirectorySecurity(longDir, AccessControlSections.Owner); + new DirectorySecurity(longDir, AccessControlSections.Owner); }); } @@ -440,7 +440,7 @@ public void FileNotFound_FileSecurity() // - NetCore: a valid name because long paths are correctly handled, and non-existent, as expected AssertExtensions.Throws(() => { - var security = new FileSecurity(filePath, AccessControlSections.Owner); + new FileSecurity(filePath, AccessControlSections.Owner); }); } diff --git a/src/libraries/System.IO.FileSystem.DriveInfo/src/System/IO/DriveInfo.Windows.cs b/src/libraries/System.IO.FileSystem.DriveInfo/src/System/IO/DriveInfo.Windows.cs index df7eadd5e1e5da..e1834a4b2d8020 100644 --- a/src/libraries/System.IO.FileSystem.DriveInfo/src/System/IO/DriveInfo.Windows.cs +++ b/src/libraries/System.IO.FileSystem.DriveInfo/src/System/IO/DriveInfo.Windows.cs @@ -59,7 +59,7 @@ public long AvailableFreeSpace finally { if (success) - Interop.Kernel32.SetThreadErrorMode(oldMode, out oldMode); + Interop.Kernel32.SetThreadErrorMode(oldMode, out _); } return userBytes; } @@ -81,7 +81,7 @@ public long TotalFreeSpace finally { if (success) - Interop.Kernel32.SetThreadErrorMode(oldMode, out oldMode); + Interop.Kernel32.SetThreadErrorMode(oldMode, out _); } return freeBytes; } @@ -95,7 +95,7 @@ public long TotalSize // or other various removable media drives. long userBytes, totalBytes, freeBytes; uint oldMode; - bool success = Interop.Kernel32.SetThreadErrorMode(Interop.Kernel32.SEM_FAILCRITICALERRORS, out oldMode); + Interop.Kernel32.SetThreadErrorMode(Interop.Kernel32.SEM_FAILCRITICALERRORS, out oldMode); try { bool r = Interop.Kernel32.GetDiskFreeSpaceEx(Name, out userBytes, out totalBytes, out freeBytes); @@ -104,7 +104,7 @@ public long TotalSize } finally { - Interop.Kernel32.SetThreadErrorMode(oldMode, out oldMode); + Interop.Kernel32.SetThreadErrorMode(oldMode, out _); } return totalBytes; } @@ -159,7 +159,7 @@ public unsafe string VolumeLabel finally { if (success) - Interop.Kernel32.SetThreadErrorMode(oldMode, out oldMode); + Interop.Kernel32.SetThreadErrorMode(oldMode, out _); } } } diff --git a/src/libraries/System.IO.FileSystem/tests/Directory/EnumerableAPIs.cs b/src/libraries/System.IO.FileSystem/tests/Directory/EnumerableAPIs.cs index c160e3e989069f..76e5a440b764fd 100644 --- a/src/libraries/System.IO.FileSystem/tests/Directory/EnumerableAPIs.cs +++ b/src/libraries/System.IO.FileSystem/tests/Directory/EnumerableAPIs.cs @@ -94,8 +94,8 @@ public void Clone_Enumerator_Trimmed_SearchPattern() public void Delete_Directory_After_Creating_Enumerable() { DirectoryInfo testDir = Directory.CreateDirectory(GetTestFilePath()); - DirectoryInfo subDir1 = Directory.CreateDirectory(Path.Combine(testDir.FullName, "a")); - DirectoryInfo subDir2 = Directory.CreateDirectory(Path.Combine(testDir.FullName, "b")); + Directory.CreateDirectory(Path.Combine(testDir.FullName, "a")); + Directory.CreateDirectory(Path.Combine(testDir.FullName, "b")); var enumerator = Directory.EnumerateDirectories(testDir.FullName); foreach (var dir in enumerator) { @@ -110,8 +110,8 @@ public void Trailing_Slash_Adds_Trailing_Star() { // A searchpattern of c:\temp\ will become c:\temp\* internally DirectoryInfo testDir = Directory.CreateDirectory(GetTestFilePath()); - DirectoryInfo subDir1 = Directory.CreateDirectory(Path.Combine(testDir.FullName, "a")); - DirectoryInfo subDir2 = Directory.CreateDirectory(Path.Combine(testDir.FullName, "b")); + Directory.CreateDirectory(Path.Combine(testDir.FullName, "a")); + Directory.CreateDirectory(Path.Combine(testDir.FullName, "b")); var enumerator = Directory.EnumerateDirectories(testDir.FullName, "a" + Path.DirectorySeparatorChar); Assert.Equal(0, enumerator.ToArray().Length); } diff --git a/src/libraries/System.IO.FileSystem/tests/Directory/Exists.cs b/src/libraries/System.IO.FileSystem/tests/Directory/Exists.cs index 248d0b3c218783..cfe5834f53d375 100644 --- a/src/libraries/System.IO.FileSystem/tests/Directory/Exists.cs +++ b/src/libraries/System.IO.FileSystem/tests/Directory/Exists.cs @@ -44,7 +44,7 @@ public void NonExistentValidPath_ReturnsFalse(string path) public void ValidPathExists_ReturnsTrue(string component) { string path = Path.Combine(TestDirectory, component); - DirectoryInfo testDir = Directory.CreateDirectory(path); + Directory.CreateDirectory(path); Assert.True(Exists(path)); } @@ -73,7 +73,7 @@ public void PathAlreadyExistsAsFile() public void PathAlreadyExistsAsDirectory() { string path = GetTestFilePath(); - DirectoryInfo testDir = Directory.CreateDirectory(path); + Directory.CreateDirectory(path); Assert.True(Exists(IOServices.RemoveTrailingSlash(path))); Assert.True(Exists(IOServices.RemoveTrailingSlash(IOServices.RemoveTrailingSlash(path)))); @@ -177,7 +177,7 @@ public void SymlinkToNewDirectory() public void ValidExtendedPathExists_ReturnsTrue(string component) { string path = IOInputs.ExtendedPrefix + Path.Combine(TestDirectory, "extended", component); - DirectoryInfo testDir = Directory.CreateDirectory(path); + Directory.CreateDirectory(path); Assert.True(Exists(path)); } @@ -198,7 +198,7 @@ public void ExtendedPathAlreadyExistsAsFile() public void ExtendedPathAlreadyExistsAsDirectory() { string path = IOInputs.ExtendedPrefix + GetTestFilePath(); - DirectoryInfo testDir = Directory.CreateDirectory(path); + Directory.CreateDirectory(path); Assert.True(Exists(IOServices.RemoveTrailingSlash(path))); Assert.True(Exists(IOServices.RemoveTrailingSlash(IOServices.RemoveTrailingSlash(path)))); @@ -278,7 +278,7 @@ public void TrailingSpaceExists(string component) { // Windows trims spaces string path = GetTestFilePath(); - DirectoryInfo testDir = Directory.CreateDirectory(path + component); + Directory.CreateDirectory(path + component); Assert.True(Exists(path), "can find without space"); Assert.True(Exists(path + component), "can find with space"); } diff --git a/src/libraries/System.IO.FileSystem/tests/Directory/GetFileSystemEntries_str_str.cs b/src/libraries/System.IO.FileSystem/tests/Directory/GetFileSystemEntries_str_str.cs index 6e557c5874df60..5a8c5150fd09f1 100644 --- a/src/libraries/System.IO.FileSystem/tests/Directory/GetFileSystemEntries_str_str.cs +++ b/src/libraries/System.IO.FileSystem/tests/Directory/GetFileSystemEntries_str_str.cs @@ -682,7 +682,7 @@ public virtual void WindowsSearchPatternQuestionMarks() { string testDir1Str = GetTestFileName(); DirectoryInfo testDir = new DirectoryInfo(TestDirectory); - DirectoryInfo testDir1 = testDir.CreateSubdirectory(testDir1Str); + testDir.CreateSubdirectory(testDir1Str); using (File.Create(Path.Combine(TestDirectory, testDir1Str, GetTestFileName()))) using (File.Create(Path.Combine(TestDirectory, GetTestFileName()))) diff --git a/src/libraries/System.IO.FileSystem/tests/Directory/GetFileSystemEntries_str_str_so.cs b/src/libraries/System.IO.FileSystem/tests/Directory/GetFileSystemEntries_str_str_so.cs index 7410d20492f77a..c18f14e5bc4836 100644 --- a/src/libraries/System.IO.FileSystem/tests/Directory/GetFileSystemEntries_str_str_so.cs +++ b/src/libraries/System.IO.FileSystem/tests/Directory/GetFileSystemEntries_str_str_so.cs @@ -32,7 +32,7 @@ public override void WindowsSearchPatternQuestionMarks() { string testDir1Str = GetTestFileName(); DirectoryInfo testDir = new DirectoryInfo(TestDirectory); - DirectoryInfo testDir1 = testDir.CreateSubdirectory(testDir1Str); + testDir.CreateSubdirectory(testDir1Str); using (File.Create(Path.Combine(TestDirectory, testDir1Str, GetTestFileName()))) using (File.Create(Path.Combine(TestDirectory, GetTestFileName()))) diff --git a/src/libraries/System.IO.FileSystem/tests/Directory/SetCurrentDirectory.cs b/src/libraries/System.IO.FileSystem/tests/Directory/SetCurrentDirectory.cs index 04e636582d7e24..16287ef7b3f455 100644 --- a/src/libraries/System.IO.FileSystem/tests/Directory/SetCurrentDirectory.cs +++ b/src/libraries/System.IO.FileSystem/tests/Directory/SetCurrentDirectory.cs @@ -64,8 +64,6 @@ public void SetToPathContainingSymLink() Assert.True(Directory.Exists(linkPath), "linkPath should exist"); // Set Current Directory to symlink - string currentDir = Directory.GetCurrentDirectory(); - Directory.SetCurrentDirectory(linkPath); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { diff --git a/src/libraries/System.IO.FileSystem/tests/File/Exists.cs b/src/libraries/System.IO.FileSystem/tests/File/Exists.cs index 9263b48e4b6c20..40d5ebce3d4b77 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/Exists.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/Exists.cs @@ -104,7 +104,7 @@ public void PathEndsInAltTrailingSlash_AndExists_Windows() public void PathAlreadyExistsAsDirectory() { string path = GetTestFilePath(); - DirectoryInfo testDir = Directory.CreateDirectory(path); + Directory.CreateDirectory(path); Assert.False(Exists(IOServices.RemoveTrailingSlash(path))); Assert.False(Exists(IOServices.RemoveTrailingSlash(IOServices.RemoveTrailingSlash(path)))); diff --git a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs index 46d2e87437355d..33c10d40b84784 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytes.cs @@ -22,7 +22,6 @@ public void NullParameters() [Fact] public void InvalidParameters() { - string path = GetTestFilePath(); Assert.Throws(() => File.WriteAllBytes(string.Empty, new byte[0])); Assert.Throws(() => File.ReadAllBytes(string.Empty)); } diff --git a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs index 11779d7de3f1ae..30fc35e97b1e7a 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllBytesAsync.cs @@ -24,7 +24,6 @@ public async Task NullParametersAsync() [Fact] public async Task InvalidParametersAsync() { - string path = GetTestFilePath(); await Assert.ThrowsAsync("path", async () => await File.WriteAllBytesAsync(string.Empty, new byte[0])); await Assert.ThrowsAsync("path", async () => await File.ReadAllBytesAsync(string.Empty)); } diff --git a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllText.cs b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllText.cs index 1062036adfe551..152858cc92388a 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllText.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllText.cs @@ -28,7 +28,6 @@ protected virtual string Read(string path) [Fact] public void NullParameters() { - string path = GetTestFilePath(); Assert.Throws(() => Write(null, "Text")); Assert.Throws(() => Read(null)); } @@ -58,7 +57,6 @@ public void EmptyStringContent_CreatesFile() [Fact] public void InvalidParameters() { - string path = GetTestFilePath(); Assert.Throws(() => Write(string.Empty, "Text")); Assert.Throws(() => Read("")); } diff --git a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllTextAsync.cs b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllTextAsync.cs index 8b8134462c8959..3d2f1d9d8da6c3 100644 --- a/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllTextAsync.cs +++ b/src/libraries/System.IO.FileSystem/tests/File/ReadWriteAllTextAsync.cs @@ -26,7 +26,6 @@ public class File_ReadWriteAllTextAsync : FileSystemTest [Fact] public async Task NullParametersAsync() { - string path = GetTestFilePath(); await Assert.ThrowsAsync("path", async () => await WriteAsync(null, "Text")); await Assert.ThrowsAsync("path", async () => await ReadAsync(null)); } @@ -54,7 +53,6 @@ public async Task EmptyStringContent_CreatesFileAsync() [Fact] public async Task InvalidParametersAsync() { - string path = GetTestFilePath(); await Assert.ThrowsAsync("path", async () => await WriteAsync(string.Empty, "Text")); await Assert.ThrowsAsync("path", async () => await ReadAsync("")); } diff --git a/src/libraries/System.IO.FileSystem/tests/FileInfo/GetSetTimes.cs b/src/libraries/System.IO.FileSystem/tests/FileInfo/GetSetTimes.cs index 2c92d0c57e60c2..b27adf59f27c85 100644 --- a/src/libraries/System.IO.FileSystem/tests/FileInfo/GetSetTimes.cs +++ b/src/libraries/System.IO.FileSystem/tests/FileInfo/GetSetTimes.cs @@ -186,13 +186,10 @@ public void CopyToMillisecondPresent_HFS() public void DeleteAfterEnumerate_TimesStillSet() { // When enumerating we populate the state as we already have it. - DateTime beforeTime = DateTime.UtcNow.AddSeconds(-1); string filePath = GetTestFilePath(); File.Create(filePath).Dispose(); FileInfo info = new DirectoryInfo(TestDirectory).EnumerateFiles().First(); - DateTime afterTime = DateTime.UtcNow.AddSeconds(1); - info.Delete(); Assert.Equal(DateTime.FromFileTimeUtc(0), info.LastAccessTimeUtc); } diff --git a/src/libraries/System.IO.FileSystem/tests/FileStream/CopyToAsync.cs b/src/libraries/System.IO.FileSystem/tests/FileStream/CopyToAsync.cs index 20179f5e9e1ca4..da7145719b90d1 100644 --- a/src/libraries/System.IO.FileSystem/tests/FileStream/CopyToAsync.cs +++ b/src/libraries/System.IO.FileSystem/tests/FileStream/CopyToAsync.cs @@ -104,7 +104,7 @@ public async Task File_AllDataCopied( // If configured to expose the handle, do so. This influences the stream's need to ensure the position is in sync. if (exposeHandle) { - var ignored = src.SafeFileHandle; + _ = src.SafeFileHandle; } // If configured to "preWrite", do a write before we start reading. diff --git a/src/libraries/System.IO.FileSystem/tests/FileStream/Dispose.cs b/src/libraries/System.IO.FileSystem/tests/FileStream/Dispose.cs index 1285c31fad147e..c87ac78705838b 100644 --- a/src/libraries/System.IO.FileSystem/tests/FileStream/Dispose.cs +++ b/src/libraries/System.IO.FileSystem/tests/FileStream/Dispose.cs @@ -193,7 +193,7 @@ public void Finalizer_CallsVirtualDispose_FalseArg() Action act = () => // separate method to avoid JIT lifetime-extension issues { - var fs2 = new MyFileStream(GetTestFilePath(), FileMode.Create) + new MyFileStream(GetTestFilePath(), FileMode.Create) { DisposeMethod = (disposing) => { diff --git a/src/libraries/System.IO.FileSystem/tests/FileStream/SafeFileHandle.cs b/src/libraries/System.IO.FileSystem/tests/FileStream/SafeFileHandle.cs index 00aac7d9b670fc..03b3353931724a 100644 --- a/src/libraries/System.IO.FileSystem/tests/FileStream/SafeFileHandle.cs +++ b/src/libraries/System.IO.FileSystem/tests/FileStream/SafeFileHandle.cs @@ -52,7 +52,7 @@ public void AccessFlushesFileClosesHandle() // other handle doesn't yet see the change Assert.Equal(0, fsr.Length); - SafeFileHandle handle = fs.SafeFileHandle; + _ = fs.SafeFileHandle; // expect the handle to be flushed Assert.Equal(TestBuffer.Length, fsr.Length); diff --git a/src/libraries/System.IO.FileSystem/tests/FileStream/WriteAsync.cs b/src/libraries/System.IO.FileSystem/tests/FileStream/WriteAsync.cs index 47bea8be293cfd..2710edcbf31068 100644 --- a/src/libraries/System.IO.FileSystem/tests/FileStream/WriteAsync.cs +++ b/src/libraries/System.IO.FileSystem/tests/FileStream/WriteAsync.cs @@ -311,7 +311,7 @@ public async Task ManyConcurrentWriteAsyncs_OuterLoop( } if (exposeHandle) { - var ignored = fs.SafeFileHandle; + _ = fs.SafeFileHandle; } Task[] writes = new Task[numWrites]; diff --git a/src/libraries/System.IO.FileSystem/tests/PortedCommon/CommonUtilities.cs b/src/libraries/System.IO.FileSystem/tests/PortedCommon/CommonUtilities.cs index f807ab97739926..03737fa30d4255 100644 --- a/src/libraries/System.IO.FileSystem/tests/PortedCommon/CommonUtilities.cs +++ b/src/libraries/System.IO.FileSystem/tests/PortedCommon/CommonUtilities.cs @@ -262,9 +262,6 @@ private void CreateFileSystem() //we will not include this directory // m_listOfAllDirs.Add(m_startDir); - string currentWorkingDir = _startDir; - string parentDir = _startDir; - _allDirs = new Dictionary>>(); // List dirsForOneLevel = new List(); // List tempDirsForOneLevel; @@ -386,72 +383,4 @@ static TestInfo() } public static string CurrentDirectory { get; set; } - - private delegate void ExceptionCode(); - - private void DeleteFile(string fileName) - { - if (File.Exists(fileName)) - File.Delete(fileName); - } - - - //Checks for error - private static bool Eval(bool expression, string msg, params object[] values) - { - return Eval(expression, string.Format(msg, values)); - } - - private static bool Eval(T actual, T expected, string errorMsg) - { - bool retValue = expected == null ? actual == null : expected.Equals(actual); - - if (!retValue) - Eval(retValue, errorMsg + - " Expected:" + (null == expected ? "" : expected.ToString()) + - " Actual:" + (null == actual ? "" : actual.ToString())); - - return retValue; - } - - private static bool Eval(bool expression, string msg) - { - if (!expression) - { - Console.WriteLine(msg); - } - return expression; - } - - //Checks for a particular type of exception - private static void CheckException(ExceptionCode test, string error) - { - CheckException(test, error, null); - } - - //Checks for a particular type of exception and an Exception msg - private static void CheckException(ExceptionCode test, string error, string msgExpected) - { - bool exception = false; - try - { - test(); - error = string.Format("{0} Exception NOT thrown ", error); - } - catch (Exception e) - { - if (e.GetType() == typeof(E)) - { - exception = true; - if (System.Globalization.CultureInfo.CurrentUICulture.Name == "en-US" && msgExpected != null && e.Message != msgExpected) - { - exception = false; - error = string.Format("{0} Message Different: <{1}>", error, e.Message); - } - } - else - error = string.Format("{0} Exception type: {1}", error, e.GetType().Name); - } - Eval(exception, error); - } } From 90d47a70454a8b32d24155f555777a5c07566e40 Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Fri, 17 Jul 2020 21:26:22 -0700 Subject: [PATCH 007/458] Add more information to test timeout message (#39558) This is to help validate that timeouts are what we think. --- .../Coreclr.TestWrapper/CoreclrTestWrapperLib.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/tests/Common/Coreclr.TestWrapper/CoreclrTestWrapperLib.cs b/src/tests/Common/Coreclr.TestWrapper/CoreclrTestWrapperLib.cs index ee471092a4ac87..21c3e1b7093b87 100644 --- a/src/tests/Common/Coreclr.TestWrapper/CoreclrTestWrapperLib.cs +++ b/src/tests/Common/Coreclr.TestWrapper/CoreclrTestWrapperLib.cs @@ -333,6 +333,7 @@ public int RunTest(string executable, string outputFile, string errorFile) process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError = true; + DateTime startTime = DateTime.Now; process.Start(); var cts = new CancellationTokenSource(); @@ -348,14 +349,21 @@ public int RunTest(string executable, string outputFile, string errorFile) else { // Timed out. + + DateTime endTime = DateTime.Now; + try { cts.Cancel(); } catch {} - outputWriter.WriteLine("\ncmdLine:" + executable + " Timed Out"); - errorWriter.WriteLine("\ncmdLine:" + executable + " Timed Out"); + outputWriter.WriteLine("\ncmdLine:{0} Timed Out (timeout in milliseconds: {1}{2}{3}, start: {4}, end: {5})", + executable, timeout, (environmentVar != null) ? " from variable " : "", (environmentVar != null) ? TIMEOUT_ENVIRONMENT_VAR : "", + startTime.ToString(), endTime.ToString()); + errorWriter.WriteLine("\ncmdLine:{0} Timed Out (timeout in milliseconds: {1}{2}{3}, start: {4}, end: {5})", + executable, timeout, (environmentVar != null) ? " from variable " : "", (environmentVar != null) ? TIMEOUT_ENVIRONMENT_VAR : "", + startTime.ToString(), endTime.ToString()); if (collectCrashDumps) { From 8e7b5aed6b97ff21330f1f4268f9e9d31a34ac43 Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Fri, 17 Jul 2020 21:27:50 -0700 Subject: [PATCH 008/458] Disable Vector tests failing under GCStress (#39580) * Disable Vector tests failing under GCStress Issues: https://github.com/dotnet/runtime/issues/39576 https://github.com/dotnet/runtime/issues/39579 * Also disable Vector256_1_r/Vector_1_ro tests Issue: https://github.com/dotnet/runtime/issues/39581 --- .../JIT/HardwareIntrinsics/General/Vector128/Vector128_r.csproj | 2 ++ .../HardwareIntrinsics/General/Vector128/Vector128_ro.csproj | 2 ++ .../HardwareIntrinsics/General/Vector128_1/Vector128_1_r.csproj | 2 ++ .../General/Vector128_1/Vector128_1_ro.csproj | 2 ++ .../JIT/HardwareIntrinsics/General/Vector256/Vector256_r.csproj | 2 ++ .../HardwareIntrinsics/General/Vector256/Vector256_ro.csproj | 2 ++ .../HardwareIntrinsics/General/Vector256_1/Vector256_1_r.csproj | 2 ++ .../General/Vector256_1/Vector256_1_ro.csproj | 2 ++ .../JIT/HardwareIntrinsics/General/Vector64/Vector64_r.csproj | 2 ++ .../JIT/HardwareIntrinsics/General/Vector64/Vector64_ro.csproj | 2 ++ .../HardwareIntrinsics/General/Vector64_1/Vector64_1_r.csproj | 2 ++ .../HardwareIntrinsics/General/Vector64_1/Vector64_1_ro.csproj | 2 ++ 12 files changed, 24 insertions(+) diff --git a/src/tests/JIT/HardwareIntrinsics/General/Vector128/Vector128_r.csproj b/src/tests/JIT/HardwareIntrinsics/General/Vector128/Vector128_r.csproj index 2e1ffa2dcc1c7d..794326d41ec536 100644 --- a/src/tests/JIT/HardwareIntrinsics/General/Vector128/Vector128_r.csproj +++ b/src/tests/JIT/HardwareIntrinsics/General/Vector128/Vector128_r.csproj @@ -2,6 +2,8 @@ Exe true + + true Embedded diff --git a/src/tests/JIT/HardwareIntrinsics/General/Vector128/Vector128_ro.csproj b/src/tests/JIT/HardwareIntrinsics/General/Vector128/Vector128_ro.csproj index 91f1f64aec297a..0384e6834e0190 100644 --- a/src/tests/JIT/HardwareIntrinsics/General/Vector128/Vector128_ro.csproj +++ b/src/tests/JIT/HardwareIntrinsics/General/Vector128/Vector128_ro.csproj @@ -2,6 +2,8 @@ Exe true + + true Embedded diff --git a/src/tests/JIT/HardwareIntrinsics/General/Vector128_1/Vector128_1_r.csproj b/src/tests/JIT/HardwareIntrinsics/General/Vector128_1/Vector128_1_r.csproj index 2e1ffa2dcc1c7d..794326d41ec536 100644 --- a/src/tests/JIT/HardwareIntrinsics/General/Vector128_1/Vector128_1_r.csproj +++ b/src/tests/JIT/HardwareIntrinsics/General/Vector128_1/Vector128_1_r.csproj @@ -2,6 +2,8 @@ Exe true + + true Embedded diff --git a/src/tests/JIT/HardwareIntrinsics/General/Vector128_1/Vector128_1_ro.csproj b/src/tests/JIT/HardwareIntrinsics/General/Vector128_1/Vector128_1_ro.csproj index 91f1f64aec297a..0384e6834e0190 100644 --- a/src/tests/JIT/HardwareIntrinsics/General/Vector128_1/Vector128_1_ro.csproj +++ b/src/tests/JIT/HardwareIntrinsics/General/Vector128_1/Vector128_1_ro.csproj @@ -2,6 +2,8 @@ Exe true + + true Embedded diff --git a/src/tests/JIT/HardwareIntrinsics/General/Vector256/Vector256_r.csproj b/src/tests/JIT/HardwareIntrinsics/General/Vector256/Vector256_r.csproj index 2e1ffa2dcc1c7d..794326d41ec536 100644 --- a/src/tests/JIT/HardwareIntrinsics/General/Vector256/Vector256_r.csproj +++ b/src/tests/JIT/HardwareIntrinsics/General/Vector256/Vector256_r.csproj @@ -2,6 +2,8 @@ Exe true + + true Embedded diff --git a/src/tests/JIT/HardwareIntrinsics/General/Vector256/Vector256_ro.csproj b/src/tests/JIT/HardwareIntrinsics/General/Vector256/Vector256_ro.csproj index 91f1f64aec297a..0384e6834e0190 100644 --- a/src/tests/JIT/HardwareIntrinsics/General/Vector256/Vector256_ro.csproj +++ b/src/tests/JIT/HardwareIntrinsics/General/Vector256/Vector256_ro.csproj @@ -2,6 +2,8 @@ Exe true + + true Embedded diff --git a/src/tests/JIT/HardwareIntrinsics/General/Vector256_1/Vector256_1_r.csproj b/src/tests/JIT/HardwareIntrinsics/General/Vector256_1/Vector256_1_r.csproj index 2e1ffa2dcc1c7d..6eedfbbafd0f18 100644 --- a/src/tests/JIT/HardwareIntrinsics/General/Vector256_1/Vector256_1_r.csproj +++ b/src/tests/JIT/HardwareIntrinsics/General/Vector256_1/Vector256_1_r.csproj @@ -2,6 +2,8 @@ Exe true + + true Embedded diff --git a/src/tests/JIT/HardwareIntrinsics/General/Vector256_1/Vector256_1_ro.csproj b/src/tests/JIT/HardwareIntrinsics/General/Vector256_1/Vector256_1_ro.csproj index 91f1f64aec297a..ea939ebef62106 100644 --- a/src/tests/JIT/HardwareIntrinsics/General/Vector256_1/Vector256_1_ro.csproj +++ b/src/tests/JIT/HardwareIntrinsics/General/Vector256_1/Vector256_1_ro.csproj @@ -2,6 +2,8 @@ Exe true + + true Embedded diff --git a/src/tests/JIT/HardwareIntrinsics/General/Vector64/Vector64_r.csproj b/src/tests/JIT/HardwareIntrinsics/General/Vector64/Vector64_r.csproj index 2e1ffa2dcc1c7d..794326d41ec536 100644 --- a/src/tests/JIT/HardwareIntrinsics/General/Vector64/Vector64_r.csproj +++ b/src/tests/JIT/HardwareIntrinsics/General/Vector64/Vector64_r.csproj @@ -2,6 +2,8 @@ Exe true + + true Embedded diff --git a/src/tests/JIT/HardwareIntrinsics/General/Vector64/Vector64_ro.csproj b/src/tests/JIT/HardwareIntrinsics/General/Vector64/Vector64_ro.csproj index 91f1f64aec297a..0384e6834e0190 100644 --- a/src/tests/JIT/HardwareIntrinsics/General/Vector64/Vector64_ro.csproj +++ b/src/tests/JIT/HardwareIntrinsics/General/Vector64/Vector64_ro.csproj @@ -2,6 +2,8 @@ Exe true + + true Embedded diff --git a/src/tests/JIT/HardwareIntrinsics/General/Vector64_1/Vector64_1_r.csproj b/src/tests/JIT/HardwareIntrinsics/General/Vector64_1/Vector64_1_r.csproj index 2e1ffa2dcc1c7d..794326d41ec536 100644 --- a/src/tests/JIT/HardwareIntrinsics/General/Vector64_1/Vector64_1_r.csproj +++ b/src/tests/JIT/HardwareIntrinsics/General/Vector64_1/Vector64_1_r.csproj @@ -2,6 +2,8 @@ Exe true + + true Embedded diff --git a/src/tests/JIT/HardwareIntrinsics/General/Vector64_1/Vector64_1_ro.csproj b/src/tests/JIT/HardwareIntrinsics/General/Vector64_1/Vector64_1_ro.csproj index 91f1f64aec297a..0384e6834e0190 100644 --- a/src/tests/JIT/HardwareIntrinsics/General/Vector64_1/Vector64_1_ro.csproj +++ b/src/tests/JIT/HardwareIntrinsics/General/Vector64_1/Vector64_1_ro.csproj @@ -2,6 +2,8 @@ Exe true + + true Embedded From 595402c1d20bcf305f724c605b5d28b4280801c3 Mon Sep 17 00:00:00 2001 From: Matt Kotsenas Date: Fri, 17 Jul 2020 21:48:32 -0700 Subject: [PATCH 009/458] Remove unused locals in System.IO.Ports (#39557) Also changed visibility in some tests from `private` to `public` to follow the other code in the project and prevent the compiler from thinking the tests are unused. --- .../tests/SerialPort/BaudRate.cs | 3 +- .../tests/SerialPort/Encoding.cs | 2 +- .../tests/SerialPort/Handshake.cs | 2 -- .../tests/SerialPort/ReadBufferSize.cs | 1 - .../SerialPort/Read_char_int_int_Generic.cs | 2 -- .../tests/SerialPort/RtsEnable.cs | 4 +-- .../tests/SerialPort/WriteLine.cs | 23 +++++++------ .../tests/SerialPort/Write_byte_int_int.cs | 9 ------ .../tests/SerialStream/BeginRead_Generic.cs | 32 ------------------- .../tests/SerialStream/Length.cs | 2 +- .../tests/SerialStream/Position.cs | 2 +- 11 files changed, 17 insertions(+), 65 deletions(-) diff --git a/src/libraries/System.IO.Ports/tests/SerialPort/BaudRate.cs b/src/libraries/System.IO.Ports/tests/SerialPort/BaudRate.cs index 1dee6e9e3688fe..2735d9dc0470fa 100644 --- a/src/libraries/System.IO.Ports/tests/SerialPort/BaudRate.cs +++ b/src/libraries/System.IO.Ports/tests/SerialPort/BaudRate.cs @@ -260,7 +260,6 @@ private void VerifyBaudRate(SerialPort com1) using (SerialPort com2 = new SerialPort(TCSupport.LocalMachineSerialInfo.SecondAvailablePortName)) { double expectedTime, actualTime, percentageDifference; - int numBytes = 0; //Generate some random byte to read/write at this baudrate for (int i = 0; i < xmitBytes.Length; i++) @@ -316,7 +315,7 @@ private void VerifyBaudRate(SerialPort com1) if (MAX_ACCEPTABLE_PERCENTAGE_DIFFERENCE < percentageDifference) { Assert.True(false, string.Format("ERROR!!! BuadRate not used Expected time:{0}, actual time:{1} percentageDifference:{2}", - expectedTime, actualTime, percentageDifference, numBytes)); + expectedTime, actualTime, percentageDifference)); } com2.Read(rcvBytes, 0, rcvBytes.Length); diff --git a/src/libraries/System.IO.Ports/tests/SerialPort/Encoding.cs b/src/libraries/System.IO.Ports/tests/SerialPort/Encoding.cs index 0380848d84320a..88fd4f2391f7b7 100644 --- a/src/libraries/System.IO.Ports/tests/SerialPort/Encoding.cs +++ b/src/libraries/System.IO.Ports/tests/SerialPort/Encoding.cs @@ -175,7 +175,7 @@ private void VerifyExceptionAtOpen(SerialPort com, Encoding encoding, ThrowAt th if (ThrowAt.Open == throwAt) com.Open(); - object myEncoding = com.Encoding; + _ = com.Encoding; com.Encoding = origEncoding; diff --git a/src/libraries/System.IO.Ports/tests/SerialPort/Handshake.cs b/src/libraries/System.IO.Ports/tests/SerialPort/Handshake.cs index 7bb7b1ac4981c4..a9c80e3e76ca60 100644 --- a/src/libraries/System.IO.Ports/tests/SerialPort/Handshake.cs +++ b/src/libraries/System.IO.Ports/tests/SerialPort/Handshake.cs @@ -591,7 +591,6 @@ private void VerirfyRTSBufferFull(SerialPort com1, SerialPort com2) { int com1BaudRate = com1.BaudRate; int com2BaudRate = com2.BaudRate; - int com1ReadBufferSize = com1.ReadBufferSize; int bufferSize = com1.ReadBufferSize; int upperLimit = (3 * bufferSize) / 4; int lowerLimit = bufferSize / 4; @@ -695,7 +694,6 @@ private void VerirfyXOnXOffBufferFull(SerialPort com1, SerialPort com2) { int com1BaudRate = com1.BaudRate; int com2BaudRate = com2.BaudRate; - int com1ReadBufferSize = com1.ReadBufferSize; bool com2RtsEnable = com2.RtsEnable; int bufferSize = com1.ReadBufferSize; int upperLimit = bufferSize - 1024; diff --git a/src/libraries/System.IO.Ports/tests/SerialPort/ReadBufferSize.cs b/src/libraries/System.IO.Ports/tests/SerialPort/ReadBufferSize.cs index 733253fa9f9831..4ec9ea9cd41de7 100644 --- a/src/libraries/System.IO.Ports/tests/SerialPort/ReadBufferSize.cs +++ b/src/libraries/System.IO.Ports/tests/SerialPort/ReadBufferSize.cs @@ -299,7 +299,6 @@ private void VerifyReadBufferSize(SerialPort com1) SerialPortProperties serPortProp = new SerialPortProperties(); Random rndGen = new Random(-55); int bytesToRead = readBufferSize < 4096 ? 4096 : readBufferSize; - int origBaudRate = com1.BaudRate; int origReadTimeout = com1.ReadTimeout; int bytesRead; diff --git a/src/libraries/System.IO.Ports/tests/SerialPort/Read_char_int_int_Generic.cs b/src/libraries/System.IO.Ports/tests/SerialPort/Read_char_int_int_Generic.cs index ba3f3dede8753a..817b38e1daeb6c 100644 --- a/src/libraries/System.IO.Ports/tests/SerialPort/Read_char_int_int_Generic.cs +++ b/src/libraries/System.IO.Ports/tests/SerialPort/Read_char_int_int_Generic.cs @@ -276,8 +276,6 @@ public void BytesToRead_1_Buffer_Size() [ConditionalFact(nameof(HasNullModem))] public void BytesToRead_Equal_Buffer_Size() { - Random rndGen = new Random(-55); - VerifyBytesToRead(numRndBytesToRead); } #endregion diff --git a/src/libraries/System.IO.Ports/tests/SerialPort/RtsEnable.cs b/src/libraries/System.IO.Ports/tests/SerialPort/RtsEnable.cs index bd347c42cced61..23cbbe7a5304c2 100644 --- a/src/libraries/System.IO.Ports/tests/SerialPort/RtsEnable.cs +++ b/src/libraries/System.IO.Ports/tests/SerialPort/RtsEnable.cs @@ -190,7 +190,7 @@ public void RtsEnable_Get_Handshake_RequestToSend() Assert.Throws(() => { - bool rtsEnable = com1.RtsEnable; + _ = com1.RtsEnable; }); } } @@ -208,7 +208,7 @@ public void RtsEnable_Get_Handshake_RequestToSendXOnXOff() Assert.Throws(() => { - bool rtsEnable = com1.RtsEnable; + _ = com1.RtsEnable; }); } } diff --git a/src/libraries/System.IO.Ports/tests/SerialPort/WriteLine.cs b/src/libraries/System.IO.Ports/tests/SerialPort/WriteLine.cs index 9a690ae6cf4710..9cb5b700d022d7 100644 --- a/src/libraries/System.IO.Ports/tests/SerialPort/WriteLine.cs +++ b/src/libraries/System.IO.Ports/tests/SerialPort/WriteLine.cs @@ -29,35 +29,35 @@ public class WriteLine : PortsTest #region Test Cases [ConditionalFact(nameof(HasLoopbackOrNullModem))] - private void ASCIIEncoding() + public void ASCIIEncoding() { Debug.WriteLine("Verifying write method with ASCIIEncoding"); VerifyWrite(new ASCIIEncoding(), ENCODING_STRING_SIZE, GenRandomNewLine(true)); } [ConditionalFact(nameof(HasLoopbackOrNullModem))] - private void UTF8Encoding() + public void UTF8Encoding() { Debug.WriteLine("Verifying write method with UTF8Encoding"); VerifyWrite(new UTF8Encoding(), ENCODING_STRING_SIZE, GenRandomNewLine(false)); } [ConditionalFact(nameof(HasLoopbackOrNullModem))] - private void UTF32Encoding() + public void UTF32Encoding() { Debug.WriteLine("Verifying write method with UTF32Encoding"); VerifyWrite(new UTF32Encoding(), ENCODING_STRING_SIZE, GenRandomNewLine(false)); } [ConditionalFact(nameof(HasLoopbackOrNullModem))] - private void UnicodeEncoding() + public void UnicodeEncoding() { Debug.WriteLine("Verifying write method with UnicodeEncoding"); VerifyWrite(new UnicodeEncoding(), ENCODING_STRING_SIZE, GenRandomNewLine(false)); } [ConditionalFact(nameof(HasOneSerialPort))] - private void NullString() + public void NullString() { using (SerialPort com = new SerialPort(TCSupport.LocalMachineSerialInfo.FirstAvailablePortName)) { @@ -75,7 +75,7 @@ private void NullString() } [ConditionalFact(nameof(HasLoopbackOrNullModem))] - private void EmptyString() + public void EmptyString() { using (SerialPort com1 = TCSupport.InitFirstSerialPort()) using (SerialPort com2 = TCSupport.InitSecondSerialPort(com1)) @@ -92,7 +92,7 @@ private void EmptyString() } [ConditionalFact(nameof(HasLoopbackOrNullModem))] - private void String_Null_Char() + public void String_Null_Char() { using (SerialPort com1 = TCSupport.InitFirstSerialPort()) using (SerialPort com2 = TCSupport.InitSecondSerialPort(com1)) @@ -110,7 +110,7 @@ private void String_Null_Char() } [ConditionalFact(nameof(HasLoopbackOrNullModem))] - private void LargeString() + public void LargeString() { Debug.WriteLine("Verifying write method with a large string size"); VerifyWrite(new UnicodeEncoding(), LARGE_STRING_SIZE, DEFAULT_NEW_LINE, 1); @@ -118,7 +118,7 @@ private void LargeString() [ConditionalFact(nameof(HasLoopbackOrNullModem))] - private void StrContains_NewLine_RND() + public void StrContains_NewLine_RND() { using (SerialPort com1 = TCSupport.InitFirstSerialPort()) using (SerialPort com2 = TCSupport.InitSecondSerialPort(com1)) @@ -145,7 +145,7 @@ private void StrContains_NewLine_RND() } [ConditionalFact(nameof(HasLoopbackOrNullModem))] - private void StrContains_NewLine_CRLF() + public void StrContains_NewLine_CRLF() { using (SerialPort com1 = TCSupport.InitFirstSerialPort()) using (SerialPort com2 = TCSupport.InitSecondSerialPort(com1)) @@ -172,7 +172,7 @@ private void StrContains_NewLine_CRLF() } [ConditionalFact(nameof(HasLoopbackOrNullModem))] - private void StrContains_NewLine_null() + public void StrContains_NewLine_null() { using (SerialPort com1 = TCSupport.InitFirstSerialPort()) using (SerialPort com2 = TCSupport.InitSecondSerialPort(com1)) @@ -239,7 +239,6 @@ private void VerifyWriteLine(SerialPort com1, SerialPort com2, string stringToWr int byteRead; int index = 0; int numNewLineBytes; - char[] newLineChars = com1.NewLine.ToCharArray(); StringBuilder expectedStrBldr = new StringBuilder(); string expectedString; diff --git a/src/libraries/System.IO.Ports/tests/SerialPort/Write_byte_int_int.cs b/src/libraries/System.IO.Ports/tests/SerialPort/Write_byte_int_int.cs index 1574766ca620dc..6357e341c419ee 100644 --- a/src/libraries/System.IO.Ports/tests/SerialPort/Write_byte_int_int.cs +++ b/src/libraries/System.IO.Ports/tests/SerialPort/Write_byte_int_int.cs @@ -134,7 +134,6 @@ public void OffsetCount_EQ_Length() int bufferLength = rndGen.Next(1, MAX_BUFFER_SIZE); int offset = rndGen.Next(0, bufferLength - 1); int count = bufferLength - offset; - Type expectedException = typeof(ArgumentException); VerifyWrite(new byte[bufferLength], offset, count); } @@ -146,7 +145,6 @@ public void Offset_EQ_Length_Minus_1() int bufferLength = rndGen.Next(1, MAX_BUFFER_SIZE); int offset = bufferLength - 1; int count = 1; - Type expectedException = typeof(ArgumentException); VerifyWrite(new byte[bufferLength], offset, count); } @@ -158,7 +156,6 @@ public void Count_EQ_Length() int bufferLength = rndGen.Next(1, MAX_BUFFER_SIZE); int offset = 0; int count = bufferLength; - Type expectedException = typeof(ArgumentException); VerifyWrite(new byte[bufferLength], offset, count); } @@ -300,12 +297,6 @@ private void VerifyWrite(byte[] buffer, int offset, int count, Encoding encoding } } - private void VerifyWriteByteArray(byte[] buffer, int offset, int count, SerialPort com1, SerialPort com2) - { - VerifyWriteByteArray(buffer, offset, count, com1, com2, DEFAULT_NUM_WRITES); - } - - private void VerifyWriteByteArray(byte[] buffer, int offset, int count, SerialPort com1, SerialPort com2, int numWrites) { byte[] oldBuffer, expectedBytes, actualBytes; diff --git a/src/libraries/System.IO.Ports/tests/SerialStream/BeginRead_Generic.cs b/src/libraries/System.IO.Ports/tests/SerialStream/BeginRead_Generic.cs index 9967eba360b628..fac360dcfb2549 100644 --- a/src/libraries/System.IO.Ports/tests/SerialStream/BeginRead_Generic.cs +++ b/src/libraries/System.IO.Ports/tests/SerialStream/BeginRead_Generic.cs @@ -13,13 +13,6 @@ namespace System.IO.Ports.Tests { public class SerialStream_BeginRead_Generic : PortsTest { - // Set bounds fore random timeout values. - // If the min is to low read will not timeout accurately and the testcase will fail - private const int minRandomTimeout = 250; - - // If the max is to large then the testcase will take forever to run - private const int maxRandomTimeout = 2000; - // If the percentage difference between the expected timeout and the actual timeout // found through Stopwatch is greater then 10% then the timeout value was not correctly // to the read method and the testcase fails. @@ -39,10 +32,6 @@ public class SerialStream_BeginRead_Generic : PortsTest // byte array used in this situation private const int defaultByteArraySize = 1; - private const int NUM_TRYS = 5; - - private const int MAX_WAIT_THREAD = 1000; - #region Test Cases [ConditionalFact(nameof(HasOneSerialPort))] @@ -102,25 +91,6 @@ public void TimeoutIsIgnoredForBeginRead() } } - private void WriteToCom1() - { - using (var com2 = new SerialPort(TCSupport.LocalMachineSerialInfo.SecondAvailablePortName)) - { - var rndGen = new Random(-55); - var xmitBuffer = new byte[1]; - int sleepPeriod = rndGen.Next(minRandomTimeout, maxRandomTimeout / 2); - - // Sleep some random period with of a maximum duration of half the largest possible timeout value for a read method on COM1 - Thread.Sleep(sleepPeriod); - - com2.Open(); - com2.Write(xmitBuffer, 0, xmitBuffer.Length); - - if (com2.IsOpen) - com2.Close(); - } - } - [KnownFailure] [ConditionalFact(nameof(HasNullModem))] public void DefaultParityReplaceByte() @@ -236,8 +206,6 @@ public void BytesToRead_1_Buffer_Size() [ConditionalFact(nameof(HasNullModem))] public void BytesToRead_Equal_Buffer_Size() { - var rndGen = new Random(-55); - VerifyBytesToRead(numRndBytesToRead, new UTF8Encoding()); } #endregion diff --git a/src/libraries/System.IO.Ports/tests/SerialStream/Length.cs b/src/libraries/System.IO.Ports/tests/SerialStream/Length.cs index 3372b371ac4da8..e634d51f29a7e7 100644 --- a/src/libraries/System.IO.Ports/tests/SerialStream/Length.cs +++ b/src/libraries/System.IO.Ports/tests/SerialStream/Length.cs @@ -64,7 +64,7 @@ private void VerifyLengthException(Stream serialStream, Type expectedException) { Assert.Throws(expectedException, () => { - long lengthTest = serialStream.Length; + _ = serialStream.Length; }); } #endregion diff --git a/src/libraries/System.IO.Ports/tests/SerialStream/Position.cs b/src/libraries/System.IO.Ports/tests/SerialStream/Position.cs index 265f55a688896d..36b8d1d005ef27 100644 --- a/src/libraries/System.IO.Ports/tests/SerialStream/Position.cs +++ b/src/libraries/System.IO.Ports/tests/SerialStream/Position.cs @@ -78,7 +78,7 @@ private void VerifyPositionException(Stream serialStream, long value, Type expec Assert.Throws(expectedException, () => serialStream.Position = value); Assert.Throws(expectedException, () => { - long positionTest = serialStream.Position; + _ = serialStream.Position; }); } #endregion From ad325b014124b1adb9306abf95fdac85e3f7f2f4 Mon Sep 17 00:00:00 2001 From: Eugene Rozenfeld Date: Fri, 17 Jul 2020 22:07:35 -0700 Subject: [PATCH 010/458] Fix GC poll insertion for `BBJ_CALLFINALLY` basic blocks. (#39564) Fixes #39472. --- src/coreclr/src/jit/flowgraph.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/coreclr/src/jit/flowgraph.cpp b/src/coreclr/src/jit/flowgraph.cpp index e870a8f4c0fe63..65c9af9e8f2c7a 100644 --- a/src/coreclr/src/jit/flowgraph.cpp +++ b/src/coreclr/src/jit/flowgraph.cpp @@ -3650,6 +3650,7 @@ PhaseStatus Compiler::fgInsertGCPolls() case BBJ_SWITCH: case BBJ_NONE: case BBJ_THROW: + case BBJ_CALLFINALLY: break; default: assert(!"Unexpected block kind"); @@ -4058,9 +4059,11 @@ BasicBlock* Compiler::fgCreateGCPoll(GCPollType pollType, BasicBlock* block) createdPollBlocks = false; Statement* newStmt = nullptr; - if (block->bbJumpKind == BBJ_ALWAYS) + if ((block->bbJumpKind == BBJ_ALWAYS) || (block->bbJumpKind == BBJ_CALLFINALLY) || + (block->bbJumpKind == BBJ_NONE)) { - // for BBJ_ALWAYS I don't need to insert it before the condition. Just append it. + // For BBJ_ALWAYS, BBJ_CALLFINALLY, and BBJ_NONE and we don't need to insert it before the condition. + // Just append it. newStmt = fgNewStmtAtEnd(block, call); } else @@ -4265,6 +4268,7 @@ BasicBlock* Compiler::fgCreateGCPoll(GCPollType pollType, BasicBlock* block) __fallthrough; case BBJ_ALWAYS: + case BBJ_CALLFINALLY: fgReplacePred(bottom->bbJumpDest, top, bottom); break; case BBJ_SWITCH: From 16830d153437fc40aa40ae983d6ffec593cd9d83 Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Fri, 17 Jul 2020 22:58:06 -0700 Subject: [PATCH 011/458] Disable Interop\COM\Dynamic\Dynamic under GCStress (#39585) Issue: https://github.com/dotnet/runtime/issues/39584 --- src/tests/Interop/COM/Dynamic/Dynamic.csproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tests/Interop/COM/Dynamic/Dynamic.csproj b/src/tests/Interop/COM/Dynamic/Dynamic.csproj index ebf603a1bbfe1b..df80707843e23d 100644 --- a/src/tests/Interop/COM/Dynamic/Dynamic.csproj +++ b/src/tests/Interop/COM/Dynamic/Dynamic.csproj @@ -8,6 +8,10 @@ true true + + true From fcfcc92ed0d449abc091a249aca0e52c89dbbdf0 Mon Sep 17 00:00:00 2001 From: Matt Kotsenas Date: Fri, 17 Jul 2020 23:29:30 -0700 Subject: [PATCH 012/458] Remove unused locals in System.Configuration.ConfigurationManager (#39544) * Remove unused locals in System.Configuration.ConfigurationManager Removed unused locals, and where needed updated tests in System.Configuration.ConfigurationManager. * Update GetHashCode test --- .../tests/Mono/GenericEnumConverterTest.cs | 4 ++-- .../System/Configuration/CallBackValidatorAttributeTests.cs | 2 +- .../tests/System/Configuration/SettingElementTests.cs | 3 +++ .../tests/System/Configuration/StringValidatorTests.cs | 4 ++-- .../tests/System/Configuration/UrlPathTests.cs | 2 +- 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/Mono/GenericEnumConverterTest.cs b/src/libraries/System.Configuration.ConfigurationManager/tests/Mono/GenericEnumConverterTest.cs index dd15eb2ebc95b0..039d6845e8ebfb 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/tests/Mono/GenericEnumConverterTest.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/tests/Mono/GenericEnumConverterTest.cs @@ -49,9 +49,9 @@ public void Ctor_Null() } [Fact] - public void Ctor_TypeError() + public void Ctor_Object() { - GenericEnumConverter cv = new GenericEnumConverter(typeof(object)); + Assert.NotNull(new GenericEnumConverter(typeof(object))); } [Fact] diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/CallBackValidatorAttributeTests.cs b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/CallBackValidatorAttributeTests.cs index 2b400892b389cb..aa3b8f204d357c 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/CallBackValidatorAttributeTests.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/CallBackValidatorAttributeTests.cs @@ -56,7 +56,7 @@ public void SuccessfulCallback_CallTwice() Type = typeof(CallBackValidatorAttributeTests), CallbackMethodName = "CallBackValidatorTestMethod" }; - var response = testCallBackValidatorAttribute.ValidatorInstance; + _ = testCallBackValidatorAttribute.ValidatorInstance; Assert.IsType(testCallBackValidatorAttribute.ValidatorInstance); } diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/SettingElementTests.cs b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/SettingElementTests.cs index 325c98ef014cc7..5ed74c72148578 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/SettingElementTests.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/SettingElementTests.cs @@ -73,6 +73,9 @@ public void NonDefaultValueHasNonNullHashCode() } } }; + + // Validate the getting the hash code doesn't throw + _ = Element.GetHashCode(); } } } diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/StringValidatorTests.cs b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/StringValidatorTests.cs index 981d54db02a99f..40cbf78668cfc2 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/StringValidatorTests.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/StringValidatorTests.cs @@ -42,7 +42,7 @@ public void Validate_StringTooSmall() public void Validate_StringTooBig() { StringValidator validator = new StringValidator(5, 10); - ArgumentException thrownException = AssertExtensions.Throws(null, () => validator.Validate("This is more than ten")); + AssertExtensions.Throws(null, () => validator.Validate("This is more than ten")); } [Fact] @@ -58,7 +58,7 @@ public void Validate_EmptyString() public void Validate_UsinginvalidCharacters(string stringToValidate) { StringValidator validator = new StringValidator(1, 20, "_-"); - ArgumentException result = AssertExtensions.Throws(null, () => validator.Validate(stringToValidate)); + AssertExtensions.Throws(null, () => validator.Validate(stringToValidate)); } [Fact] diff --git a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/UrlPathTests.cs b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/UrlPathTests.cs index dbcfea89d0f818..4619bec0f43023 100644 --- a/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/UrlPathTests.cs +++ b/src/libraries/System.Configuration.ConfigurationManager/tests/System/Configuration/UrlPathTests.cs @@ -14,7 +14,7 @@ public class UrlPathTests public void GetDirectoryOrRootName_Null() { string test = UrlPath.GetDirectoryOrRootName(null); - Assert.Null(null); + Assert.Null(test); } [Fact] From b5705587347d29d79cec830dc22b389e1ad9a9e0 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Sat, 18 Jul 2020 07:03:24 -0400 Subject: [PATCH 013/458] Use static lambdas in several libraries (#39273) * Use static lambdas in System.Net.Http This caught one bug that was causing an unexpected/undesirable closure. * Use static lambdas in System.Private.CoreLib * Use static lambdas in System.Net.WebSockets * Use static lambdas in System.Threading.Channels --- .../Common/src/System/HexConverter.cs | 2 +- .../HttpKnownHeaderNames.TryGetHeaderName.cs | 8 ++++---- .../System/Net/WebSockets/ManagedWebSocket.cs | 14 ++++++------- .../Threading/Tasks/RendezvousAwaitable.cs | 2 +- .../TaskCompletionSourceWithCancellation.cs | 2 +- .../Net/Http/Headers/HttpRequestHeaders.cs | 16 +++++++-------- .../Net/Http/Headers/HttpResponseHeaders.cs | 11 +++++----- .../Net/Http/Headers/MediaTypeHeaderParser.cs | 9 +++------ .../src/System/Net/Http/HttpContent.cs | 6 +++--- .../Net/Http/MessageProcessingHandler.cs | 2 +- .../ChunkedEncodingReadStream.cs | 2 +- .../Http/SocketsHttpHandler/ConnectHelper.cs | 6 +++--- .../ContentLengthReadStream.cs | 2 +- .../Http/SocketsHttpHandler/CreditWaiter.cs | 2 +- .../SocketsHttpHandler/Http2Connection.cs | 20 +++++++++---------- .../Http/SocketsHttpHandler/Http2Stream.cs | 8 ++++---- .../SocketsHttpHandler/Http3RequestStream.cs | 6 ++---- .../Http/SocketsHttpHandler/HttpConnection.cs | 4 ++-- .../SocketsHttpHandler/HttpConnectionBase.cs | 4 ++-- .../SocketsHttpHandler/HttpConnectionPool.cs | 2 +- .../HttpConnectionPoolManager.cs | 2 +- .../src/System/BitConverter.cs | 2 +- .../Environment.GetFolderPathCore.Unix.cs | 2 +- .../System/Globalization/CalendarData.Icu.cs | 2 +- .../src/System/IO/FileStream.Unix.cs | 8 ++++---- .../src/System/IO/FileStream.Windows.cs | 2 +- .../src/System/IO/Path.cs | 6 +++--- .../src/System/IO/Stream.cs | 4 ++-- .../src/System/IO/TextReader.cs | 8 ++++---- .../src/System/IO/TextWriter.cs | 18 ++++++++--------- .../System/Resources/ResourceReader.Core.cs | 4 ++-- .../Runtime/CompilerServices/TaskAwaiter.cs | 2 +- .../CompilerServices/ValueTaskAwaiter.cs | 2 +- .../CompilerServices/YieldAwaitable.cs | 6 +++--- .../src/System/Text/Latin1Encoding.cs | 4 ++-- .../src/System/Text/Utf8Span.cs | 2 +- .../Threading/CancellationTokenSource.cs | 8 ++++---- .../src/System/Threading/SemaphoreSlim.cs | 2 +- .../Threading/SynchronizationContext.cs | 2 +- .../Tasks/ConcurrentExclusiveSchedulerPair.cs | 2 +- .../System/Threading/Tasks/FutureFactory.cs | 16 +++++++-------- .../Sources/ManualResetValueTaskSourceCore.cs | 4 ++-- .../src/System/Threading/Tasks/Task.cs | 12 +++++------ .../Threading/Tasks/TaskContinuation.cs | 6 +++--- .../System/Threading/Tasks/TaskScheduler.cs | 2 +- .../Tasks/ThreadPoolTaskScheduler.cs | 2 +- .../src/System/Threading/Tasks/ValueTask.cs | 4 ++-- .../src/System/Threading/ThreadPool.cs | 2 +- .../src/System/Threading/Timer.cs | 2 +- .../src/System/TimeZoneInfo.cs | 2 +- .../Threading/Channels/AsyncOperation.cs | 10 +++++----- 51 files changed, 136 insertions(+), 142 deletions(-) diff --git a/src/libraries/Common/src/System/HexConverter.cs b/src/libraries/Common/src/System/HexConverter.cs index d6160a18aa031e..df2e4417b40c95 100644 --- a/src/libraries/Common/src/System/HexConverter.cs +++ b/src/libraries/Common/src/System/HexConverter.cs @@ -120,7 +120,7 @@ public static unsafe string ToString(ReadOnlySpan bytes, Casing casing = C #else fixed (byte* bytesPtr = bytes) { - return string.Create(bytes.Length * 2, (Ptr: (IntPtr)bytesPtr, bytes.Length, casing), (chars, args) => + return string.Create(bytes.Length * 2, (Ptr: (IntPtr)bytesPtr, bytes.Length, casing), static (chars, args) => { var ros = new ReadOnlySpan((byte*)args.Ptr, args.Length); EncodeToUtf16(ros, chars, args.casing); diff --git a/src/libraries/Common/src/System/Net/HttpKnownHeaderNames.TryGetHeaderName.cs b/src/libraries/Common/src/System/Net/HttpKnownHeaderNames.TryGetHeaderName.cs index 05871eae320fdc..bd8a01a8e1e1a1 100644 --- a/src/libraries/Common/src/System/Net/HttpKnownHeaderNames.TryGetHeaderName.cs +++ b/src/libraries/Common/src/System/Net/HttpKnownHeaderNames.TryGetHeaderName.cs @@ -22,8 +22,8 @@ public static bool TryGetHeaderName(char[] array, int startIndex, int length, [N return TryGetHeaderName( array, startIndex, length, - (arr, index) => arr[index], - (known, arr, start, len) => known.AsSpan().SequenceEqual(arr.AsSpan(start, len)), + static (arr, index) => arr[index], + static (known, arr, start, len) => known.AsSpan().SequenceEqual(arr.AsSpan(start, len)), out name); } @@ -46,8 +46,8 @@ public static unsafe bool TryGetHeaderName(IntPtr buffer, int length, out string return TryGetHeaderName( buffer, startIndex, length, - (buf, index) => (char)((byte*)buf)[index], - (known, buf, start, len) => EqualsOrdinal(known, buf, len), + static (buf, index) => (char)((byte*)buf)[index], + static (known, buf, start, len) => EqualsOrdinal(known, buf, len), out name); } diff --git a/src/libraries/Common/src/System/Net/WebSockets/ManagedWebSocket.cs b/src/libraries/Common/src/System/Net/WebSockets/ManagedWebSocket.cs index 77e89ea60a9749..38a83c25d151ca 100644 --- a/src/libraries/Common/src/System/Net/WebSockets/ManagedWebSocket.cs +++ b/src/libraries/Common/src/System/Net/WebSockets/ManagedWebSocket.cs @@ -182,7 +182,7 @@ private ManagedWebSocket(Stream stream, bool isServer, string? subprotocol, Time // Set up the abort source so that if it's triggered, we transition the instance appropriately. // There's no need to store the resulting CancellationTokenRegistration, as this instance owns // the CancellationTokenSource, and the lifetime of that CTS matches the lifetime of the registration. - _abortSource.Token.UnsafeRegister(s => + _abortSource.Token.UnsafeRegister(static s => { var thisRef = (ManagedWebSocket)s!; @@ -203,7 +203,7 @@ private ManagedWebSocket(Stream stream, bool isServer, string? subprotocol, Time // that could keep the web socket rooted in erroneous cases. if (keepAliveInterval > TimeSpan.Zero) { - _keepAliveTimer = new Timer(s => + _keepAliveTimer = new Timer(static s => { var wr = (WeakReference)s!; if (wr.TryGetTarget(out ManagedWebSocket? thisRef)) @@ -448,7 +448,7 @@ private async ValueTask SendFrameFallbackAsync(MessageOpcode opcode, bool endOfM try { int sendBytes = WriteFrameToSendBuffer(opcode, endOfMessage, payloadBuffer.Span); - using (cancellationToken.Register(s => ((ManagedWebSocket)s!).Abort(), this)) + using (cancellationToken.Register(static s => ((ManagedWebSocket)s!).Abort(), this)) { await _stream.WriteAsync(new ReadOnlyMemory(_sendBuffer, 0, sendBytes), cancellationToken).ConfigureAwait(false); } @@ -523,7 +523,7 @@ private void SendKeepAliveFrameAsync() else { // "Observe" any exception, ignoring it to prevent the unobserved exception event from being raised. - t.AsTask().ContinueWith(p => { _ = p.Exception; }, + t.AsTask().ContinueWith(static p => { _ = p.Exception; }, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default); @@ -633,7 +633,7 @@ private async ValueTask ReceiveAsyncPrivate ((ManagedWebSocket)s!).Abort(), this); + CancellationTokenRegistration registration = cancellationToken.Register(static s => ((ManagedWebSocket)s!).Abort(), this); try { while (true) // in case we get control frames that should be ignored from the user's perspective @@ -868,7 +868,7 @@ private async ValueTask WaitForServerToCloseConnectionAsync(CancellationToken ca { const int WaitForCloseTimeoutMs = 1_000; // arbitrary amount of time to give the server (same as netfx) using (var finalCts = new CancellationTokenSource(WaitForCloseTimeoutMs)) - using (finalCts.Token.Register(s => ((ManagedWebSocket)s!).Abort(), this)) + using (finalCts.Token.Register(static s => ((ManagedWebSocket)s!).Abort(), this)) { try { @@ -1138,7 +1138,7 @@ private async Task CloseAsyncPrivate(WebSocketCloseStatus closeStatus, string? s // If this is an existing receive, and if we have a cancelable token, we need to register with that // token while we wait, since it may not be the same one that was given to the receive initially. Debug.Assert(receiveTask != null); - using (usingExistingReceive ? cancellationToken.Register(s => ((ManagedWebSocket)s!).Abort(), this) : default) + using (usingExistingReceive ? cancellationToken.Register(static s => ((ManagedWebSocket)s!).Abort(), this) : default) { await receiveTask.ConfigureAwait(false); } diff --git a/src/libraries/Common/src/System/Threading/Tasks/RendezvousAwaitable.cs b/src/libraries/Common/src/System/Threading/Tasks/RendezvousAwaitable.cs index 5c8cbc55cbeacc..3b4fd9a3acbb4a 100644 --- a/src/libraries/Common/src/System/Threading/Tasks/RendezvousAwaitable.cs +++ b/src/libraries/Common/src/System/Threading/Tasks/RendezvousAwaitable.cs @@ -14,7 +14,7 @@ namespace System.Threading.Tasks internal class RendezvousAwaitable : ICriticalNotifyCompletion { /// Sentinel object indicating that the operation has completed prior to OnCompleted being called. - private static readonly Action s_completionSentinel = () => Debug.Fail("Completion sentinel should never be invoked"); + private static readonly Action s_completionSentinel = static () => Debug.Fail("Completion sentinel should never be invoked"); /// /// The continuation to invoke when the operation completes, or if the operation diff --git a/src/libraries/Common/src/System/Threading/Tasks/TaskCompletionSourceWithCancellation.cs b/src/libraries/Common/src/System/Threading/Tasks/TaskCompletionSourceWithCancellation.cs index 56cea38604288d..4c1e370f6270f5 100644 --- a/src/libraries/Common/src/System/Threading/Tasks/TaskCompletionSourceWithCancellation.cs +++ b/src/libraries/Common/src/System/Threading/Tasks/TaskCompletionSourceWithCancellation.cs @@ -25,7 +25,7 @@ private void OnCancellation() public async ValueTask WaitWithCancellationAsync(CancellationToken cancellationToken) { _cancellationToken = cancellationToken; - using (cancellationToken.UnsafeRegister(s => ((TaskCompletionSourceWithCancellation)s!).OnCancellation(), this)) + using (cancellationToken.UnsafeRegister(static s => ((TaskCompletionSourceWithCancellation)s!).OnCancellation(), this)) { return await Task.ConfigureAwait(false); } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpRequestHeaders.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpRequestHeaders.cs index 9f837133de0a9b..b2eacbfd619f00 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpRequestHeaders.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpRequestHeaders.cs @@ -35,16 +35,16 @@ private T GetSpecializedCollection(int slot, Func crea } public HttpHeaderValueCollection Accept => - GetSpecializedCollection(AcceptSlot, thisRef => new HttpHeaderValueCollection(KnownHeaders.Accept.Descriptor, thisRef)); + GetSpecializedCollection(AcceptSlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.Accept.Descriptor, thisRef)); public HttpHeaderValueCollection AcceptCharset => - GetSpecializedCollection(AcceptCharsetSlot, thisRef => new HttpHeaderValueCollection(KnownHeaders.AcceptCharset.Descriptor, thisRef)); + GetSpecializedCollection(AcceptCharsetSlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.AcceptCharset.Descriptor, thisRef)); public HttpHeaderValueCollection AcceptEncoding => - GetSpecializedCollection(AcceptEncodingSlot, thisRef => new HttpHeaderValueCollection(KnownHeaders.AcceptEncoding.Descriptor, thisRef)); + GetSpecializedCollection(AcceptEncodingSlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.AcceptEncoding.Descriptor, thisRef)); public HttpHeaderValueCollection AcceptLanguage => - GetSpecializedCollection(AcceptLanguageSlot, thisRef => new HttpHeaderValueCollection(KnownHeaders.AcceptLanguage.Descriptor, thisRef)); + GetSpecializedCollection(AcceptLanguageSlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.AcceptLanguage.Descriptor, thisRef)); public AuthenticationHeaderValue? Authorization { @@ -130,7 +130,7 @@ public string? Host } public HttpHeaderValueCollection IfMatch => - GetSpecializedCollection(IfMatchSlot, thisRef => new HttpHeaderValueCollection(KnownHeaders.IfMatch.Descriptor, thisRef)); + GetSpecializedCollection(IfMatchSlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.IfMatch.Descriptor, thisRef)); public DateTimeOffset? IfModifiedSince { @@ -139,7 +139,7 @@ public DateTimeOffset? IfModifiedSince } public HttpHeaderValueCollection IfNoneMatch => - GetSpecializedCollection(IfNoneMatchSlot, thisRef => new HttpHeaderValueCollection(KnownHeaders.IfNoneMatch.Descriptor, thisRef)); + GetSpecializedCollection(IfNoneMatchSlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.IfNoneMatch.Descriptor, thisRef)); public RangeConditionHeaderValue? IfRange { @@ -187,10 +187,10 @@ public Uri? Referrer } public HttpHeaderValueCollection TE => - GetSpecializedCollection(TransferEncodingSlot, thisRef => new HttpHeaderValueCollection(KnownHeaders.TE.Descriptor, thisRef)); + GetSpecializedCollection(TransferEncodingSlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.TE.Descriptor, thisRef)); public HttpHeaderValueCollection UserAgent => - GetSpecializedCollection(UserAgentSlot, thisRef => new HttpHeaderValueCollection(KnownHeaders.UserAgent.Descriptor, thisRef)); + GetSpecializedCollection(UserAgentSlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.UserAgent.Descriptor, thisRef)); private HttpHeaderValueCollection ExpectCore => _expect ??= new HttpHeaderValueCollection(KnownHeaders.Expect.Descriptor, this, HeaderUtilities.ExpectContinue); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpResponseHeaders.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpResponseHeaders.cs index fd8557f758ccef..2c03f00acf7972 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpResponseHeaders.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/HttpResponseHeaders.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; namespace System.Net.Http.Headers { @@ -36,7 +35,7 @@ private T GetSpecializedCollection(int slot, Func cre } public HttpHeaderValueCollection AcceptRanges => - GetSpecializedCollection(AcceptRangesSlot, thisRef => new HttpHeaderValueCollection(KnownHeaders.AcceptRanges.Descriptor, thisRef, HeaderUtilities.TokenValidator)); + GetSpecializedCollection(AcceptRangesSlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.AcceptRanges.Descriptor, thisRef, HeaderUtilities.TokenValidator)); public TimeSpan? Age { @@ -57,7 +56,7 @@ public Uri? Location } public HttpHeaderValueCollection ProxyAuthenticate => - GetSpecializedCollection(ProxyAuthenticateSlot, thisRef => new HttpHeaderValueCollection(KnownHeaders.ProxyAuthenticate.Descriptor, thisRef)); + GetSpecializedCollection(ProxyAuthenticateSlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.ProxyAuthenticate.Descriptor, thisRef)); public RetryConditionHeaderValue? RetryAfter { @@ -66,13 +65,13 @@ public RetryConditionHeaderValue? RetryAfter } public HttpHeaderValueCollection Server => - GetSpecializedCollection(ServerSlot, thisRef => new HttpHeaderValueCollection(KnownHeaders.Server.Descriptor, thisRef)); + GetSpecializedCollection(ServerSlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.Server.Descriptor, thisRef)); public HttpHeaderValueCollection Vary => - GetSpecializedCollection(VarySlot, thisRef => new HttpHeaderValueCollection(KnownHeaders.Vary.Descriptor, thisRef, HeaderUtilities.TokenValidator)); + GetSpecializedCollection(VarySlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.Vary.Descriptor, thisRef, HeaderUtilities.TokenValidator)); public HttpHeaderValueCollection WwwAuthenticate => - GetSpecializedCollection(WwwAuthenticateSlot, thisRef => new HttpHeaderValueCollection(KnownHeaders.WWWAuthenticate.Descriptor, thisRef)); + GetSpecializedCollection(WwwAuthenticateSlot, static thisRef => new HttpHeaderValueCollection(KnownHeaders.WWWAuthenticate.Descriptor, thisRef)); #endregion diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/MediaTypeHeaderParser.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/MediaTypeHeaderParser.cs index ab8d0a6cd288de..42e4cf3f043fc5 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/Headers/MediaTypeHeaderParser.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/Headers/MediaTypeHeaderParser.cs @@ -10,12 +10,9 @@ internal class MediaTypeHeaderParser : BaseHeaderParser private readonly bool _supportsMultipleValues; private readonly Func _mediaTypeCreator; - internal static readonly MediaTypeHeaderParser SingleValueParser = new MediaTypeHeaderParser(false, - CreateMediaType); - internal static readonly MediaTypeHeaderParser SingleValueWithQualityParser = new MediaTypeHeaderParser(false, - CreateMediaTypeWithQuality); - internal static readonly MediaTypeHeaderParser MultipleValuesParser = new MediaTypeHeaderParser(true, - CreateMediaTypeWithQuality); + internal static readonly MediaTypeHeaderParser SingleValueParser = new MediaTypeHeaderParser(false, CreateMediaType); + internal static readonly MediaTypeHeaderParser SingleValueWithQualityParser = new MediaTypeHeaderParser(false, CreateMediaTypeWithQuality); + internal static readonly MediaTypeHeaderParser MultipleValuesParser = new MediaTypeHeaderParser(true, CreateMediaTypeWithQuality); private MediaTypeHeaderParser(bool supportsMultipleValues, Func mediaTypeCreator) : base(supportsMultipleValues) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpContent.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpContent.cs index 0ec9f1ab0a39a5..7ceae4eeacccea 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpContent.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpContent.cs @@ -155,7 +155,7 @@ public Task ReadAsStringAsync() => public Task ReadAsStringAsync(CancellationToken cancellationToken) { CheckDisposed(); - return WaitAndReturnAsync(LoadIntoBufferAsync(cancellationToken), this, s => s.ReadBufferedContentAsString()); + return WaitAndReturnAsync(LoadIntoBufferAsync(cancellationToken), this, static s => s.ReadBufferedContentAsString()); } private string ReadBufferedContentAsString() @@ -240,7 +240,7 @@ public Task ReadAsByteArrayAsync() => public Task ReadAsByteArrayAsync(CancellationToken cancellationToken) { CheckDisposed(); - return WaitAndReturnAsync(LoadIntoBufferAsync(cancellationToken), this, s => s.ReadBufferedContentAsByteArray()); + return WaitAndReturnAsync(LoadIntoBufferAsync(cancellationToken), this, static s => s.ReadBufferedContentAsByteArray()); } internal byte[] ReadBufferedContentAsByteArray() @@ -457,7 +457,7 @@ internal void LoadIntoBuffer(long maxBufferSize, CancellationToken cancellationT // We're only comfortable disposing of the HttpContent instance like this because LoadIntoBuffer is internal and // we're only using it on content instances we get back from a handler's Send call that haven't been given out to the user yet. // If we were to ever make LoadIntoBuffer public, we'd need to rethink this. - CancellationTokenRegistration cancellationRegistration = cancellationToken.Register(s => ((HttpContent)s!).Dispose(), this); + CancellationTokenRegistration cancellationRegistration = cancellationToken.Register(static s => ((HttpContent)s!).Dispose(), this); try { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/MessageProcessingHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/MessageProcessingHandler.cs index dff8ab9db0f524..f903186995e70c 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/MessageProcessingHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/MessageProcessingHandler.cs @@ -63,7 +63,7 @@ protected internal sealed override Task SendAsync(HttpReque // We schedule a continuation task once the inner handler completes in order to trigger the response // processing method. ProcessResponse() is only called if the task wasn't canceled before. - sendAsyncTask.ContinueWithStandard(tcs, (task, state) => + sendAsyncTask.ContinueWithStandard(tcs, static (task, state) => { var sendState = (SendState)state!; MessageProcessingHandler self = sendState._handler; diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingReadStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingReadStream.cs index 7cef2961ed160f..d747bd8ba233ad 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingReadStream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ChunkedEncodingReadStream.cs @@ -468,7 +468,7 @@ public override async ValueTask DrainAsync(int maxDrainBytes) if (drainTime != Timeout.InfiniteTimeSpan) { cts = new CancellationTokenSource((int)drainTime.TotalMilliseconds); - ctr = cts.Token.Register(s => ((HttpConnection)s!).Dispose(), _connection); + ctr = cts.Token.Register(static s => ((HttpConnection)s!).Dispose(), _connection); } } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs index ab6047ec43ce4a..31b33df8c6b36d 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs @@ -55,7 +55,7 @@ private static async ValueTask ConnectAsync(string host, int port, Cance if (Socket.ConnectAsync(SocketType.Stream, ProtocolType.Tcp, saea)) { // Connect completing asynchronously. Enable it to be canceled and wait for it. - using (cancellationToken.UnsafeRegister(s => Socket.CancelConnectAsync((SocketAsyncEventArgs)s!), saea)) + using (cancellationToken.UnsafeRegister(static s => Socket.CancelConnectAsync((SocketAsyncEventArgs)s!), saea)) { await saea.Builder.Task.ConfigureAwait(false); } @@ -92,7 +92,7 @@ private static Stream Connect(string host, int port, CancellationToken cancellat try { socket.NoDelay = true; - using (cancellationToken.UnsafeRegister(s => ((Socket)s!).Dispose(), socket)) + using (cancellationToken.UnsafeRegister(static s => ((Socket)s!).Dispose(), socket)) { socket.Connect(new DnsEndPoint(host, port)); } @@ -186,7 +186,7 @@ private static async ValueTask EstablishSslConnectionAsyncCore(bool a } else { - using (cancellationToken.UnsafeRegister(s => ((Stream)s!).Dispose(), stream)) + using (cancellationToken.UnsafeRegister(static s => ((Stream)s!).Dispose(), stream)) { sslStream.AuthenticateAsClient(sslOptions); } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ContentLengthReadStream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ContentLengthReadStream.cs index ca0e0033d57366..f6f7b44da3e196 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ContentLengthReadStream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ContentLengthReadStream.cs @@ -218,7 +218,7 @@ public override async ValueTask DrainAsync(int maxDrainBytes) if (drainTime != Timeout.InfiniteTimeSpan) { cts = new CancellationTokenSource((int)drainTime.TotalMilliseconds); - ctr = cts.Token.Register(s => ((HttpConnection)s!).Dispose(), _connection); + ctr = cts.Token.Register(static s => ((HttpConnection)s!).Dispose(), _connection); } try { diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CreditWaiter.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CreditWaiter.cs index 430d92a6543160..31ca2470b1f135 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CreditWaiter.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/CreditWaiter.cs @@ -84,7 +84,7 @@ public override void CleanUp() private void RegisterCancellation(CancellationToken cancellationToken) { - _registration = cancellationToken.UnsafeRegister(s => + _registration = cancellationToken.UnsafeRegister(static s => { CancelableCreditWaiter thisRef = (CancelableCreditWaiter)s!; lock (thisRef._syncObj) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs index e34219aac41739..5432df730991f6 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Connection.cs @@ -765,7 +765,7 @@ private void ProcessGoAwayFrame(FrameHeader frameHeader) } internal Task FlushAsync(CancellationToken cancellationToken) => - PerformWriteAsync(0, 0, (_, __) => true, cancellationToken); + PerformWriteAsync(0, 0, static (_, __) => true, cancellationToken); private abstract class WriteQueueEntry : TaskCompletionSource { @@ -778,7 +778,7 @@ public WriteQueueEntry(int writeBytes, CancellationToken cancellationToken) WriteBytes = writeBytes; _cancellationToken = cancellationToken; - _cancellationRegistration = cancellationToken.UnsafeRegister(s => ((WriteQueueEntry)s!).OnCancellation(), this); + _cancellationRegistration = cancellationToken.UnsafeRegister(static s => ((WriteQueueEntry)s!).OnCancellation(), this); } public int WriteBytes { get; } @@ -901,7 +901,7 @@ private async Task ProcessOutgoingFramesAsync() } private Task SendSettingsAckAsync() => - PerformWriteAsync(FrameHeader.Size, this, (thisRef, writeBuffer) => + PerformWriteAsync(FrameHeader.Size, this, static (thisRef, writeBuffer) => { if (NetEventSource.Log.IsEnabled()) thisRef.Trace("Started writing."); @@ -912,7 +912,7 @@ private Task SendSettingsAckAsync() => /// The 8-byte ping content to send, read as a big-endian integer. private Task SendPingAckAsync(long pingContent) => - PerformWriteAsync(FrameHeader.Size + FrameHeader.PingLength, (thisRef: this, pingContent), (state, writeBuffer) => + PerformWriteAsync(FrameHeader.Size + FrameHeader.PingLength, (thisRef: this, pingContent), static (state, writeBuffer) => { if (NetEventSource.Log.IsEnabled()) state.thisRef.Trace("Started writing."); @@ -926,7 +926,7 @@ private Task SendPingAckAsync(long pingContent) => }); private Task SendRstStreamAsync(int streamId, Http2ProtocolErrorCode errorCode) => - PerformWriteAsync(FrameHeader.Size + FrameHeader.RstStreamLength, (thisRef: this, streamId, errorCode), (s, writeBuffer) => + PerformWriteAsync(FrameHeader.Size + FrameHeader.RstStreamLength, (thisRef: this, streamId, errorCode), static (s, writeBuffer) => { if (NetEventSource.Log.IsEnabled()) s.thisRef.Trace(s.streamId, $"Started writing. {nameof(s.errorCode)}={s.errorCode}"); @@ -1249,7 +1249,7 @@ private async ValueTask SendHeadersAsync(HttpRequestMessage request // Start the write. This serializes access to write to the connection, and ensures that HEADERS // and CONTINUATION frames stay together, as they must do. We use the lock as well to ensure new // streams are created and started in order. - await PerformWriteAsync(totalSize, (thisRef: this, http2Stream, headerBytes, endStream: (request.Content == null), mustFlush), (s, writeBuffer) => + await PerformWriteAsync(totalSize, (thisRef: this, http2Stream, headerBytes, endStream: (request.Content == null), mustFlush), static (s, writeBuffer) => { if (NetEventSource.Log.IsEnabled()) s.thisRef.Trace(s.http2Stream.StreamId, $"Started writing. Total header bytes={s.headerBytes.Length}"); @@ -1269,7 +1269,7 @@ await PerformWriteAsync(totalSize, (thisRef: this, http2Stream, headerBytes, end // assigning the stream ID to ensure only one stream gets an ID, and it must be held // across setting the initial window size (available credit) and storing the stream into // collection such that window size updates are able to atomically affect all known streams. - s.http2Stream.Initialize(s.thisRef._nextStream, _initialWindowSize); + s.http2Stream.Initialize(s.thisRef._nextStream, s.thisRef._initialWindowSize); // Client-initiated streams are always odd-numbered, so increase by 2. s.thisRef._nextStream += 2; @@ -1337,7 +1337,7 @@ private async Task SendStreamDataAsync(int streamId, ReadOnlyMemory buffer (current, remaining) = SplitBuffer(remaining, frameSize); try { - await PerformWriteAsync(FrameHeader.Size + current.Length, (thisRef: this, streamId, current), (s, writeBuffer) => + await PerformWriteAsync(FrameHeader.Size + current.Length, (thisRef: this, streamId, current), static (s, writeBuffer) => { // Invoked while holding the lock: if (NetEventSource.Log.IsEnabled()) s.thisRef.Trace(s.streamId, $"Started writing. {nameof(writeBuffer.Length)}={writeBuffer.Length}"); @@ -1358,7 +1358,7 @@ await PerformWriteAsync(FrameHeader.Size + current.Length, (thisRef: this, strea } private Task SendEndStreamAsync(int streamId) => - PerformWriteAsync(FrameHeader.Size, (thisRef: this, streamId), (s, writeBuffer) => + PerformWriteAsync(FrameHeader.Size, (thisRef: this, streamId), static (s, writeBuffer) => { if (NetEventSource.Log.IsEnabled()) s.thisRef.Trace(s.streamId, "Started writing."); @@ -1371,7 +1371,7 @@ private Task SendWindowUpdateAsync(int streamId, int amount) { // We update both the connection-level and stream-level windows at the same time Debug.Assert(amount > 0); - return PerformWriteAsync(FrameHeader.Size + FrameHeader.WindowUpdateLength, (thisRef: this, streamId, amount), (s, writeBuffer) => + return PerformWriteAsync(FrameHeader.Size + FrameHeader.WindowUpdateLength, (thisRef: this, streamId, amount), static (s, writeBuffer) => { if (NetEventSource.Log.IsEnabled()) s.thisRef.Trace(s.streamId, $"Started writing. {nameof(s.amount)}={s.amount}"); diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs index eb866134c06212..f9cee658c61e7c 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http2Stream.cs @@ -300,8 +300,8 @@ public async ValueTask WaitFor100ContinueAsync(CancellationToken cancellat // We await the created Timer's disposal so that we ensure any work associated with it has quiesced prior to this method // returning, just in case this object is pooled and potentially reused for another operation in the future. TaskCompletionSource waiter = _expect100ContinueWaiter!; - using (cancellationToken.UnsafeRegister(s => ((TaskCompletionSource)s!).TrySetResult(false), waiter)) - await using (new Timer(s => + using (cancellationToken.UnsafeRegister(static s => ((TaskCompletionSource)s!).TrySetResult(false), waiter)) + await using (new Timer(static s => { var thisRef = (Http2Stream)s!; if (NetEventSource.Log.IsEnabled()) thisRef.Trace($"100-Continue timer expired."); @@ -1149,7 +1149,7 @@ private void CloseResponseBody() } private CancellationTokenRegistration RegisterRequestBodyCancellation(CancellationToken cancellationToken) => - cancellationToken.UnsafeRegister(s => ((CancellationTokenSource)s!).Cancel(), _requestBodyCancellationSource); + cancellationToken.UnsafeRegister(static s => ((CancellationTokenSource)s!).Cancel(), _requestBodyCancellationSource); // This object is itself usable as a backing source for ValueTask. Since there's only ever one awaiter // for this object's state transitions at a time, we allow the object to be awaited directly. All functionality @@ -1191,7 +1191,7 @@ private ValueTask WaitForDataAsync(CancellationToken cancellationToken) // However, this could still be non-cancelable if HttpMessageInvoker was used, at which point this will only be // cancelable if the caller's token was cancelable. - _waitSourceCancellation = cancellationToken.UnsafeRegister(s => + _waitSourceCancellation = cancellationToken.UnsafeRegister(static s => { var thisRef = (Http2Stream)s!; 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 52f2363700b70f..07c2840be7e415 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 @@ -331,10 +331,8 @@ private async Task SendContentAsync(HttpContent content, CancellationToken cance { if (_connection.Pool.Settings._expect100ContinueTimeout != Timeout.InfiniteTimeSpan) { - timer = new Timer(o => - { - ((Http3RequestStream)o!)._expect100ContinueCompletionSource!.TrySetResult(true); - }, this, _connection.Pool.Settings._expect100ContinueTimeout, Timeout.InfiniteTimeSpan); + timer = new Timer(static o => ((Http3RequestStream)o!)._expect100ContinueCompletionSource!.TrySetResult(true), + this, _connection.Pool.Settings._expect100ContinueTimeout, Timeout.InfiniteTimeSpan); } if (!await _expect100ContinueCompletionSource.Task.ConfigureAwait(false)) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs index 943eb017d23cac..4a9485a472428e 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnection.cs @@ -457,7 +457,7 @@ public async Task SendAsyncCore(HttpRequestMessage request, // Then kick off the request. The TCS' result indicates whether content should be sent or not. allowExpect100ToContinue = new TaskCompletionSource(); var expect100Timer = new Timer( - s => ((TaskCompletionSource)s!).TrySetResult(true), + static s => ((TaskCompletionSource)s!).TrySetResult(true), allowExpect100ToContinue, _pool.Settings._expect100ContinueTimeout, Timeout.InfiniteTimeSpan); sendRequestContentTask = SendRequestContentWithExpect100ContinueAsync( request, allowExpect100ToContinue.Task, CreateRequestContentStream(request), expect100Timer, async, cancellationToken); @@ -755,7 +755,7 @@ private CancellationTokenRegistration RegisterCancellation(CancellationToken can // request and prioritize that over other exceptions, wrapping the actual exception as an inner of an OCE. // - A weak reference to this HttpConnection is stored in the cancellation token, to prevent the token from // artificially keeping this connection alive. - return cancellationToken.Register(s => + return cancellationToken.Register(static s => { var weakThisRef = (WeakReference)s!; if (weakThisRef.TryGetTarget(out HttpConnection? strongThisRef)) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs index c96f56b2906543..b4b0aa19fbad59 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionBase.cs @@ -111,7 +111,7 @@ internal static void IgnoreExceptions(ValueTask task) } else { - task.AsTask().ContinueWith(t => _ = t.Exception, + task.AsTask().ContinueWith(static t => _ = t.Exception, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default); } } @@ -128,7 +128,7 @@ internal void LogExceptions(Task task) } else { - task.ContinueWith((t, state) => LogFaulted((HttpConnectionBase)state!, t), this, + task.ContinueWith(static (t, state) => LogFaulted((HttpConnectionBase)state!, t), this, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default); } diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs index 94989785eb4cee..a363430d1bf41c 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPool.cs @@ -900,7 +900,7 @@ internal void HandleAltSvc(IEnumerable altSvcHeaderValues, TimeSpan? res restoreFlow = true; } - _authorityExpireTimer = new Timer(o => + _authorityExpireTimer = new Timer(static o => { var wr = (WeakReference)o!; if (wr.TryGetTarget(out HttpConnectionPool? @this)) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPoolManager.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPoolManager.cs index e01950ed8d0e49..67906139abd503 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPoolManager.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPoolManager.cs @@ -102,7 +102,7 @@ public HttpConnectionPoolManager(HttpConnectionSettings settings) // Create the timer. Ensure the Timer has a weak reference to this manager; otherwise, it // can introduce a cycle that keeps the HttpConnectionPoolManager rooted by the Timer // implementation until the handler is Disposed (or indefinitely if it's not). - _cleaningTimer = new Timer(s => + _cleaningTimer = new Timer(static s => { var wr = (WeakReference)s!; if (wr.TryGetTarget(out HttpConnectionPoolManager? thisRef)) diff --git a/src/libraries/System.Private.CoreLib/src/System/BitConverter.cs b/src/libraries/System.Private.CoreLib/src/System/BitConverter.cs index fe03da6ec47be9..4a06da0807f530 100644 --- a/src/libraries/System.Private.CoreLib/src/System/BitConverter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/BitConverter.cs @@ -382,7 +382,7 @@ public static string ToString(byte[] value, int startIndex, int length) throw new ArgumentOutOfRangeException(nameof(length), SR.Format(SR.ArgumentOutOfRange_LengthTooLarge, int.MaxValue / 3)); } - return string.Create(length * 3 - 1, (value, startIndex, length), (dst, state) => + return string.Create(length * 3 - 1, (value, startIndex, length), static (dst, state) => { var src = new ReadOnlySpan(state.value, state.startIndex, state.length); diff --git a/src/libraries/System.Private.CoreLib/src/System/Environment.GetFolderPathCore.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Environment.GetFolderPathCore.Unix.cs index 255717538ffada..10374813d6660d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Environment.GetFolderPathCore.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Environment.GetFolderPathCore.Unix.cs @@ -41,7 +41,7 @@ private static string GetFolderPathCore(SpecialFolder folder, SpecialFolderOptio { Debug.Assert(option == SpecialFolderOption.Create); - Func createDirectory = LazyInitializer.EnsureInitialized(ref s_directoryCreateDirectory, () => + Func createDirectory = LazyInitializer.EnsureInitialized(ref s_directoryCreateDirectory, static () => { Type dirType = Type.GetType("System.IO.Directory, System.IO.FileSystem, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", throwOnError: true)!; MethodInfo mi = dirType.GetTypeInfo().GetDeclaredMethod("CreateDirectory")!; diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs index e5425f8d0a31b3..26567368d392d1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs @@ -121,7 +121,7 @@ private static unsafe bool GetCalendarInfo(string localeName, CalendarId calenda Debug.Assert(!GlobalizationMode.Invariant); return Interop.CallStringMethod( - (buffer, locale, id, type) => + static (buffer, locale, id, type) => { fixed (char* bufferPtr = buffer) { diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/FileStream.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/IO/FileStream.Unix.cs index 1adc48377db072..8d823b5362fb8f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/FileStream.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/FileStream.Unix.cs @@ -290,7 +290,7 @@ public override ValueTask DisposeAsync() // override may already exist on a derived type. if (_useAsyncIO && _writePos > 0) { - return new ValueTask(Task.Factory.StartNew(s => ((FileStream)s!).Dispose(), this, + return new ValueTask(Task.Factory.StartNew(static s => ((FileStream)s!).Dispose(), this, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default)); } @@ -364,7 +364,7 @@ private Task FlushAsyncInternal(CancellationToken cancellationToken) if (CanWrite) { return Task.Factory.StartNew( - state => ((FileStream)state!).FlushOSBuffer(), + static state => ((FileStream)state!).FlushOSBuffer(), this, cancellationToken, TaskCreationOptions.DenyChildAttach, @@ -556,7 +556,7 @@ private unsafe int ReadNative(Span buffer) // Otherwise, issue the whole request asynchronously. synchronousResult = 0; _asyncState.Memory = destination; - return waitTask.ContinueWith((t, s) => + return waitTask.ContinueWith(static (t, s) => { // The options available on Unix for writing asynchronously to an arbitrary file // handle typically amount to just using another thread to do the synchronous write, @@ -715,7 +715,7 @@ private ValueTask WriteAsyncInternal(ReadOnlyMemory source, CancellationTo // Otherwise, issue the whole request asynchronously. _asyncState.ReadOnlyMemory = source; - return new ValueTask(waitTask.ContinueWith((t, s) => + return new ValueTask(waitTask.ContinueWith(static (t, s) => { // The options available on Unix for writing asynchronously to an arbitrary file // handle typically amount to just using another thread to do the synchronous write, diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/FileStream.Windows.cs b/src/libraries/System.Private.CoreLib/src/System/IO/FileStream.Windows.cs index b97fc5251fde22..3cfdf8de38f0b9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/FileStream.Windows.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/FileStream.Windows.cs @@ -1325,7 +1325,7 @@ private async Task AsyncModeCopyToAsync(Stream destination, int bufferSize, Canc // in the read/write copy loop. if (cancellationToken.CanBeCanceled) { - cancellationReg = cancellationToken.UnsafeRegister(s => + cancellationReg = cancellationToken.UnsafeRegister(static s => { Debug.Assert(s is AsyncCopyToAwaitable); var innerAwaitable = (AsyncCopyToAwaitable)s; 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 ce912c51cc47ad..5e3e2096d5869e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Path.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Path.cs @@ -655,7 +655,7 @@ private static unsafe string JoinInternal(ReadOnlySpan first, ReadOnlySpan #endif first.Length + second.Length + (hasSeparator ? 0 : 1), (First: (IntPtr)f, FirstLength: first.Length, Second: (IntPtr)s, SecondLength: second.Length, HasSeparator: hasSeparator), - (destination, state) => + static (destination, state) => { new Span((char*)state.First, state.FirstLength).CopyTo(destination); if (!state.HasSeparator) @@ -684,7 +684,7 @@ private static unsafe string JoinInternal(ReadOnlySpan first, ReadOnlySpan first.Length + second.Length + third.Length + (firstHasSeparator ? 0 : 1) + (thirdHasSeparator ? 0 : 1), (First: (IntPtr)f, FirstLength: first.Length, Second: (IntPtr)s, SecondLength: second.Length, Third: (IntPtr)t, ThirdLength: third.Length, FirstHasSeparator: firstHasSeparator, ThirdHasSeparator: thirdHasSeparator), - (destination, state) => + static (destination, state) => { new Span((char*)state.First, state.FirstLength).CopyTo(destination); if (!state.FirstHasSeparator) @@ -719,7 +719,7 @@ private static unsafe string JoinInternal(ReadOnlySpan first, ReadOnlySpan (First: (IntPtr)f, FirstLength: first.Length, Second: (IntPtr)s, SecondLength: second.Length, Third: (IntPtr)t, ThirdLength: third.Length, Fourth: (IntPtr)u, FourthLength: fourth.Length, FirstHasSeparator: firstHasSeparator, ThirdHasSeparator: thirdHasSeparator, FourthHasSeparator: fourthHasSeparator), - (destination, state) => + static (destination, state) => { new Span((char*)state.First, state.FirstLength).CopyTo(destination); if (!state.FirstHasSeparator) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/Stream.cs b/src/libraries/System.Private.CoreLib/src/System/IO/Stream.cs index dfde3d55c3e983..79388280125786 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/Stream.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/Stream.cs @@ -235,7 +235,7 @@ public Task FlushAsync() public virtual Task FlushAsync(CancellationToken cancellationToken) { - return Task.Factory.StartNew(state => ((Stream)state!).Flush(), this, + return Task.Factory.StartNew(static state => ((Stream)state!).Flush(), this, cancellationToken, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); } @@ -488,7 +488,7 @@ private void RunReadWriteTaskWhenReady(Task asyncWaiter, ReadWriteTask readWrite } else // Otherwise, wait for our turn, and then run the task. { - asyncWaiter.ContinueWith((t, state) => + asyncWaiter.ContinueWith(static (t, state) => { Debug.Assert(t.IsCompletedSuccessfully, "The semaphore wait should always complete successfully."); var rwt = (ReadWriteTask)state!; diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/TextReader.cs b/src/libraries/System.Private.CoreLib/src/System/IO/TextReader.cs index d64625bbff956f..8321c525d2a2ed 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/TextReader.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/TextReader.cs @@ -204,7 +204,7 @@ public virtual int ReadBlock(Span buffer) #region Task based Async APIs public virtual Task ReadLineAsync() => - Task.Factory.StartNew(state => ((TextReader)state!).ReadLine(), this, + Task.Factory.StartNew(static state => ((TextReader)state!).ReadLine(), this, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); public virtual async Task ReadToEndAsync() @@ -247,7 +247,7 @@ public virtual Task ReadAsync(char[] buffer, int index, int count) public virtual ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken = default) => new ValueTask(MemoryMarshal.TryGetArray(buffer, out ArraySegment array) ? ReadAsync(array.Array!, array.Offset, array.Count) : - Task.Factory.StartNew(state => + Task.Factory.StartNew(static state => { var t = (Tuple>)state!; return t.Item1.Read(t.Item2.Span); @@ -256,7 +256,7 @@ public virtual ValueTask ReadAsync(Memory buffer, CancellationToken c internal virtual ValueTask ReadAsyncInternal(Memory buffer, CancellationToken cancellationToken) { var tuple = new Tuple>(this, buffer); - return new ValueTask(Task.Factory.StartNew(state => + return new ValueTask(Task.Factory.StartNew(static state => { var t = (Tuple>)state!; return t.Item1.Read(t.Item2.Span); @@ -285,7 +285,7 @@ public virtual Task ReadBlockAsync(char[] buffer, int index, int count) public virtual ValueTask ReadBlockAsync(Memory buffer, CancellationToken cancellationToken = default) => new ValueTask(MemoryMarshal.TryGetArray(buffer, out ArraySegment array) ? ReadBlockAsync(array.Array!, array.Offset, array.Count) : - Task.Factory.StartNew(state => + Task.Factory.StartNew(static state => { var t = (Tuple>)state!; return t.Item1.ReadBlock(t.Item2.Span); diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/TextWriter.cs b/src/libraries/System.Private.CoreLib/src/System/IO/TextWriter.cs index 15baed8be2f9cb..d969ee23a919c7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/TextWriter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/TextWriter.cs @@ -541,7 +541,7 @@ public virtual void WriteLine(string format, params object?[] arg) public virtual Task WriteAsync(char value) { var tuple = new Tuple(this, value); - return Task.Factory.StartNew(state => + return Task.Factory.StartNew(static state => { var t = (Tuple)state!; t.Item1.Write(t.Item2); @@ -552,7 +552,7 @@ public virtual Task WriteAsync(char value) public virtual Task WriteAsync(string? value) { var tuple = new Tuple(this, value); - return Task.Factory.StartNew(state => + return Task.Factory.StartNew(static state => { var t = (Tuple)state!; t.Item1.Write(t.Item2); @@ -595,7 +595,7 @@ public Task WriteAsync(char[]? buffer) public virtual Task WriteAsync(char[] buffer, int index, int count) { var tuple = new Tuple(this, buffer, index, count); - return Task.Factory.StartNew(state => + return Task.Factory.StartNew(static state => { var t = (Tuple)state!; t.Item1.Write(t.Item2, t.Item3, t.Item4); @@ -607,7 +607,7 @@ public virtual Task WriteAsync(ReadOnlyMemory buffer, CancellationToken ca cancellationToken.IsCancellationRequested ? Task.FromCanceled(cancellationToken) : MemoryMarshal.TryGetArray(buffer, out ArraySegment array) ? WriteAsync(array.Array!, array.Offset, array.Count) : - Task.Factory.StartNew(state => + Task.Factory.StartNew(static state => { var t = (Tuple>)state!; t.Item1.Write(t.Item2.Span); @@ -616,7 +616,7 @@ public virtual Task WriteAsync(ReadOnlyMemory buffer, CancellationToken ca public virtual Task WriteLineAsync(char value) { var tuple = new Tuple(this, value); - return Task.Factory.StartNew(state => + return Task.Factory.StartNew(static state => { var t = (Tuple)state!; t.Item1.WriteLine(t.Item2); @@ -627,7 +627,7 @@ public virtual Task WriteLineAsync(char value) public virtual Task WriteLineAsync(string? value) { var tuple = new Tuple(this, value); - return Task.Factory.StartNew(state => + return Task.Factory.StartNew(static state => { var t = (Tuple)state!; t.Item1.WriteLine(t.Item2); @@ -671,7 +671,7 @@ public Task WriteLineAsync(char[]? buffer) public virtual Task WriteLineAsync(char[] buffer, int index, int count) { var tuple = new Tuple(this, buffer, index, count); - return Task.Factory.StartNew(state => + return Task.Factory.StartNew(static state => { var t = (Tuple)state!; t.Item1.WriteLine(t.Item2, t.Item3, t.Item4); @@ -683,7 +683,7 @@ public virtual Task WriteLineAsync(ReadOnlyMemory buffer, CancellationToke cancellationToken.IsCancellationRequested ? Task.FromCanceled(cancellationToken) : MemoryMarshal.TryGetArray(buffer, out ArraySegment array) ? WriteLineAsync(array.Array!, array.Offset, array.Count) : - Task.Factory.StartNew(state => + Task.Factory.StartNew(static state => { var t = (Tuple>)state!; t.Item1.WriteLine(t.Item2.Span); @@ -696,7 +696,7 @@ public virtual Task WriteLineAsync() public virtual Task FlushAsync() { - return Task.Factory.StartNew(state => ((TextWriter)state!).Flush(), this, + return Task.Factory.StartNew(static state => ((TextWriter)state!).Flush(), this, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); } #endregion diff --git a/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceReader.Core.cs b/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceReader.Core.cs index 880f21c1b98bff..bb2cea4df74978 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceReader.Core.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceReader.Core.cs @@ -78,11 +78,11 @@ private bool InitializeBinaryFormatter() // If BinaryFormatter support is disabled for the app, the linker will replace this entire // method body with "return false;", skipping all reflection code below. - LazyInitializer.EnsureInitialized(ref s_binaryFormatterType, () => + LazyInitializer.EnsureInitialized(ref s_binaryFormatterType, static () => Type.GetType("System.Runtime.Serialization.Formatters.Binary.BinaryFormatter, System.Runtime.Serialization.Formatters, Version=0.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", throwOnError: true)!); - LazyInitializer.EnsureInitialized(ref s_deserializeMethod, () => + LazyInitializer.EnsureInitialized(ref s_deserializeMethod, static () => { MethodInfo binaryFormatterDeserialize = s_binaryFormatterType!.GetMethod("Deserialize", new Type[] { typeof(Stream) })!; diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/TaskAwaiter.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/TaskAwaiter.cs index b14e8432eb3faf..e5eddb76ee9db0 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/TaskAwaiter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/TaskAwaiter.cs @@ -270,7 +270,7 @@ private static Action OutputWaitEtwEvents(Task task, Action continuation) // is enabled, and in doing so it allows us to pass the awaited task's information into the end event // in a purely pay-for-play manner (the alternatively would be to increase the size of TaskAwaiter // just for this ETW purpose, not pay-for-play, since GetResult would need to know whether a real yield occurred). - return AsyncMethodBuilderCore.CreateContinuationWrapper(continuation, (innerContinuation, innerTask) => + return AsyncMethodBuilderCore.CreateContinuationWrapper(continuation, static (innerContinuation, innerTask) => { if (Task.s_asyncDebuggingEnabled) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ValueTaskAwaiter.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ValueTaskAwaiter.cs index 4cf0714e3a5372..68675a82f0afc9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ValueTaskAwaiter.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/ValueTaskAwaiter.cs @@ -14,7 +14,7 @@ namespace System.Runtime.CompilerServices public readonly struct ValueTaskAwaiter : ICriticalNotifyCompletion, IStateMachineBoxAwareAwaiter { /// Shim used to invoke an passed as the state argument to a . - internal static readonly Action s_invokeActionDelegate = state => + internal static readonly Action s_invokeActionDelegate = static state => { if (!(state is Action action)) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/YieldAwaitable.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/YieldAwaitable.cs index 45a73ad88c5aa8..7500cba3d4e303 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/YieldAwaitable.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/YieldAwaitable.cs @@ -129,7 +129,7 @@ void IStateMachineBoxAwareAwaiter.AwaitUnsafeOnCompleted(IAsyncStateMachineBox b SynchronizationContext? syncCtx = SynchronizationContext.Current; if (syncCtx != null && syncCtx.GetType() != typeof(SynchronizationContext)) { - syncCtx.Post(s => ((IAsyncStateMachineBox)s!).MoveNext(), box); + syncCtx.Post(static s => ((IAsyncStateMachineBox)s!).MoveNext(), box); } else { @@ -140,7 +140,7 @@ void IStateMachineBoxAwareAwaiter.AwaitUnsafeOnCompleted(IAsyncStateMachineBox b } else { - Task.Factory.StartNew(s => ((IAsyncStateMachineBox)s!).MoveNext(), box, default, TaskCreationOptions.PreferFairness, scheduler); + Task.Factory.StartNew(static s => ((IAsyncStateMachineBox)s!).MoveNext(), box, default, TaskCreationOptions.PreferFairness, scheduler); } } } @@ -156,7 +156,7 @@ private static Action OutputCorrelationEtwEvent(Action continuation) // fire the correlation ETW event TplEventSource.Log.AwaitTaskContinuationScheduled(TaskScheduler.Current.Id, (currentTask != null) ? currentTask.Id : 0, continuationId); - return AsyncMethodBuilderCore.CreateContinuationWrapper(continuation, (innerContinuation, continuationIdTask) => + return AsyncMethodBuilderCore.CreateContinuationWrapper(continuation, static (innerContinuation, continuationIdTask) => { TplEventSource log = TplEventSource.Log; log.TaskWaitContinuationStarted(((Task)continuationIdTask).Result); 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 5ba1d6a902aa9e..01f6710a9632f5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Latin1Encoding.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Latin1Encoding.cs @@ -542,7 +542,7 @@ public unsafe override string GetString(byte[] bytes) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.bytes); } - return string.Create(bytes.Length, (encoding: this, bytes), (chars, args) => + return string.Create(bytes.Length, (encoding: this, bytes), static (chars, args) => { Debug.Assert(chars.Length == args.bytes.Length); @@ -577,7 +577,7 @@ public unsafe override string GetString(byte[] bytes, int index, int count) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.bytes, ExceptionResource.ArgumentOutOfRange_IndexCountBuffer); } - return string.Create(count, (encoding: this, bytes, index), (chars, args) => + return string.Create(count, (encoding: this, bytes, index), static (chars, args) => { fixed (byte* pBytes = args.bytes) fixed (char* pChars = chars) diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.cs index 83beddeff2e362..fcd6d4f92cb230 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Utf8Span.cs @@ -275,7 +275,7 @@ internal unsafe string ToStringNoReplacement() #if (!NETSTANDARD2_0 && !NETFRAMEWORK) // TODO_UTF8STRING: Can we call string.FastAllocate directly? - return string.Create(utf16CharCount, (pbData: (IntPtr)pData, cbData: Length), (chars, state) => + return string.Create(utf16CharCount, (pbData: (IntPtr)pData, cbData: Length), static (chars, state) => { OperationStatus status = Utf8.ToUtf16(new ReadOnlySpan((byte*)state.pbData, state.cbData), chars, out _, out _, replaceInvalidSequences: false); Debug.Assert(status == OperationStatus.Done, "Did somebody mutate this Utf8String instance unexpectedly?"); diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/CancellationTokenSource.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/CancellationTokenSource.cs index b15c39dd93d1bc..d439fd3c29ec62 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/CancellationTokenSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/CancellationTokenSource.cs @@ -681,7 +681,7 @@ private void ExecuteCallbackHandlers(bool throwOnFirstException) if (node.SynchronizationContext != null) { // Transition to the target syncContext and continue there. - node.SynchronizationContext.Send(s => + node.SynchronizationContext.Send(static s => { var n = (CallbackNode)s!; n.Partition.Source.ThreadIDExecutingCallbacks = Environment.CurrentManagedThreadId; @@ -819,7 +819,7 @@ internal ValueTask WaitForCallbackToCompleteAsync(long id) // unfortunate thing to do. However, we expect this to be a rare case (disposing while the associated // callback is running), and brief when it happens (so the polling will be minimal), and making // this work with a callback mechanism will add additional cost to other more common cases. - return new ValueTask(Task.Factory.StartNew(s => + return new ValueTask(Task.Factory.StartNew(static s => { Debug.Assert(s is Tuple); var state = (Tuple)s; @@ -874,7 +874,7 @@ protected override void Dispose(bool disposing) private sealed class LinkedNCancellationTokenSource : CancellationTokenSource { - internal static readonly Action s_linkedTokenCancelDelegate = s => + internal static readonly Action s_linkedTokenCancelDelegate = static s => { Debug.Assert(s is CancellationTokenSource, $"Expected {typeof(CancellationTokenSource)}, got {s}"); ((CancellationTokenSource)s).NotifyCancellation(throwOnFirstException: false); // skip ThrowIfDisposed() check in Cancel() @@ -1028,7 +1028,7 @@ public void ExecuteCallback() ExecutionContext? context = ExecutionContext; if (context != null) { - ExecutionContext.RunInternal(context, s => + ExecutionContext.RunInternal(context, static s => { Debug.Assert(s is CallbackNode, $"Expected {typeof(CallbackNode)}, got {s}"); CallbackNode n = (CallbackNode)s; diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/SemaphoreSlim.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/SemaphoreSlim.cs index f4fa69d1c2ec55..7b13c93c0b5592 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/SemaphoreSlim.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/SemaphoreSlim.cs @@ -728,7 +728,7 @@ private async Task WaitUntilCountOrTimeoutAsync(TaskNode asyncWaiter, int { // Wait until either the task is completed or cancellation is requested. var cancellationTask = new Task(null, TaskCreationOptions.RunContinuationsAsynchronously, promiseStyle: true); - using (cancellationToken.UnsafeRegister(s => ((Task)s!).TrySetResult(), cancellationTask)) + using (cancellationToken.UnsafeRegister(static s => ((Task)s!).TrySetResult(), cancellationTask)) { if (asyncWaiter == await Task.WhenAny(asyncWaiter, cancellationTask).ConfigureAwait(false)) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/SynchronizationContext.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/SynchronizationContext.cs index cce3668bd58431..b3ed9d1b9691f9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/SynchronizationContext.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/SynchronizationContext.cs @@ -19,7 +19,7 @@ public SynchronizationContext() public virtual void Send(SendOrPostCallback d, object? state) => d(state); - public virtual void Post(SendOrPostCallback d, object? state) => ThreadPool.QueueUserWorkItem(s => s.d(s.state), (d, state), preferLocal: false); + public virtual void Post(SendOrPostCallback d, object? state) => ThreadPool.QueueUserWorkItem(static s => s.d(s.state), (d, state), preferLocal: false); /// /// Optional override for subclasses, for responding to notification that operation is starting. diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs index 8537465a43bc1d..cec1ef48a1c090 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/ConcurrentExclusiveSchedulerPair.cs @@ -197,7 +197,7 @@ private void CompleteTaskAsync() if (!cs.m_completionQueued) { cs.m_completionQueued = true; - ThreadPool.QueueUserWorkItem(state => + ThreadPool.QueueUserWorkItem(static state => { Debug.Assert(state is ConcurrentExclusiveSchedulerPair); var localThis = (ConcurrentExclusiveSchedulerPair)state; diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/FutureFactory.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/FutureFactory.cs index 8049fd764b904f..b2ca3898176ce8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/FutureFactory.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/FutureFactory.cs @@ -1670,7 +1670,7 @@ internal static Task ContinueWhenAllImpl(Task[] tasks, if (continuationFunction != null) { return starter.ContinueWith( - (completedTasks, state) => + static (completedTasks, state) => { completedTasks.NotifyDebuggerOfWaitCompletionIfNecessary(); Debug.Assert(state is Func); @@ -1682,7 +1682,7 @@ internal static Task ContinueWhenAllImpl(Task[] tasks, { Debug.Assert(continuationAction != null); return starter.ContinueWith( - (completedTasks, state) => + static (completedTasks, state) => { completedTasks.NotifyDebuggerOfWaitCompletionIfNecessary(); Debug.Assert(state is Action); @@ -1992,7 +1992,7 @@ internal static Task ContinueWhenAnyImpl(Task[] tasks, if (continuationFunction != null) { return starter.ContinueWith( - (completedTask, state) => + static (completedTask, state) => { Debug.Assert(state is Func); return ((Func)state)(completedTask.Result); @@ -2003,7 +2003,7 @@ internal static Task ContinueWhenAnyImpl(Task[] tasks, { Debug.Assert(continuationAction != null); return starter.ContinueWith( - (completedTask, state) => + static (completedTask, state) => { Debug.Assert(state is Action); ((Action)state)(completedTask.Result); @@ -2063,7 +2063,7 @@ internal static class GenericDelegateCache { // ContinueWith delegate for TaskFactory.ContinueWhenAnyImpl(non-null continuationFunction) internal static Func, object?, TResult> CWAnyFuncDelegate = - (Task wrappedWinner, object? state) => + static (Task wrappedWinner, object? state) => { Debug.Assert(state is Func, TResult>); var func = (Func, TResult>)state; @@ -2073,7 +2073,7 @@ internal static class GenericDelegateCache // ContinueWith delegate for TaskFactory.ContinueWhenAnyImpl(non-null continuationAction) internal static Func, object?, TResult> CWAnyActionDelegate = - (Task wrappedWinner, object? state) => + static (Task wrappedWinner, object? state) => { Debug.Assert(state is Action>); var action = (Action>)state; @@ -2084,7 +2084,7 @@ internal static class GenericDelegateCache // ContinueWith delegate for TaskFactory.ContinueWhenAllImpl(non-null continuationFunction) internal static Func[]>, object?, TResult> CWAllFuncDelegate = - (Task[]> wrappedAntecedents, object? state) => + static (Task[]> wrappedAntecedents, object? state) => { wrappedAntecedents.NotifyDebuggerOfWaitCompletionIfNecessary(); Debug.Assert(state is Func[], TResult>); @@ -2094,7 +2094,7 @@ internal static class GenericDelegateCache // ContinueWith delegate for TaskFactory.ContinueWhenAllImpl(non-null continuationAction) internal static Func[]>, object?, TResult> CWAllActionDelegate = - (Task[]> wrappedAntecedents, object? state) => + static (Task[]> wrappedAntecedents, object? state) => { wrappedAntecedents.NotifyDebuggerOfWaitCompletionIfNecessary(); Debug.Assert(state is Action[]>); diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Sources/ManualResetValueTaskSourceCore.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Sources/ManualResetValueTaskSourceCore.cs index 734c1a605cedee..8a4a2db853144c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Sources/ManualResetValueTaskSourceCore.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Sources/ManualResetValueTaskSourceCore.cs @@ -173,7 +173,7 @@ public void OnCompleted(Action continuation, object? state, short token break; case SynchronizationContext sc: - sc.Post(s => + sc.Post(static s => { var tuple = (Tuple, object?>)s!; tuple.Item1(tuple.Item2); @@ -318,7 +318,7 @@ private void InvokeSchedulerContinuation() switch (_capturedContext) { case SynchronizationContext sc: - sc.Post(s => + sc.Post(static s => { var state = (Tuple, object?>)s!; state.Item1(state.Item2); diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs index fbf12c5cc4c488..3b34af008a2b85 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/Task.cs @@ -619,7 +619,7 @@ private void AssignCancellationToken(CancellationToken cancellationToken, Task? if (antecedent == null) { // if no antecedent was specified, use this task's reference as the cancellation state object - ctr = cancellationToken.UnsafeRegister(t => ((Task)t!).InternalCancel(), this); + ctr = cancellationToken.UnsafeRegister(static t => ((Task)t!).InternalCancel(), this); } else { @@ -628,7 +628,7 @@ private void AssignCancellationToken(CancellationToken cancellationToken, Task? // If an antecedent was specified, pack this task, its antecedent and the TaskContinuation together as a tuple // and use it as the cancellation state object. This will be unpacked in the cancellation callback so that // antecedent.RemoveCancellation(continuation) can be invoked. - ctr = cancellationToken.UnsafeRegister(t => + ctr = cancellationToken.UnsafeRegister(static t => { var tuple = (Tuple)t!; @@ -1880,7 +1880,7 @@ internal static void ThrowAsync(Exception exception, SynchronizationContext? tar try { // Post the throwing of the exception to that context, and return. - targetContext.Post(state => ((ExceptionDispatchInfo)state!).Throw(), edi); + targetContext.Post(static state => ((ExceptionDispatchInfo)state!).Throw(), edi); return; } catch (Exception postException) @@ -1895,7 +1895,7 @@ internal static void ThrowAsync(Exception exception, SynchronizationContext? tar RuntimeExceptionHelpers.ReportUnhandledException(edi.SourceException); #else // Propagate the exception(s) on the ThreadPool - ThreadPool.QueueUserWorkItem(state => ((ExceptionDispatchInfo)state!).Throw(), edi); + ThreadPool.QueueUserWorkItem(static state => ((ExceptionDispatchInfo)state!).Throw(), edi); #endif // CORERT } @@ -5420,7 +5420,7 @@ internal DelayPromiseWithCancellation(int millisecondsDelay, CancellationToken t Debug.Assert(token.CanBeCanceled); _token = token; - _registration = token.UnsafeRegister(state => ((DelayPromiseWithCancellation)state!).CompleteCanceled(), this); + _registration = token.UnsafeRegister(static state => ((DelayPromiseWithCancellation)state!).CompleteCanceled(), this); } private void CompleteCanceled() @@ -6590,7 +6590,7 @@ private void InvokeCoreAsync(Task completingTask) // there's a high liklihood this thread is going to be doing lots more work before // returning to the thread pool (at the very least unwinding through thousands of // stack frames). So we queue to the global queue. - ThreadPool.UnsafeQueueUserWorkItem(state => + ThreadPool.UnsafeQueueUserWorkItem(static state => { // InvokeCore(completingTask); var tuple = (Tuple, Task>)state!; diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TaskContinuation.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TaskContinuation.cs index 9136bad1024087..f6a1627450597a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TaskContinuation.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TaskContinuation.cs @@ -364,7 +364,7 @@ internal override void Run(Task completedTask, bool canInlineContinuationTask) internal sealed class SynchronizationContextAwaitTaskContinuation : AwaitTaskContinuation { /// SendOrPostCallback delegate to invoke the action. - private static readonly SendOrPostCallback s_postCallback = state => + private static readonly SendOrPostCallback s_postCallback = static state => { Debug.Assert(state is Action); ((Action)state)(); @@ -490,7 +490,7 @@ internal sealed override void Run(Task ignored, bool canInlineContinuationTask) // Create the continuation task task. If we're allowed to inline, try to do so. // The target scheduler may still deny us from executing on this thread, in which case this'll be queued. - Task task = CreateTask(state => + Task task = CreateTask(static state => { try { @@ -664,7 +664,7 @@ void IThreadPoolWorkItem.Execute() } /// Cached delegate that invokes an Action passed as an object parameter. - private static readonly ContextCallback s_invokeContextCallback = (state) => + private static readonly ContextCallback s_invokeContextCallback = static (state) => { Debug.Assert(state is Action); ((Action)state)(); diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TaskScheduler.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TaskScheduler.cs index fce90d7289f372..e416fe36519957 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TaskScheduler.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/TaskScheduler.cs @@ -600,7 +600,7 @@ protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQu public override int MaximumConcurrencyLevel => 1; // preallocated SendOrPostCallback delegate - private static readonly SendOrPostCallback s_postCallback = s => + private static readonly SendOrPostCallback s_postCallback = static s => { Debug.Assert(s is Task); ((Task)s).ExecuteEntry(); // with double-execute check because SC could be buggy diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs index d7e806bdcedbd0..dd502abd95f21b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/ThreadPoolTaskScheduler.cs @@ -29,7 +29,7 @@ internal ThreadPoolTaskScheduler() } // static delegate for threads allocated to handle LongRunning tasks. - private static readonly ParameterizedThreadStart s_longRunningThreadWork = s => + private static readonly ParameterizedThreadStart s_longRunningThreadWork = static s => { Debug.Assert(s is Task); ((Task)s).ExecuteEntryUnsafe(threadPoolThread: null); diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/ValueTask.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/ValueTask.cs index fbfecd11b13888..7a04c041d653fa 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/ValueTask.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Tasks/ValueTask.cs @@ -231,7 +231,7 @@ private Task GetTaskForValueTaskSource(IValueTaskSource t) /// Type used to create a to represent a . private sealed class ValueTaskSourceAsTask : Task { - private static readonly Action s_completionAction = state => + private static readonly Action s_completionAction = static state => { if (!(state is ValueTaskSourceAsTask vtst) || !(vtst._source is IValueTaskSource source)) @@ -623,7 +623,7 @@ private Task GetTaskForValueTaskSource(IValueTaskSource t) /// Type used to create a to represent a . private sealed class ValueTaskSourceAsTask : Task { - private static readonly Action s_completionAction = state => + private static readonly Action s_completionAction = static state => { if (!(state is ValueTaskSourceAsTask vtst) || !(vtst._source is IValueTaskSource source)) diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.cs index 4ff85f148998e1..4bcf665b9a6ca3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.cs @@ -938,7 +938,7 @@ public static partial class ThreadPool internal static readonly ThreadPoolWorkQueue s_workQueue = new ThreadPoolWorkQueue(); /// Shim used to invoke of the supplied . - internal static readonly Action s_invokeAsyncStateMachineBox = state => + internal static readonly Action s_invokeAsyncStateMachineBox = static state => { if (!(state is IAsyncStateMachineBox box)) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Timer.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Timer.cs index 95c146de38b0cf..6486053794a5f5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Timer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Timer.cs @@ -639,7 +639,7 @@ internal void CallCallback(bool isThreadPool) } } - private static readonly ContextCallback s_callCallbackInContext = state => + private static readonly ContextCallback s_callCallbackInContext = static state => { Debug.Assert(state is TimerQueueTimer); var t = (TimerQueueTimer)state; diff --git a/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.cs b/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.cs index 9d43ddf5d5139c..b9b2d3831bb2c4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/TimeZoneInfo.cs @@ -796,7 +796,7 @@ public static ReadOnlyCollection GetSystemTimeZones() } // sort and copy the TimeZoneInfo's into a ReadOnlyCollection for the user - list.Sort((x, y) => + list.Sort(static (x, y) => { // sort by BaseUtcOffset first and by DisplayName second - this is similar to the Windows Date/Time control panel int comparison = x.BaseUtcOffset.CompareTo(y.BaseUtcOffset); diff --git a/src/libraries/System.Threading.Channels/src/System/Threading/Channels/AsyncOperation.cs b/src/libraries/System.Threading.Channels/src/System/Threading/Channels/AsyncOperation.cs index 2a2120327fc4cd..67106d328e80d6 100644 --- a/src/libraries/System.Threading.Channels/src/System/Threading/Channels/AsyncOperation.cs +++ b/src/libraries/System.Threading.Channels/src/System/Threading/Channels/AsyncOperation.cs @@ -89,7 +89,7 @@ public AsyncOperation(bool runContinuationsAsynchronously, CancellationToken can { Debug.Assert(!_pooled, "Cancelable operations can't be pooled"); CancellationToken = cancellationToken; - _registration = UnsafeRegister(cancellationToken, s => + _registration = UnsafeRegister(cancellationToken, static s => { var thisRef = (AsyncOperation)s!; thisRef.TrySetCanceled(thisRef.CancellationToken); @@ -273,7 +273,7 @@ public void OnCompleted(Action continuation, object? state, short token } else if (sc != null) { - sc.Post(s => + sc.Post(static s => { var t = (Tuple, object>)s!; t.Item1(t.Item2); @@ -395,7 +395,7 @@ private void SignalCompletion() // Otherwise fall through to invoke it synchronously. if (_runContinuationsAsynchronously || sc != SynchronizationContext.Current) { - sc.Post(s => ((AsyncOperation)s!).SetCompletionAndInvokeContinuation(), this); + sc.Post(static s => ((AsyncOperation)s!).SetCompletionAndInvokeContinuation(), this); return; } } @@ -408,7 +408,7 @@ private void SignalCompletion() Debug.Assert(ts != null, "Expected a TaskScheduler"); if (_runContinuationsAsynchronously || ts != TaskScheduler.Current) { - Task.Factory.StartNew(s => ((AsyncOperation)s!).SetCompletionAndInvokeContinuation(), this, + Task.Factory.StartNew(static s => ((AsyncOperation)s!).SetCompletionAndInvokeContinuation(), this, CancellationToken.None, TaskCreationOptions.DenyChildAttach, ts); return; } @@ -429,7 +429,7 @@ private void SetCompletionAndInvokeContinuation() } else { - ExecutionContext.Run(_executionContext, s => + ExecutionContext.Run(_executionContext, static s => { var thisRef = (AsyncOperation)s!; Action c = thisRef._continuation!; From 3f7202ba9f2f9a604816530f9d3154b0ee279a21 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Sat, 18 Jul 2020 05:45:18 -0700 Subject: [PATCH 014/458] Replace USE_INTERNAL_ACCESSIBILITY with SYSTEM_PRIVATE_CORELIB (#39588) Follow pattern used everywhere else --- src/libraries/Directory.Build.targets | 6 +----- .../Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs | 8 ++++---- .../Intrinsics/Arm/ArmBase.PlatformNotSupported.cs | 8 ++++---- .../src/System.Text.Encodings.Web.csproj | 1 - 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/libraries/Directory.Build.targets b/src/libraries/Directory.Build.targets index 15be91dbe1c68a..39a6e0ecaef582 100644 --- a/src/libraries/Directory.Build.targets +++ b/src/libraries/Directory.Build.targets @@ -222,10 +222,6 @@ - - $(DefineConstants),USE_INTERNAL_ACCESSIBILITY - - @@ -234,7 +230,7 @@ - + true true diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs index 748ba26f67d522..2fcc2efcfc9cad 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/AdvSimd.PlatformNotSupported.cs @@ -9,12 +9,12 @@ namespace System.Runtime.Intrinsics.Arm /// This class provides access to the ARM AdvSIMD hardware instructions via intrinsics /// [CLSCompliant(false)] -#if USE_INTERNAL_ACCESSIBILITY - internal -#else +#if SYSTEM_PRIVATE_CORELIB public +#else + internal #endif - abstract class AdvSimd : ArmBase + abstract class AdvSimd : ArmBase { internal AdvSimd() { } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/ArmBase.PlatformNotSupported.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/ArmBase.PlatformNotSupported.cs index ad356ade45adde..48bafcb0489f19 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/ArmBase.PlatformNotSupported.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/ArmBase.PlatformNotSupported.cs @@ -10,12 +10,12 @@ namespace System.Runtime.Intrinsics.Arm /// This class provides access to the ARM base hardware instructions via intrinsics /// [CLSCompliant(false)] -#if USE_INTERNAL_ACCESSIBILITY - internal -#else +#if SYSTEM_PRIVATE_CORELIB public +#else + internal #endif - abstract class ArmBase + abstract class ArmBase { internal ArmBase() { } diff --git a/src/libraries/System.Text.Encodings.Web/src/System.Text.Encodings.Web.csproj b/src/libraries/System.Text.Encodings.Web/src/System.Text.Encodings.Web.csproj index 126ef92db5b5b0..449759c379dd88 100644 --- a/src/libraries/System.Text.Encodings.Web/src/System.Text.Encodings.Web.csproj +++ b/src/libraries/System.Text.Encodings.Web/src/System.Text.Encodings.Web.csproj @@ -7,7 +7,6 @@ enable - $(DefineConstants),USE_INTERNAL_ACCESSIBILITY $(NoWarn);CS3019 From a9b0bebdbb3b7fc50f295bb26acaa39b045634ae Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Sat, 18 Jul 2020 13:54:41 +0100 Subject: [PATCH 015/458] Correct TryReadTo ref assembly parameter name (#39594) --- src/libraries/System.Memory/ref/System.Memory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Memory/ref/System.Memory.cs b/src/libraries/System.Memory/ref/System.Memory.cs index ec2eec1d2a4f11..fc29a53017de0e 100644 --- a/src/libraries/System.Memory/ref/System.Memory.cs +++ b/src/libraries/System.Memory/ref/System.Memory.cs @@ -283,7 +283,7 @@ public void Rewind(long count) { } public bool TryReadTo(out System.Buffers.ReadOnlySequence sequence, System.ReadOnlySpan delimiter, bool advancePastDelimiter = true) { throw null; } public bool TryReadTo(out System.Buffers.ReadOnlySequence sequence, T delimiter, bool advancePastDelimiter = true) { throw null; } public bool TryReadTo(out System.Buffers.ReadOnlySequence sequence, T delimiter, T delimiterEscape, bool advancePastDelimiter = true) { throw null; } - public bool TryReadTo(out System.ReadOnlySpan sequence, System.ReadOnlySpan delimiter, bool advancePastDelimiter = true) { throw null; } + public bool TryReadTo(out System.ReadOnlySpan span, System.ReadOnlySpan delimiter, bool advancePastDelimiter = true) { throw null; } public bool TryReadTo(out System.ReadOnlySpan span, T delimiter, bool advancePastDelimiter = true) { throw null; } public bool TryReadTo(out System.ReadOnlySpan span, T delimiter, T delimiterEscape, bool advancePastDelimiter = true) { throw null; } public bool TryReadToAny(out System.Buffers.ReadOnlySequence sequence, System.ReadOnlySpan delimiters, bool advancePastDelimiter = true) { throw null; } From 902645707215bcd0c22900d0a9ba4d01ca1a2fbe Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Sat, 18 Jul 2020 14:58:02 +0200 Subject: [PATCH 016/458] Remove SELECTANY usage (#39532) This change replaces SELECTANY by using constexpr. It results in major reduction of the native binaries size (3.2MB in the libcoreclr.so case) --- src/coreclr/src/debug/inc/amd64/primitives.h | 2 +- src/coreclr/src/debug/inc/arm/primitives.h | 2 +- src/coreclr/src/debug/inc/arm64/primitives.h | 2 +- src/coreclr/src/debug/inc/dbgipcevents.h | 2 +- src/coreclr/src/debug/inc/i386/primitives.h | 2 +- src/coreclr/src/dlls/mscorpe/stubs.h | 12 +++--- src/coreclr/src/inc/clr/fs/path.h | 1 - src/coreclr/src/inc/cor.h | 10 +---- src/coreclr/src/inc/corinfo.h | 10 +---- src/coreclr/src/inc/delayloadhelpers.h | 4 +- src/coreclr/src/inc/palclr.h | 20 ---------- src/coreclr/src/inc/simplerhash.h | 4 +- src/coreclr/src/inc/simplerhash.inl | 2 +- src/coreclr/src/inc/utilcode.h | 12 +++--- src/coreclr/src/jit/_typeinfo.h | 6 +-- src/coreclr/src/jit/jithashtable.h | 6 +-- src/coreclr/src/jit/target.h | 40 ++++++++++---------- src/coreclr/src/pal/inc/rt/guiddef.h | 2 +- src/coreclr/src/pal/inc/rt/palrt.h | 1 - src/coreclr/src/pal/inc/rt/rpc.h | 2 +- src/coreclr/src/scripts/genEtwProvider.py | 2 +- src/coreclr/src/scripts/genEventing.py | 6 +-- src/coreclr/src/vm/stdinterfaces.cpp | 2 +- 23 files changed, 57 insertions(+), 95 deletions(-) diff --git a/src/coreclr/src/debug/inc/amd64/primitives.h b/src/coreclr/src/debug/inc/amd64/primitives.h index d1e02238ece842..a119c2b3639fe3 100644 --- a/src/coreclr/src/debug/inc/amd64/primitives.h +++ b/src/coreclr/src/debug/inc/amd64/primitives.h @@ -53,7 +53,7 @@ inline CORDB_ADDRESS GetPatchEndAddr(CORDB_ADDRESS patchAddr) CORDbgInsertBreakpoint((CORDB_ADDRESS_TYPE *)((_buffer) + ((_patchAddr) - (_requestedAddr)))); -SELECTANY const CorDebugRegister g_JITToCorDbgReg[] = +constexpr CorDebugRegister g_JITToCorDbgReg[] = { REGISTER_AMD64_RAX, REGISTER_AMD64_RCX, diff --git a/src/coreclr/src/debug/inc/arm/primitives.h b/src/coreclr/src/debug/inc/arm/primitives.h index a360737b89734e..269281eb006bed 100644 --- a/src/coreclr/src/debug/inc/arm/primitives.h +++ b/src/coreclr/src/debug/inc/arm/primitives.h @@ -63,7 +63,7 @@ inline T _ClearThumbBit(T addr) CORDbgInsertBreakpointExImpl((CORDB_ADDRESS_TYPE *)((_buffer) + (_ClearThumbBit(_patchAddr) - (_requestedAddr)))); -SELECTANY const CorDebugRegister g_JITToCorDbgReg[] = +constexpr CorDebugRegister g_JITToCorDbgReg[] = { REGISTER_ARM_R0, REGISTER_ARM_R1, diff --git a/src/coreclr/src/debug/inc/arm64/primitives.h b/src/coreclr/src/debug/inc/arm64/primitives.h index b0ab65bac15e23..f359680370dfe5 100644 --- a/src/coreclr/src/debug/inc/arm64/primitives.h +++ b/src/coreclr/src/debug/inc/arm64/primitives.h @@ -56,7 +56,7 @@ inline CORDB_ADDRESS GetPatchEndAddr(CORDB_ADDRESS patchAddr) CORDbgInsertBreakpointExImpl((CORDB_ADDRESS_TYPE *)((_buffer) + (_patchAddr) - (_requestedAddr))); -SELECTANY const CorDebugRegister g_JITToCorDbgReg[] = +constexpr CorDebugRegister g_JITToCorDbgReg[] = { REGISTER_ARM64_X0, REGISTER_ARM64_X1, diff --git a/src/coreclr/src/debug/inc/dbgipcevents.h b/src/coreclr/src/debug/inc/dbgipcevents.h index 5c433c2bf6131a..eda4029c0fb1e5 100644 --- a/src/coreclr/src/debug/inc/dbgipcevents.h +++ b/src/coreclr/src/debug/inc/dbgipcevents.h @@ -984,7 +984,7 @@ struct MSLAYOUT IPCEventTypeNameMapping const char * eventName; }; -extern const IPCEventTypeNameMapping DECLSPEC_SELECTANY DbgIPCEventTypeNames[] = +constexpr IPCEventTypeNameMapping DbgIPCEventTypeNames[] = { #define IPC_EVENT_TYPE0(type, val) { type, #type }, #define IPC_EVENT_TYPE1(type, val) { type, #type }, diff --git a/src/coreclr/src/debug/inc/i386/primitives.h b/src/coreclr/src/debug/inc/i386/primitives.h index 05b696a4a0f692..980dc2707bb0f6 100644 --- a/src/coreclr/src/debug/inc/i386/primitives.h +++ b/src/coreclr/src/debug/inc/i386/primitives.h @@ -48,7 +48,7 @@ inline CORDB_ADDRESS GetPatchEndAddr(CORDB_ADDRESS patchAddr) CORDbgInsertBreakpoint((CORDB_ADDRESS_TYPE *)((_buffer) + ((_patchAddr) - (_requestedAddr)))); -SELECTANY const CorDebugRegister g_JITToCorDbgReg[] = +constexpr CorDebugRegister g_JITToCorDbgReg[] = { REGISTER_X86_EAX, REGISTER_X86_ECX, diff --git a/src/coreclr/src/dlls/mscorpe/stubs.h b/src/coreclr/src/dlls/mscorpe/stubs.h index 893fc4783a2758..f0e7ce380df33c 100644 --- a/src/coreclr/src/dlls/mscorpe/stubs.h +++ b/src/coreclr/src/dlls/mscorpe/stubs.h @@ -28,7 +28,7 @@ // fixed up by the loader when the image is paged in. //***************************************************************************** -SELECTANY const BYTE ExeMainX86Template[] = +constexpr BYTE ExeMainX86Template[] = { // Jump through IAT to _CorExeMain 0xFF, 0x25, // jmp [iat:_CorDllMain entry] @@ -51,7 +51,7 @@ SELECTANY const BYTE ExeMainX86Template[] = // fixed up by the loader when the image is paged in. //***************************************************************************** -SELECTANY const BYTE DllMainX86Template[] = +constexpr BYTE DllMainX86Template[] = { // Jump through IAT to CorDllMain 0xFF, 0x25, // jmp [iat:_CorDllMain entry] @@ -74,7 +74,7 @@ SELECTANY const BYTE DllMainX86Template[] = // fixed up by the loader when the image is paged in. //***************************************************************************** -SELECTANY const BYTE ExeMainAMD64Template[] = +constexpr BYTE ExeMainAMD64Template[] = { // Jump through IAT to _CorExeMain 0x48, 0xA1, // rex.w rex.b mov rax,[following address] @@ -98,7 +98,7 @@ SELECTANY const BYTE ExeMainAMD64Template[] = // fixed up by the loader when the image is paged in. //***************************************************************************** -SELECTANY const BYTE DllMainAMD64Template[] = +constexpr BYTE DllMainAMD64Template[] = { // Jump through IAT to CorDllMain 0x48, 0xA1, // rex.w rex.b mov rax,[following address] @@ -120,7 +120,7 @@ SELECTANY const BYTE DllMainAMD64Template[] = // We set the value of gp to point at the iat table entry for _CorExeMain //***************************************************************************** -SELECTANY const BYTE ExeMainIA64Template[] = +constexpr BYTE ExeMainIA64Template[] = { // ld8 r9 = [gp] ;; // ld8 r10 = [r9],8 @@ -148,7 +148,7 @@ SELECTANY const BYTE ExeMainIA64Template[] = // We set the value of gp to point at the iat table entry for _CorExeMain //***************************************************************************** -SELECTANY const BYTE DllMainIA64Template[] = +constexpr BYTE DllMainIA64Template[] = { // ld8 r9 = [gp] ;; // ld8 r10 = [r9],8 diff --git a/src/coreclr/src/inc/clr/fs/path.h b/src/coreclr/src/inc/clr/fs/path.h index 7f1d0e00d73823..efc21a5cdd4392 100644 --- a/src/coreclr/src/inc/clr/fs/path.h +++ b/src/coreclr/src/inc/clr/fs/path.h @@ -9,7 +9,6 @@ #define _clr_fs_Path_h_ #include "clrtypes.h" -#include "cor.h" // SELECTANY #include "strsafe.h" diff --git a/src/coreclr/src/inc/cor.h b/src/coreclr/src/inc/cor.h index 9625641288ca6b..8d2b6329460299 100644 --- a/src/coreclr/src/inc/cor.h +++ b/src/coreclr/src/inc/cor.h @@ -2093,15 +2093,7 @@ inline ULONG CorSigUncompressData( // return number of bytes of that compre } -#if !defined(SELECTANY) -#if defined(__GNUC__) - #define SELECTANY extern __attribute__((weak)) -#else - #define SELECTANY extern __declspec(selectany) -#endif -#endif - -SELECTANY const mdToken g_tkCorEncodeToken[4] ={mdtTypeDef, mdtTypeRef, mdtTypeSpec, mdtBaseType}; +constexpr mdToken g_tkCorEncodeToken[4] ={mdtTypeDef, mdtTypeRef, mdtTypeSpec, mdtBaseType}; // uncompress a token inline mdToken CorSigUncompressToken( // return the token. diff --git a/src/coreclr/src/inc/corinfo.h b/src/coreclr/src/inc/corinfo.h index f7f6d8ecf2ea4e..e93f59b0da417a 100644 --- a/src/coreclr/src/inc/corinfo.h +++ b/src/coreclr/src/inc/corinfo.h @@ -208,15 +208,7 @@ TODO: Talk about initializing strutures before use // ////////////////////////////////////////////////////////////////////////////////////////////////////////// -#if !defined(SELECTANY) -#if defined(__GNUC__) - #define SELECTANY extern __attribute__((weak)) -#else - #define SELECTANY extern __declspec(selectany) -#endif -#endif - -SELECTANY const GUID JITEEVersionIdentifier = { /* 7af97117-55be-4c76-afb2-e26261cb140e */ +constexpr GUID JITEEVersionIdentifier = { /* 7af97117-55be-4c76-afb2-e26261cb140e */ 0x7af97117, 0x55be, 0x4c76, diff --git a/src/coreclr/src/inc/delayloadhelpers.h b/src/coreclr/src/inc/delayloadhelpers.h index 740999926a28cd..160a9da3068002 100644 --- a/src/coreclr/src/inc/delayloadhelpers.h +++ b/src/coreclr/src/inc/delayloadhelpers.h @@ -49,7 +49,7 @@ namespace DelayLoad #define DELAY_LOADED_MODULE(DLL_NAME) \ namespace DelayLoad { \ namespace Modules { \ - SELECTANY Module DLL_NAME = { L#DLL_NAME W(".dll"), nullptr, S_OK, false }; \ + constexpr Module DLL_NAME = { L#DLL_NAME W(".dll"), nullptr, S_OK, false }; \ } \ } @@ -104,7 +104,7 @@ namespace DelayLoad DELAY_LOADED_MODULE(DLL_NAME) \ namespace DelayLoad { \ namespace DLL_NAME { \ - SELECTANY Function FUNC_NAME = { &Modules::##DLL_NAME, #FUNC_NAME, nullptr, S_OK, false }; \ + constexpr Function FUNC_NAME = { &Modules::##DLL_NAME, #FUNC_NAME, nullptr, S_OK, false }; \ } \ } diff --git a/src/coreclr/src/inc/palclr.h b/src/coreclr/src/inc/palclr.h index 40a68dd91384c1..2ab9c62c3e8446 100644 --- a/src/coreclr/src/inc/palclr.h +++ b/src/coreclr/src/inc/palclr.h @@ -485,26 +485,6 @@ #define PAL_CPP_CATCH_EXCEPTION_NOARG catch (Exception *) -// SELECTANY macro is intended to prevent duplication of static const -// arrays declared in .h files in binary modules. -// The problem is that const variables have static internal linkage -// in C++. That means that if a const variable is declared in a .h file -// the compiler will emit it into every translation unit that uses that .h file. -// That will cause duplication of the data when those translation units -// are linked into a binary module. -// SELECTANY declares a variable as extern to give it external linkage -// and it provides __declspec(selectany) to instruct the linker to merge -// duplicate external const static data copies into one. -// -#if defined(SOURCE_FORMATTING) -#define SELECTANY extern -#else -#if defined(__GNUC__) -#define SELECTANY extern __attribute__((weak)) -#else -#define SELECTANY extern __declspec(selectany) -#endif -#endif #if defined(SOURCE_FORMATTING) #define __annotation(x) #endif diff --git a/src/coreclr/src/inc/simplerhash.h b/src/coreclr/src/inc/simplerhash.h index ebd8a3e6871ee7..83c552eda19f74 100644 --- a/src/coreclr/src/inc/simplerhash.h +++ b/src/coreclr/src/inc/simplerhash.h @@ -68,8 +68,8 @@ class DefaultSimplerHashBehavior class PrimeInfo { public: - PrimeInfo() : prime(0), magic(0), shift(0) {} - PrimeInfo(unsigned p, unsigned m, unsigned s) : prime(p), magic(m), shift(s) {} + constexpr PrimeInfo() : prime(0), magic(0), shift(0) {} + constexpr PrimeInfo(unsigned p, unsigned m, unsigned s) : prime(p), magic(m), shift(s) {} unsigned prime; unsigned magic; unsigned shift; diff --git a/src/coreclr/src/inc/simplerhash.inl b/src/coreclr/src/inc/simplerhash.inl index 10a6b157ce99cd..309778e917914d 100644 --- a/src/coreclr/src/inc/simplerhash.inl +++ b/src/coreclr/src/inc/simplerhash.inl @@ -303,7 +303,7 @@ void SimplerHashTable::Reallocate(unsigned newTable // 32-bit magic numbers, (because the algorithm for using 33-bit magic numbers is slightly slower). // -SELECTANY const PrimeInfo primeInfo[] = +constexpr PrimeInfo primeInfo[] = { PrimeInfo(9, 0x38e38e39, 1), PrimeInfo(23, 0xb21642c9, 4), diff --git a/src/coreclr/src/inc/utilcode.h b/src/coreclr/src/inc/utilcode.h index f02e58aeaf7db0..f411acb7e66a22 100644 --- a/src/coreclr/src/inc/utilcode.h +++ b/src/coreclr/src/inc/utilcode.h @@ -4071,13 +4071,13 @@ HRESULT GetImageRuntimeVersionString(PVOID pMetaData, LPCSTR* pString); // The registry keys and values that contain the information regarding // the default registered unmanaged debugger. //***************************************************************************** -SELECTANY const WCHAR kDebugApplicationsPoliciesKey[] = W("SOFTWARE\\Policies\\Microsoft\\Windows\\Windows Error Reporting\\DebugApplications"); -SELECTANY const WCHAR kDebugApplicationsKey[] = W("SOFTWARE\\Microsoft\\Windows\\Windows Error Reporting\\DebugApplications"); +constexpr WCHAR kDebugApplicationsPoliciesKey[] = W("SOFTWARE\\Policies\\Microsoft\\Windows\\Windows Error Reporting\\DebugApplications"); +constexpr WCHAR kDebugApplicationsKey[] = W("SOFTWARE\\Microsoft\\Windows\\Windows Error Reporting\\DebugApplications"); -SELECTANY const WCHAR kUnmanagedDebuggerKey[] = W("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug"); -SELECTANY const WCHAR kUnmanagedDebuggerValue[] = W("Debugger"); -SELECTANY const WCHAR kUnmanagedDebuggerAutoValue[] = W("Auto"); -SELECTANY const WCHAR kUnmanagedDebuggerAutoExclusionListKey[] = W("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\AutoExclusionList"); +constexpr WCHAR kUnmanagedDebuggerKey[] = W("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug"); +constexpr WCHAR kUnmanagedDebuggerValue[] = W("Debugger"); +constexpr WCHAR kUnmanagedDebuggerAutoValue[] = W("Auto"); +constexpr WCHAR kUnmanagedDebuggerAutoExclusionListKey[] = W("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\AutoExclusionList"); BOOL GetRegistryLongValue(HKEY hKeyParent, // Parent key. LPCWSTR szKey, // Key name to look at. diff --git a/src/coreclr/src/jit/_typeinfo.h b/src/coreclr/src/jit/_typeinfo.h index 4aa38c540b220b..4bc90e50dbe65a 100644 --- a/src/coreclr/src/jit/_typeinfo.h +++ b/src/coreclr/src/jit/_typeinfo.h @@ -42,7 +42,7 @@ enum ti_types namespace { #endif // _MSC_VER -SELECTANY const char* g_ti_type_names_map[] = { +constexpr char* g_ti_type_names_map[] = { #define DEF_TI(ti, nm) nm, #include "titypes.h" #undef DEF_TI @@ -57,7 +57,7 @@ SELECTANY const char* g_ti_type_names_map[] = { namespace { #endif // _MSC_VER -SELECTANY const ti_types g_jit_types_map[] = { +constexpr ti_types g_jit_types_map[] = { #define DEF_TP(tn, nm, jitType, verType, sz, sze, asze, st, al, tf, howUsed) verType, #include "typelist.h" #undef DEF_TP @@ -92,7 +92,7 @@ inline ti_types varType2tiType(var_types type) namespace { #endif // _MSC_VER -SELECTANY const ti_types g_ti_types_map[CORINFO_TYPE_COUNT] = { +constexpr ti_types g_ti_types_map[CORINFO_TYPE_COUNT] = { // see the definition of enum CorInfoType in file inc/corinfo.h TI_ERROR, // CORINFO_TYPE_UNDEF = 0x0, TI_ERROR, // CORINFO_TYPE_VOID = 0x1, diff --git a/src/coreclr/src/jit/jithashtable.h b/src/coreclr/src/jit/jithashtable.h index 4d2d19d1389ff4..cb2cc1e60d20c3 100644 --- a/src/coreclr/src/jit/jithashtable.h +++ b/src/coreclr/src/jit/jithashtable.h @@ -57,10 +57,10 @@ class JitHashTableBehavior class JitPrimeInfo { public: - JitPrimeInfo() : prime(0), magic(0), shift(0) + constexpr JitPrimeInfo() : prime(0), magic(0), shift(0) { } - JitPrimeInfo(unsigned p, unsigned m, unsigned s) : prime(p), magic(m), shift(s) + constexpr JitPrimeInfo(unsigned p, unsigned m, unsigned s) : prime(p), magic(m), shift(s) { } unsigned prime; @@ -92,7 +92,7 @@ class JitPrimeInfo // 32-bit magic numbers, (because the algorithm for using 33-bit magic numbers is slightly slower). // clang-format off -SELECTANY const JitPrimeInfo jitPrimeInfo[] +constexpr JitPrimeInfo jitPrimeInfo[] { JitPrimeInfo(9, 0x38e38e39, 1), JitPrimeInfo(23, 0xb21642c9, 4), diff --git a/src/coreclr/src/jit/target.h b/src/coreclr/src/jit/target.h index c9fc28df7bb1c8..4e75434cd2426e 100644 --- a/src/coreclr/src/jit/target.h +++ b/src/coreclr/src/jit/target.h @@ -441,10 +441,10 @@ typedef unsigned char regNumberSmall; #define REG_ARG_0 REG_ECX #define REG_ARG_1 REG_EDX - SELECTANY const regNumber intArgRegs [] = {REG_ECX, REG_EDX}; - SELECTANY const regMaskTP intArgMasks[] = {RBM_ECX, RBM_EDX}; - SELECTANY const regNumber fltArgRegs [] = {REG_XMM0, REG_XMM1, REG_XMM2, REG_XMM3}; - SELECTANY const regMaskTP fltArgMasks[] = {RBM_XMM0, RBM_XMM1, RBM_XMM2, RBM_XMM3}; + constexpr regNumber intArgRegs [] = {REG_ECX, REG_EDX}; + constexpr regMaskTP intArgMasks[] = {RBM_ECX, RBM_EDX}; + constexpr regNumber fltArgRegs [] = {REG_XMM0, REG_XMM1, REG_XMM2, REG_XMM3}; + constexpr regMaskTP fltArgMasks[] = {RBM_XMM0, RBM_XMM1, RBM_XMM2, RBM_XMM3}; #define RBM_ARG_0 RBM_ECX #define RBM_ARG_1 RBM_EDX @@ -779,10 +779,10 @@ typedef unsigned char regNumberSmall; #define REG_ARG_4 REG_R8 #define REG_ARG_5 REG_R9 - SELECTANY const regNumber intArgRegs [] = { REG_EDI, REG_ESI, REG_EDX, REG_ECX, REG_R8, REG_R9 }; - SELECTANY const regMaskTP intArgMasks[] = { RBM_EDI, RBM_ESI, RBM_EDX, RBM_ECX, RBM_R8, RBM_R9 }; - SELECTANY const regNumber fltArgRegs [] = { REG_XMM0, REG_XMM1, REG_XMM2, REG_XMM3, REG_XMM4, REG_XMM5, REG_XMM6, REG_XMM7 }; - SELECTANY const regMaskTP fltArgMasks[] = { RBM_XMM0, RBM_XMM1, RBM_XMM2, RBM_XMM3, RBM_XMM4, RBM_XMM5, RBM_XMM6, RBM_XMM7 }; + constexpr regNumber intArgRegs [] = { REG_EDI, REG_ESI, REG_EDX, REG_ECX, REG_R8, REG_R9 }; + constexpr regMaskTP intArgMasks[] = { RBM_EDI, RBM_ESI, RBM_EDX, RBM_ECX, RBM_R8, RBM_R9 }; + constexpr regNumber fltArgRegs [] = { REG_XMM0, REG_XMM1, REG_XMM2, REG_XMM3, REG_XMM4, REG_XMM5, REG_XMM6, REG_XMM7 }; + constexpr regMaskTP fltArgMasks[] = { RBM_XMM0, RBM_XMM1, RBM_XMM2, RBM_XMM3, RBM_XMM4, RBM_XMM5, RBM_XMM6, RBM_XMM7 }; #define RBM_ARG_0 RBM_RDI #define RBM_ARG_1 RBM_RSI @@ -802,10 +802,10 @@ typedef unsigned char regNumberSmall; #define REG_ARG_2 REG_R8 #define REG_ARG_3 REG_R9 - SELECTANY const regNumber intArgRegs [] = { REG_ECX, REG_EDX, REG_R8, REG_R9 }; - SELECTANY const regMaskTP intArgMasks[] = { RBM_ECX, RBM_EDX, RBM_R8, RBM_R9 }; - SELECTANY const regNumber fltArgRegs [] = { REG_XMM0, REG_XMM1, REG_XMM2, REG_XMM3 }; - SELECTANY const regMaskTP fltArgMasks[] = { RBM_XMM0, RBM_XMM1, RBM_XMM2, RBM_XMM3 }; + constexpr regNumber intArgRegs [] = { REG_ECX, REG_EDX, REG_R8, REG_R9 }; + constexpr regMaskTP intArgMasks[] = { RBM_ECX, RBM_EDX, RBM_R8, RBM_R9 }; + constexpr regNumber fltArgRegs [] = { REG_XMM0, REG_XMM1, REG_XMM2, REG_XMM3 }; + constexpr regMaskTP fltArgMasks[] = { RBM_XMM0, RBM_XMM1, RBM_XMM2, RBM_XMM3 }; #define RBM_ARG_0 RBM_ECX #define RBM_ARG_1 RBM_EDX @@ -1150,8 +1150,8 @@ typedef unsigned char regNumberSmall; #define REG_ARG_2 REG_R2 #define REG_ARG_3 REG_R3 - SELECTANY const regNumber intArgRegs [] = {REG_R0, REG_R1, REG_R2, REG_R3}; - SELECTANY const regMaskTP intArgMasks[] = {RBM_R0, RBM_R1, RBM_R2, RBM_R3}; + constexpr regNumber intArgRegs [] = {REG_R0, REG_R1, REG_R2, REG_R3}; + constexpr regMaskTP intArgMasks[] = {RBM_R0, RBM_R1, RBM_R2, RBM_R3}; #define RBM_ARG_0 RBM_R0 #define RBM_ARG_1 RBM_R1 @@ -1162,8 +1162,8 @@ typedef unsigned char regNumberSmall; #define RBM_FLTARG_REGS (RBM_F0|RBM_F1|RBM_F2|RBM_F3|RBM_F4|RBM_F5|RBM_F6|RBM_F7|RBM_F8|RBM_F9|RBM_F10|RBM_F11|RBM_F12|RBM_F13|RBM_F14|RBM_F15) #define RBM_DBL_REGS RBM_ALLDOUBLE - SELECTANY const regNumber fltArgRegs [] = {REG_F0, REG_F1, REG_F2, REG_F3, REG_F4, REG_F5, REG_F6, REG_F7, REG_F8, REG_F9, REG_F10, REG_F11, REG_F12, REG_F13, REG_F14, REG_F15 }; - SELECTANY const regMaskTP fltArgMasks[] = {RBM_F0, RBM_F1, RBM_F2, RBM_F3, RBM_F4, RBM_F5, RBM_F6, RBM_F7, RBM_F8, RBM_F9, RBM_F10, RBM_F11, RBM_F12, RBM_F13, RBM_F14, RBM_F15 }; + constexpr regNumber fltArgRegs [] = {REG_F0, REG_F1, REG_F2, REG_F3, REG_F4, REG_F5, REG_F6, REG_F7, REG_F8, REG_F9, REG_F10, REG_F11, REG_F12, REG_F13, REG_F14, REG_F15 }; + constexpr regMaskTP fltArgMasks[] = {RBM_F0, RBM_F1, RBM_F2, RBM_F3, RBM_F4, RBM_F5, RBM_F6, RBM_F7, RBM_F8, RBM_F9, RBM_F10, RBM_F11, RBM_F12, RBM_F13, RBM_F14, RBM_F15 }; #define LBL_DIST_SMALL_MAX_NEG (0) #define LBL_DIST_SMALL_MAX_POS (+1020) @@ -1484,8 +1484,8 @@ typedef unsigned char regNumberSmall; #define REG_ARG_6 REG_R6 #define REG_ARG_7 REG_R7 - SELECTANY const regNumber intArgRegs [] = {REG_R0, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7}; - SELECTANY const regMaskTP intArgMasks[] = {RBM_R0, RBM_R1, RBM_R2, RBM_R3, RBM_R4, RBM_R5, RBM_R6, RBM_R7}; + constexpr regNumber intArgRegs [] = {REG_R0, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7}; + constexpr regMaskTP intArgMasks[] = {RBM_R0, RBM_R1, RBM_R2, RBM_R3, RBM_R4, RBM_R5, RBM_R6, RBM_R7}; #define RBM_ARG_0 RBM_R0 #define RBM_ARG_1 RBM_R1 @@ -1517,8 +1517,8 @@ typedef unsigned char regNumberSmall; #define RBM_ARG_REGS (RBM_ARG_0|RBM_ARG_1|RBM_ARG_2|RBM_ARG_3|RBM_ARG_4|RBM_ARG_5|RBM_ARG_6|RBM_ARG_7) #define RBM_FLTARG_REGS (RBM_FLTARG_0|RBM_FLTARG_1|RBM_FLTARG_2|RBM_FLTARG_3|RBM_FLTARG_4|RBM_FLTARG_5|RBM_FLTARG_6|RBM_FLTARG_7) - SELECTANY const regNumber fltArgRegs [] = {REG_V0, REG_V1, REG_V2, REG_V3, REG_V4, REG_V5, REG_V6, REG_V7 }; - SELECTANY const regMaskTP fltArgMasks[] = {RBM_V0, RBM_V1, RBM_V2, RBM_V3, RBM_V4, RBM_V5, RBM_V6, RBM_V7 }; + constexpr regNumber fltArgRegs [] = {REG_V0, REG_V1, REG_V2, REG_V3, REG_V4, REG_V5, REG_V6, REG_V7 }; + constexpr regMaskTP fltArgMasks[] = {RBM_V0, RBM_V1, RBM_V2, RBM_V3, RBM_V4, RBM_V5, RBM_V6, RBM_V7 }; #define LBL_DIST_SMALL_MAX_NEG (-1048576) #define LBL_DIST_SMALL_MAX_POS (+1048575) diff --git a/src/coreclr/src/pal/inc/rt/guiddef.h b/src/coreclr/src/pal/inc/rt/guiddef.h index 1a2ed05e16fefa..6650f11092fa24 100644 --- a/src/coreclr/src/pal/inc/rt/guiddef.h +++ b/src/coreclr/src/pal/inc/rt/guiddef.h @@ -17,7 +17,7 @@ #ifdef INITGUID #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - EXTERN_C DLLEXPORT const GUID DECLSPEC_SELECTANY name \ + EXTERN_C DLLEXPORT constexpr GUID name \ = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } #else #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ diff --git a/src/coreclr/src/pal/inc/rt/palrt.h b/src/coreclr/src/pal/inc/rt/palrt.h index 23f627e1b8e5c6..b021277e437581 100644 --- a/src/coreclr/src/pal/inc/rt/palrt.h +++ b/src/coreclr/src/pal/inc/rt/palrt.h @@ -223,7 +223,6 @@ inline void *__cdecl operator new(size_t, void *_P) #define THIS void #define DECLSPEC_NOVTABLE -#define DECLSPEC_SELECTANY __attribute__((weak)) #define DECLARE_INTERFACE(iface) interface DECLSPEC_NOVTABLE iface #define DECLARE_INTERFACE_(iface, baseiface) interface DECLSPEC_NOVTABLE iface : public baseiface diff --git a/src/coreclr/src/pal/inc/rt/rpc.h b/src/coreclr/src/pal/inc/rt/rpc.h index 9b9f425f69fe52..9fd3c096882d61 100644 --- a/src/coreclr/src/pal/inc/rt/rpc.h +++ b/src/coreclr/src/pal/inc/rt/rpc.h @@ -25,7 +25,7 @@ #define MIDL_INTERFACE(x) struct DECLSPEC_UUID(x) DECLSPEC_NOVTABLE #define EXTERN_GUID(itf,l1,s1,s2,c1,c2,c3,c4,c5,c6,c7,c8) \ - EXTERN_C const IID DECLSPEC_SELECTANY itf = {l1,s1,s2,{c1,c2,c3,c4,c5,c6,c7,c8}} + constexpr IID itf = {l1,s1,s2,{c1,c2,c3,c4,c5,c6,c7,c8}} interface IRpcStubBuffer; interface IRpcChannelBuffer; diff --git a/src/coreclr/src/scripts/genEtwProvider.py b/src/coreclr/src/scripts/genEtwProvider.py index 1a146b5fda36ff..e7df63bb5b38ff 100644 --- a/src/coreclr/src/scripts/genEtwProvider.py +++ b/src/coreclr/src/scripts/genEtwProvider.py @@ -164,7 +164,7 @@ def genEtwMacroHeader(manifest, exclusion_filename, intermediate): header_file.write("#define NO_OF_ETW_PROVIDERS " + str(numOfProviders) + "\n") header_file.write("#define MAX_BYTES_PER_ETW_PROVIDER " + str(nMaxEventBytesPerProvider) + "\n") - header_file.write("EXTERN_C SELECTANY const BYTE etwStackSupportedEvents[NO_OF_ETW_PROVIDERS][MAX_BYTES_PER_ETW_PROVIDER] = \n{\n") + header_file.write("EXTERN_C constexpr BYTE etwStackSupportedEvents[NO_OF_ETW_PROVIDERS][MAX_BYTES_PER_ETW_PROVIDER] = \n{\n") for providerNode in tree.getElementsByTagName('provider'): stackSupportedEvents = [0]*nMaxEventBytesPerProvider diff --git a/src/coreclr/src/scripts/genEventing.py b/src/coreclr/src/scripts/genEventing.py index c591be8dc0640a..a7919768c3abc1 100644 --- a/src/coreclr/src/scripts/genEventing.py +++ b/src/coreclr/src/scripts/genEventing.py @@ -627,7 +627,7 @@ def generatePlatformIndependentFiles(sClrEtwAllMan, incDir, etmDummyFile, extern if is_windows: eventpipeProviderCtxName = providerSymbol + "_EVENTPIPE_Context" - Clrallevents.write('SELECTANY EVENTPIPE_TRACE_CONTEXT const ' + eventpipeProviderCtxName + ' = { W("' + providerName + '"), 0, false, 0 };\n') + Clrallevents.write('constexpr EVENTPIPE_TRACE_CONTEXT ' + eventpipeProviderCtxName + ' = { W("' + providerName + '"), 0, false, 0 };\n') if write_xplatheader: clrproviders = os.path.join(incDir, "clrproviders.h") @@ -676,14 +676,14 @@ def generatePlatformIndependentFiles(sClrEtwAllMan, incDir, etmDummyFile, extern symbolName = eventNode.getAttribute('symbol') keywords = eventNode.getAttribute('keywords') level = convertToLevelId(levelName) - Clrproviders.write("SELECTANY EVENT_DESCRIPTOR const " + symbolName + " = { " + str(level) + ", " + hex(getKeywordsMaskCombined(keywords, keywordsToMask)) + " };\n") + Clrproviders.write("constexpr EVENT_DESCRIPTOR " + symbolName + " = { " + str(level) + ", " + hex(getKeywordsMaskCombined(keywords, keywordsToMask)) + " };\n") allProviders.append("&" + providerSymbol + "_LTTNG_Context") # define and initialize runtime providers' DOTNET_TRACE_CONTEXT depending on the platform if not is_windows: Clrproviders.write('#define NB_PROVIDERS ' + str(nbProviders) + '\n') - Clrproviders.write('SELECTANY LTTNG_TRACE_CONTEXT * const ALL_LTTNG_PROVIDERS_CONTEXT[NB_PROVIDERS] = { ') + Clrproviders.write('constexpr LTTNG_TRACE_CONTEXT * ALL_LTTNG_PROVIDERS_CONTEXT[NB_PROVIDERS] = { ') Clrproviders.write(', '.join(allProviders)) Clrproviders.write(' };\n') diff --git a/src/coreclr/src/vm/stdinterfaces.cpp b/src/coreclr/src/vm/stdinterfaces.cpp index d01a98efd80c16..c573f3041f1330 100644 --- a/src/coreclr/src/vm/stdinterfaces.cpp +++ b/src/coreclr/src/vm/stdinterfaces.cpp @@ -56,7 +56,7 @@ static const GUID LIBID_STDOLE2 = { 0x00020430, 0x0000, 0x0000, { 0xc0, 0x00, 0x // Until the Windows SDK is updated, just hard-code the IAgileObject IID #ifndef __IAgileObject_INTERFACE_DEFINED__ -EXTERN_C SELECTANY const GUID IID_IAgileObject = { 0x94ea2b94, 0xe9cc, 0x49e0, { 0xc0, 0xff, 0xee, 0x64, 0xca, 0x8f, 0x5b, 0x90 } }; +EXTERN_C constexpr GUID IID_IAgileObject = { 0x94ea2b94, 0xe9cc, 0x49e0, { 0xc0, 0xff, 0xee, 0x64, 0xca, 0x8f, 0x5b, 0x90 } }; #endif // !__IAgileObject_INTERFACE_DEFINED__ // Until the Windows SDK is updated, just hard-code the INoMarshal IID From 0f4d1d842575809aeddf13e73662ced6e926ef62 Mon Sep 17 00:00:00 2001 From: "Huang, Zhaoquan" Date: Sat, 18 Jul 2020 21:35:48 +0800 Subject: [PATCH 017/458] Make Comments In SortedList Match Code Bahaviour (#39595) The method "EnsureCapacity" does not check whether resizing is necessary, thus the comments should not contain the conditional clause. Fix #39526 --- .../src/System/Collections/Generic/SortedList.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Collections/src/System/Collections/Generic/SortedList.cs b/src/libraries/System.Collections/src/System/Collections/Generic/SortedList.cs index 57192e1a30d149..1ce3cd9cd19e37 100644 --- a/src/libraries/System.Collections/src/System/Collections/Generic/SortedList.cs +++ b/src/libraries/System.Collections/src/System/Collections/Generic/SortedList.cs @@ -526,9 +526,8 @@ void ICollection.CopyTo(Array array, int index) private const int MaxArrayLength = 0X7FEFFFFF; // Ensures that the capacity of this sorted list is at least the given - // minimum value. If the current capacity of the list is less than - // min, the capacity is increased to twice the current capacity or - // to min, whichever is larger. + // minimum value. The capacity is increased to twice the current capacity + // or to min, whichever is larger. private void EnsureCapacity(int min) { int newCapacity = keys.Length == 0 ? DefaultCapacity : keys.Length * 2; From 1d08d98a4140b5ee56df744c284decefd1efffaf Mon Sep 17 00:00:00 2001 From: Matt Kotsenas Date: Sat, 18 Jul 2020 06:43:57 -0700 Subject: [PATCH 018/458] Remove unused locals in System.Management (#39570) --- .../Management/InteropClasses/WMIInterop.cs | 52 ------------------- .../src/System/Management/ManagementObject.cs | 2 - .../src/System/Management/ManagementScope.cs | 5 +- .../src/System/Management/WMIGenerator.cs | 8 +-- 4 files changed, 2 insertions(+), 65 deletions(-) diff --git a/src/libraries/System.Management/src/System/Management/InteropClasses/WMIInterop.cs b/src/libraries/System.Management/src/System/Management/InteropClasses/WMIInterop.cs index 8ba6b71bed8bbf..b2de37af52c1a2 100644 --- a/src/libraries/System.Management/src/System/Management/InteropClasses/WMIInterop.cs +++ b/src/libraries/System.Management/src/System/Management/InteropClasses/WMIInterop.cs @@ -74,58 +74,6 @@ private void Dispose_(bool finalization) Dispose_(true); } - private void DeserializeFromBlob(byte[] rg) - { - IntPtr hGlobal = IntPtr.Zero; - System.Runtime.InteropServices.ComTypes.IStream stream = null; - try - { - // If something goes wrong, we want to make sure the object is invalidated - pWbemClassObject = IntPtr.Zero; - - hGlobal = Marshal.AllocHGlobal(rg.Length); - Marshal.Copy(rg, 0, hGlobal, rg.Length); - stream = Interop.Ole32.CreateStreamOnHGlobal(hGlobal, false); - pWbemClassObject = Interop.Ole32.CoUnmarshalInterface(stream, IID_IWbemClassObject); - } - finally - { - if (stream != null) - Marshal.ReleaseComObject(stream); - if (hGlobal != IntPtr.Zero) - Marshal.FreeHGlobal(hGlobal); - } - } - - private byte[] SerializeToBlob() - { - byte[] rg = null; - System.Runtime.InteropServices.ComTypes.IStream stream = null; - IntPtr pData = IntPtr.Zero; - try - { - // Stream will own the HGlobal - stream = Interop.Ole32.CreateStreamOnHGlobal(IntPtr.Zero, true); - - Interop.Ole32.CoMarshalInterface(stream, IID_IWbemClassObject, pWbemClassObject, (uint)MSHCTX.MSHCTX_DIFFERENTMACHINE, IntPtr.Zero, (uint)MSHLFLAGS.MSHLFLAGS_TABLEWEAK); - - System.Runtime.InteropServices.ComTypes.STATSTG statstg; - stream.Stat(out statstg, (int)STATFLAG.STATFLAG_DEFAULT); - rg = new byte[statstg.cbSize]; - pData = Interop.Kernel32.GlobalLock(Interop.Ole32.GetHGlobalFromStream(stream)); - Marshal.Copy(pData, rg, 0, (int)statstg.cbSize); - } - finally - { - if (pData != IntPtr.Zero) - Interop.Kernel32.GlobalUnlock(pData); - if (stream != null) - Marshal.ReleaseComObject(stream); - } - GC.KeepAlive(this); - return rg; - } - // Interface methods public int GetQualifierSet_(out IWbemQualifierSetFreeThreaded ppQualSet) { diff --git a/src/libraries/System.Management/src/System/Management/ManagementObject.cs b/src/libraries/System.Management/src/System/Management/ManagementObject.cs index 9bf0b10a974e35..bd551dcee66c96 100644 --- a/src/libraries/System.Management/src/System/Management/ManagementObject.cs +++ b/src/libraries/System.Management/src/System/Management/ManagementObject.cs @@ -2304,8 +2304,6 @@ public ManagementBaseObject InvokeMethod( { Initialize(false); InvokeMethodOptions o = (null != options) ? options : new InvokeMethodOptions(); - IWbemServices wbemServices = scope.GetIWbemServices(); - SecurityHandler securityHandler = null; int status = (int)ManagementStatus.NoError; diff --git a/src/libraries/System.Management/src/System/Management/ManagementScope.cs b/src/libraries/System.Management/src/System/Management/ManagementScope.cs index aa6201a195ab0e..95f18ca6b06609 100644 --- a/src/libraries/System.Management/src/System/Management/ManagementScope.cs +++ b/src/libraries/System.Management/src/System/Management/ManagementScope.cs @@ -969,8 +969,6 @@ internal void Initialize() private void InitializeGuts(object o) { ManagementScope threadParam = (ManagementScope)o; - IWbemLocator loc = (IWbemLocator)new WbemLocator(); - IntPtr punk = IntPtr.Zero; if (null == threadParam.options) { @@ -986,8 +984,7 @@ private void InitializeGuts(object o) // path here as we do NOT want to trigger an // IdentifierChanged event as a result of this set - bool bUnused; - nsPath = threadParam.prvpath.SetNamespacePath(ManagementPath.DefaultPath.Path, out bUnused); + nsPath = threadParam.prvpath.SetNamespacePath(ManagementPath.DefaultPath.Path, out _); } int status = (int)ManagementStatus.NoError; diff --git a/src/libraries/System.Management/src/System/Management/WMIGenerator.cs b/src/libraries/System.Management/src/System/Management/WMIGenerator.cs index 38453159239d80..56a515ca09cb90 100644 --- a/src/libraries/System.Management/src/System/Management/WMIGenerator.cs +++ b/src/libraries/System.Management/src/System/Management/WMIGenerator.cs @@ -3036,7 +3036,7 @@ private void GenerateMethods() { CodeTypeReference dateType = cmm.ReturnType; // Check if it is Time interval and if so change the type to Time Interval - bool isRetTypeTimeInterval = GetDateTimeType(prop, ref dateType); + GetDateTimeType(prop, ref dateType); cmm.ReturnType = dateType; } retRefType = cmm.ReturnType; @@ -6116,7 +6116,6 @@ private void AddCommentsForEmbeddedProperties() private bool GetDateTimeType(PropertyData prop, ref CodeTypeReference codeType) { bool isTimeInterval = false; - codeType = null; if (prop.IsArray) { codeType = new CodeTypeReference("System.DateTime", 1); @@ -7339,11 +7338,6 @@ private void ToDMTFDateHelper(string dateTimeMember, CodeMemberMethod cmmdt, str cmie2.Parameters.Add(new CodePrimitiveExpression(2)); cmie2.Parameters.Add(new CodePrimitiveExpression('0')); - CodeMethodInvokeExpression cmie3 = GenerateConcatStrings(cmie, cmie2); - /* new CodeMethodInvokeExpression(); - cmie3.Method = new CodeMethodReferenceExpression(cmie,"Concat"); - cmie3.Parameters.Add(cmie2); */ - cmmdt.Statements.Add(new CodeAssignStatement(new CodeVariableReferenceExpression(dmtfDateTime), GenerateConcatStrings(new CodeVariableReferenceExpression(dmtfDateTime), cmie2))); From bb27de135eb7afedd3093ecbbcb1bdf51ac07be3 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Sat, 18 Jul 2020 07:01:47 -0700 Subject: [PATCH 019/458] Fix il verification tests (#39538) * Revert "delete test project. (#39501)" This reverts commit ecb231cb3d962d332d00344358b0559043d29f88. * Fix ILVerification tests - Re-enable the test project build - Change string resources in type system to directly use ResourceManager instead of SR abstraction which is unavaliable in the test build tree - Add test to verify that all ExceptionStringID values have associated strings - Use ToolsCommonPath property to successfully reference the correct resource file * Address feedback and allow the strings to be handled with a runtime implementation --- .../Common/TypeSystemException.Resources.cs | 24 +++++++++ .../TypeSystem/Common/TypeSystemException.cs | 50 +++---------------- .../ILVerification/ILVerification.projitems | 14 +++--- .../ExceptionStringTests.cs | 26 ++++++++++ ...ompiler.TypeSystem.ReadyToRun.Tests.csproj | 1 + .../ILCompiler.TypeSystem.ReadyToRun.csproj | 6 ++- .../ilverify/ILVerification.Tests.csproj | 31 ++++++++++++ src/tests/ilverify/TestDataLoader.cs | 4 +- 8 files changed, 104 insertions(+), 52 deletions(-) create mode 100644 src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemException.Resources.cs create mode 100644 src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ExceptionStringTests.cs create mode 100644 src/tests/ilverify/ILVerification.Tests.csproj diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemException.Resources.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemException.Resources.cs new file mode 100644 index 00000000000000..bf5a3b97b292f4 --- /dev/null +++ b/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemException.Resources.cs @@ -0,0 +1,24 @@ +// 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.Globalization; +using System.Resources; +using System.Reflection; + +// This partial file is designed to allow the runtime variant of the type system to not +// need to support accessing these strings via the ResourceManager +namespace Internal.TypeSystem +{ + partial class TypeSystemException : Exception + { + private static Lazy s_stringResourceManager = + new Lazy(() => new ResourceManager("Internal.TypeSystem.Strings", typeof(TypeSystemException).GetTypeInfo().Assembly)); + + public static string GetFormatString(ExceptionStringID id) + { + return s_stringResourceManager.Value.GetString(id.ToString(), CultureInfo.InvariantCulture); + } + } +} diff --git a/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemException.cs b/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemException.cs index c9a71236c4daf0..931136950f1afc 100644 --- a/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemException.cs +++ b/src/coreclr/src/tools/Common/TypeSystem/Common/TypeSystemException.cs @@ -9,7 +9,7 @@ namespace Internal.TypeSystem /// /// Base type for all type system exceptions. /// - public abstract class TypeSystemException : Exception + public abstract partial class TypeSystemException : Exception { private string[] _arguments; @@ -43,53 +43,19 @@ internal TypeSystemException(ExceptionStringID id, params string[] args) _arguments = args; } - private static string GetFormatString(ExceptionStringID id) - { - switch (id) - { - case ExceptionStringID.ClassLoadGeneral: return SR.ClassLoadGeneral; - case ExceptionStringID.ClassLoadBadFormat: return SR.ClassLoadBadFormat; - case ExceptionStringID.ClassLoadExplicitGeneric: return SR.ClassLoadExplicitGeneric; - case ExceptionStringID.ClassLoadExplicitLayout: return SR.ClassLoadExplicitLayout; - case ExceptionStringID.ClassLoadValueClassTooLarge: return SR.ClassLoadValueClassTooLarge; - case ExceptionStringID.ClassLoadRankTooLarge: return SR.ClassLoadRankTooLarge; - case ExceptionStringID.MissingMethod: return SR.MissingMethod; - case ExceptionStringID.MissingField: return SR.MissingField; - case ExceptionStringID.InvalidProgramDefault: return SR.InvalidProgramDefault; - case ExceptionStringID.InvalidProgramSpecific: return SR.InvalidProgramSpecific; - case ExceptionStringID.InvalidProgramVararg: return SR.InvalidProgramVararg; - case ExceptionStringID.InvalidProgramCallVirtFinalize: return SR.InvalidProgramCallVirtFinalize; - case ExceptionStringID.InvalidProgramUnmanagedCallersOnly: return SR.InvalidProgramUnmanagedCallersOnly; - case ExceptionStringID.InvalidProgramCallAbstractMethod: return SR.InvalidProgramCallAbstractMethod; - case ExceptionStringID.InvalidProgramCallVirtStatic: return SR.InvalidProgramCallVirtStatic; - case ExceptionStringID.InvalidProgramNonStaticMethod: return SR.InvalidProgramNonStaticMethod; - case ExceptionStringID.InvalidProgramGenericMethod: return SR.InvalidProgramGenericMethod; - case ExceptionStringID.InvalidProgramNonBlittableTypes: return SR.InvalidProgramNonBlittableTypes; - case ExceptionStringID.BadImageFormatGeneric: return SR.BadImageFormatGeneric; - case ExceptionStringID.FileLoadErrorGeneric: return SR.FileLoadErrorGeneric; - } -#if !DEBUG - throw new Exception($"Unknown Exception string id {id}"); -#else - return null; -#endif - } - private static string GetExceptionString(ExceptionStringID id, string[] args) { string formatString = GetFormatString(id); -#if !DEBUG try { -#endif - return String.Format(formatString, (object[])args); -#if !DEBUG - } - catch - { - return "[TEMPORARY EXCEPTION MESSAGE] " + id.ToString() + ": " + String.Join(", ", args); + if (formatString != null) + { + return String.Format(formatString, (object[])args); + } } -#endif + catch {} + + return "[TEMPORARY EXCEPTION MESSAGE] " + id.ToString() + ": " + String.Join(", ", args); } /// diff --git a/src/coreclr/src/tools/ILVerification/ILVerification.projitems b/src/coreclr/src/tools/ILVerification/ILVerification.projitems index bc5bda42bc03cf..42f60611ee1813 100644 --- a/src/coreclr/src/tools/ILVerification/ILVerification.projitems +++ b/src/coreclr/src/tools/ILVerification/ILVerification.projitems @@ -13,18 +13,17 @@ + + $(MSBuildThisFileDirectory)..\Common\ + ILVerification.Strings.resources - - true - Internal.TypeSystem.SR + + Internal.TypeSystem.Strings.resources - - $(MSBuildThisFileDirectory)..\Common\ - TypeSystem\CodeGen\MethodDesc.CodeGen.cs @@ -53,6 +52,9 @@ TypeSystem\Common\TypeSystemException.cs + + TypeSystem\Common\TypeSystemException.Resources.cs + Utilities\CustomAttributeTypeNameParser.cs diff --git a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ExceptionStringTests.cs b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ExceptionStringTests.cs new file mode 100644 index 00000000000000..d40bdf774126d8 --- /dev/null +++ b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ExceptionStringTests.cs @@ -0,0 +1,26 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using Internal.TypeSystem; + +using Xunit; + +namespace TypeSystemTests +{ + public class ExceptionStringTests + { + public ExceptionStringTests() + { + } + + [Fact] + public void TestAllExceptionIdsHaveMessages() + { + foreach(var exceptionId in (ExceptionStringID[])Enum.GetValues(typeof(ExceptionStringID))) + { + Assert.NotNull(TypeSystemException.GetFormatString(exceptionId)); + } + } + } +} \ No newline at end of file diff --git a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ILCompiler.TypeSystem.ReadyToRun.Tests.csproj b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ILCompiler.TypeSystem.ReadyToRun.Tests.csproj index 38e1dda8abaaf4..c65d2b0b54dd55 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ILCompiler.TypeSystem.ReadyToRun.Tests.csproj +++ b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ILCompiler.TypeSystem.ReadyToRun.Tests.csproj @@ -56,5 +56,6 @@ + diff --git a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun/ILCompiler.TypeSystem.ReadyToRun.csproj b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun/ILCompiler.TypeSystem.ReadyToRun.csproj index 733bd833c140a7..cea2c969468d42 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun/ILCompiler.TypeSystem.ReadyToRun.csproj +++ b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun/ILCompiler.TypeSystem.ReadyToRun.csproj @@ -19,8 +19,7 @@ - true - Internal.TypeSystem.SR + Internal.TypeSystem.Strings.resources @@ -153,6 +152,9 @@ TypeSystem\Common\TypeSystemException.cs + + TypeSystem\Common\TypeSystemException.Resources.cs + TypeSystem\Common\ThrowHelper.cs diff --git a/src/tests/ilverify/ILVerification.Tests.csproj b/src/tests/ilverify/ILVerification.Tests.csproj new file mode 100644 index 00000000000000..5eaea1b89ea441 --- /dev/null +++ b/src/tests/ilverify/ILVerification.Tests.csproj @@ -0,0 +1,31 @@ + + + Exe + $(BaseOutputPathWithConfig)ilverify\ + 1 + + true + true + + + + + + + + + + + + + + + + + + + false + Content + + + diff --git a/src/tests/ilverify/TestDataLoader.cs b/src/tests/ilverify/TestDataLoader.cs index 7678981dd4a9a9..cd8709d9626ab6 100644 --- a/src/tests/ilverify/TestDataLoader.cs +++ b/src/tests/ilverify/TestDataLoader.cs @@ -27,7 +27,7 @@ class TestDataLoader /// /// The folder with the test binaries /// - private const string TestAssemblyPath = @"Tests\"; + private const string TestAssemblyPath = @"Tests"; private const string SpecialTestPrefix = "special."; @@ -236,7 +236,7 @@ public static EcmaModule GetModuleForTestAssembly(string assemblyName) foreach (var fileName in GetAllTestDlls()) { - simpleNameToPathMap.Add(Path.GetFileNameWithoutExtension(fileName), TestAssemblyPath + fileName); + simpleNameToPathMap.Add(Path.GetFileNameWithoutExtension(fileName), Path.Combine(TestAssemblyPath, fileName)); } Assembly coreAssembly = typeof(object).GetTypeInfo().Assembly; From 6af0d0e09a3b00a3a79033f7d26670b2563405fa Mon Sep 17 00:00:00 2001 From: Levi Broderick Date: Sat, 18 Jul 2020 10:02:55 -0700 Subject: [PATCH 020/458] Fix resx test name mangling logic (#39569) --- .../tests/TestData.cs | 47 ++++++++++++++++-- .../tests/TestData.resources | Bin 8184 -> 8828 bytes 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Resources.Extensions/tests/TestData.cs b/src/libraries/System.Resources.Extensions/tests/TestData.cs index a422862db46e2e..e71619c276a673 100644 --- a/src/libraries/System.Resources.Extensions/tests/TestData.cs +++ b/src/libraries/System.Resources.Extensions/tests/TestData.cs @@ -303,11 +303,8 @@ public override void BindToName(Type serializedType, out string assemblyName, ou // workaround for https://github.com/dotnet/runtime/issues/31289 assemblyQualifiedTypeName = assemblyQualifiedTypeName.Replace(s_coreAssemblyName, s_mscorlibAssemblyName); - int pos = assemblyQualifiedTypeName.IndexOf(','); - if (pos > 0 && pos < assemblyQualifiedTypeName.Length - 1) + if (TryDeconstructFullyQualifiedTypeName(assemblyQualifiedTypeName, out string newTypeName, out assemblyName)) { - assemblyName = assemblyQualifiedTypeName.Substring(pos + 1).TrimStart(); - string newTypeName = assemblyQualifiedTypeName.Substring(0, pos); if (!string.Equals(newTypeName, serializedType.FullName, StringComparison.InvariantCulture)) { typeName = newTypeName; @@ -322,6 +319,48 @@ public override Type BindToType(string assemblyName, string typeName) // We should never be using this binder during Deserialization throw new NotSupportedException($"{nameof(TypeNameManglingSerializationBinder)}.{nameof(BindToType)} should not be used during testing."); } + + private static bool TryDeconstructFullyQualifiedTypeName(string assemblyQualifiedTypeName, out string typeName, out string assemblyName) + { + // Skip over all generic arguments in the assembly-qualified type name. + + int genericDepth = 0; + int i; + for (i = 0; i < assemblyQualifiedTypeName.Length; i++) + { + switch (assemblyQualifiedTypeName[i]) + { + case '[': + checked { genericDepth++; } + break; + + case ']': + checked { genericDepth--; } + break; + + case ',' when genericDepth == 0: + goto AfterLoop; + + default: + continue; + } + } + + AfterLoop: + + if (i < assemblyQualifiedTypeName.Length - 1) + { + // Found a proper fully-qualified type name with assembly! + typeName = assemblyQualifiedTypeName.Substring(0, i); + assemblyName = assemblyQualifiedTypeName.Substring(i + 1).Trim(); + return true; + } + + // Couldn't find an assembly after the type name. + typeName = default; + assemblyName = default; + return false; + } } } } diff --git a/src/libraries/System.Resources.Extensions/tests/TestData.resources b/src/libraries/System.Resources.Extensions/tests/TestData.resources index b2f4b4cd1928883e15073f7033e78217b6800728..6b7552d4314159f50e0e8ea3d37fa6c28967c223 100644 GIT binary patch delta 875 zcmcIiO=}ZT6us{?c}?ccSDZ=n)nt;5T185VxN#vt5$eL?%7tP`+p$X1R3;fqr4+js zMSAz*Pf!brJJD5Fx)c?pSQG`tg$pH>c;7S?5f_5Ec#n6_Irq-FhxvMB>)4%^=A0G) z`ZUZ#2$RqRAD&BG(JGk@31IusB76? gHK2Z;~03g4sSD=n9r)&aEh)HDwb=)jzg zLV8X>s8He#EYLGcPqby4FX=cT3w%Y#rX0xy20%h}wqORPOn`j9z(&I1O%tEU{X8`B zvpm4Bn&|0iag9{vOL)%k_&y8I=!HY;7Qj$Io~P(zb!gKaL_TNW8BtoBY%db%!)q#s z`z6*B>B7b~e}NnXqy(J*qreRm8`}l9e-&<%Kx%d~-l<<^M;#~_*8lw)| zMOpspV$j8#M#VB+S~iTFbs+8HBcqtg6Q+excq#(V#ZQLk>?KqWX_FmeRTs-(Tg5jX2E#xFOTq0g9zQ$vh^s-V9EL|J%T^R!v>mNraqQ+sVm0 NJ;2As{2%alKLC5j&?^7{ delta 1021 zcmc&xO=uHQ5T5sv-DdxqY?s(1yUixvib!k^r57p1>ZwtC@lrLUx~*bNOMa9}rHD5# zwhnku@FX4rLN%axQ#=cL^arH~(u+k8LcxO0Y$Aw=mmXYrv-5r5%)FU-+Y?)3YgOH` z6ae!y%tI4qpaKC*Xm~}>_ZKyQL;zLd&qIl{v*aJs@QI$6sNp+3ZNH=teU_5up$rXp zt)Xi8&U<224sO6la#Q4D!br*u4UZVE{H$Tc7)*cC0b-n4g*o_O0A#uV%P~i882H@S zBflE>#n>yi4fM^V+G7Ib7VxCy%X=nHo9@U#3t(4`dOk&$m7q?x7WO#@lO*YNYI~8$ z0Hz6gU5KSv(mm19&rk<7PVVR-=uH`!bKx-^AayU&Pf!v9tUFu4f8()XO=1VYqkR6Q6hl um%TxET Date: Sat, 18 Jul 2020 19:07:43 +0200 Subject: [PATCH 021/458] Annotate and adjust more of CoreLib for trimming (#38865) * Annotate and adjust more of CoreLib for trimming * Update CustomAttribute.cs * Update TypeBuilder.Mono.cs --- .../System/Reflection/SignatureTypeExtensions.cs | 4 ++++ .../src/System/Reflection/TypeInfo.cs | 14 ++++++++++++-- .../src/System/Resources/ResourceManager.cs | 4 +++- .../src/System/Resources/ResourceSet.cs | 6 ++++-- .../src/System/Reflection/CustomAttribute.cs | 4 ++++ .../src/System/Reflection/Emit/TypeBuilder.Mono.cs | 4 ++++ .../Reflection/Emit/TypeBuilderInstantiation.cs | 2 ++ 7 files changed, 33 insertions(+), 5 deletions(-) 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 f79b42ea5fd05e..06b391696060e8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/SignatureTypeExtensions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/SignatureTypeExtensions.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; + namespace System.Reflection { #if CORERT @@ -108,6 +110,8 @@ internal static bool MatchesExactly(this SignatureType pattern, Type actual) return signatureType.TryResolve(genericMethod.GetGenericArguments()); } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2006:UnrecognizedReflectionPattern", + Justification = "Used to find matching method overloads. Only used for assignability checks.")] private static Type? TryResolve(this SignatureType signatureType, Type[] genericMethodParameters) { if (signatureType.IsSZArray) diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/TypeInfo.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/TypeInfo.cs index 5786aa4d9d02cc..3487f2aab00c4c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/TypeInfo.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/TypeInfo.cs @@ -33,11 +33,16 @@ protected TypeInfo() { } [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] public virtual IEnumerable GetDeclaredMethods(string name) { - foreach (MethodInfo method in GetMethods(TypeInfo.DeclaredOnlyLookup)) + foreach (MethodInfo method in GetDeclaredOnlyMethods(this)) { if (method.Name == name) yield return method; } + + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2006:UnrecognizedReflectionPattern", + Justification = "The yield return state machine doesn't propagate annotations")] + static MethodInfo[] GetDeclaredOnlyMethods( + Type type) => type.GetMethods(TypeInfo.DeclaredOnlyLookup); } public virtual IEnumerable DeclaredConstructors @@ -75,10 +80,15 @@ public virtual IEnumerable DeclaredNestedTypes [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] get { - foreach (Type t in GetNestedTypes(TypeInfo.DeclaredOnlyLookup)) + foreach (Type t in GetDeclaredOnlyNestedTypes(this)) { yield return t.GetTypeInfo(); } + + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2006:UnrecognizedReflectionPattern", + Justification = "The yield return state machine doesn't propagate annotations")] + static Type[] GetDeclaredOnlyNestedTypes( + Type type) => type.GetNestedTypes(TypeInfo.DeclaredOnlyLookup); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceManager.cs b/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceManager.cs index 2334103d055ff5..16c585d4fe6345 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceManager.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceManager.cs @@ -306,7 +306,9 @@ public virtual void ReleaseAllResources() } } - public static ResourceManager CreateFileBasedResourceManager(string baseName, string resourceDir, Type? usingResourceSet) + public static ResourceManager CreateFileBasedResourceManager(string baseName, string resourceDir, + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + Type? usingResourceSet) { return new ResourceManager(baseName, resourceDir, usingResourceSet); } diff --git a/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceSet.cs b/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceSet.cs index 0a42533351b55e..dbb3342b94f09d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceSet.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Resources/ResourceSet.cs @@ -14,6 +14,7 @@ using System.Collections; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Reflection; @@ -114,10 +115,11 @@ public virtual Type GetDefaultReader() // Returns the preferred IResourceWriter class for this kind of ResourceSet. // Subclasses of ResourceSet using their own Readers &; should override // GetDefaultReader and GetDefaultWriter. + // TODO: https://github.com/mono/linker/issues/943 + [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, "System.Resources.ResourceWriter", "System.Resources.Writer")] public virtual Type GetDefaultWriter() { - Assembly resourceWriterAssembly = Assembly.Load("System.Resources.Writer, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"); - return resourceWriterAssembly.GetType("System.Resources.ResourceWriter", throwOnError: true)!; + return Type.GetType("System.Resources.ResourceWriter, System.Resources.Writer", throwOnError: true)!; } public virtual IDictionaryEnumerator GetEnumerator() diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs index 3c9d4ccb82b433..b8af9e8f172c19 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs @@ -593,6 +593,8 @@ internal static bool IsDefined(ICustomAttributeProvider obj, Type attributeType, [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern bool IsDefinedInternal(ICustomAttributeProvider obj, Type AttributeType); + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2006:UnrecognizedReflectionPattern", + Justification = "Linker analyzes base properties and marks them")] private static PropertyInfo? GetBasePropertyDefinition(RuntimePropertyInfo property) { MethodInfo? method = property.GetGetMethod(true); @@ -622,6 +624,8 @@ internal static bool IsDefined(ICustomAttributeProvider obj, Type attributeType, } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2006:UnrecognizedReflectionPattern", + Justification = "Linker analyzes base events and marks them")] private static EventInfo? GetBaseEventDefinition(RuntimeEventInfo evt) { MethodInfo? method = evt.GetAddMethod(true); diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.Mono.cs index 35731ec326543b..197a76f40e34d9 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.Mono.cs @@ -794,6 +794,8 @@ private bool has_ctor_method() // We require emitted types to have all members on their bases to be accessible. // This is basically an identity function for `this`. + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2006:UnrecognizedReflectionPattern", + Justification = "Reflection emitted types have all of their members")] [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public TypeInfo? CreateTypeInfo() @@ -1821,6 +1823,8 @@ public GenericTypeParameterBuilder[] DefineGenericParameters(params string[] nam return generic_params; } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2006:UnrecognizedReflectionPattern", + Justification = "Linker thinks Type.GetConstructor(ConstructorInfo) is one of the public APIs because it doesn't analyze method signatures. We already have ConstructorInfo.")] public static ConstructorInfo GetConstructor(Type type, ConstructorInfo constructor) { /*FIXME I would expect the same checks of GetMethod here*/ diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs index 167347af4e3000..88204f50ada936 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs @@ -122,6 +122,8 @@ internal bool IsCreated return InflateType(type, type_arguments, method_args); } + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2006:UnrecognizedReflectionPattern", + Justification = "Reflection emitted types have all of their members")] internal static Type? InflateType(Type? type, Type[]? type_args, Type[]? method_args) { if (type == null) From b613cbe051234c4e55e32d0dcd198fb3e7974567 Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Sun, 19 Jul 2020 00:40:04 +0300 Subject: [PATCH 022/458] [wasm] Trim down size of dotnet.wasm (#39549) * [interp] Use constant for concurrent collection in progress Saves 4k on wasm. * [sgen] Use constant for concurrent sweep Saves 0.5k on wasm * [sgen] Remove code from threadpool when not using concurrent mode Saves 2.5k on wasm * [sgen] Avoid keeping some callbacks alive Saves 0.5k on wasm * [sgen] Avoid registering callback if not used * [sgen] Add option to remove binary protocol from build Saves 5k on wasm * [sgen] Add option to disable togglerefs Saves 1k on wasm * [sgen] We never need to wait for sweep if serial Saves 0.5k on wasm * [sgen] Disable also canaries if debug helpers are disabled Saves 1k on wasm * [sgen] Disable also pinning_stats if debug features are disabled Saves 2k on wasm * [sgen] Disable also gchandle stats if debug is disabled Saves 1k on wasm * [sgen] Disable also sgen logging if debugging is disabled Saves 6k on wasm * [runtime] Disable log messages if assert messages is disabled This is mainly beneficial do to very common calls of g_error. Saves 35k on wasm --- src/mono/configure.ac | 14 +++-- src/mono/mono.proj | 2 +- src/mono/mono/eglib/glib.h | 9 ++++ src/mono/mono/eglib/goutput.c | 6 +++ src/mono/mono/metadata/sgen-toggleref.c | 15 ++++++ src/mono/mono/sgen/sgen-client.h | 7 +++ src/mono/mono/sgen/sgen-conf.h | 5 ++ src/mono/mono/sgen/sgen-gc.c | 17 +++++++ src/mono/mono/sgen/sgen-gc.h | 27 ++++++++++ src/mono/mono/sgen/sgen-gchandles.c | 2 + src/mono/mono/sgen/sgen-marksweep.c | 17 +++++++ src/mono/mono/sgen/sgen-pinning-stats.c | 4 ++ src/mono/mono/sgen/sgen-pinning.h | 7 +++ src/mono/mono/sgen/sgen-protocol.c | 4 ++ src/mono/mono/sgen/sgen-protocol.h | 68 +++++++++++++++++++++++++ src/mono/mono/sgen/sgen-thread-pool.c | 68 +++++++++++++++++++++++++ src/mono/mono/sgen/sgen-workers.c | 10 ---- src/mono/mono/sgen/sgen-workers.h | 8 +++ 18 files changed, 276 insertions(+), 14 deletions(-) diff --git a/src/mono/configure.ac b/src/mono/configure.ac index 1b95d75f132394..18f807f842b96f 100644 --- a/src/mono/configure.ac +++ b/src/mono/configure.ac @@ -1783,9 +1783,7 @@ fi AM_CONDITIONAL(ENABLE_STATIC_GCC_LIBS, test "x$enable_static_gcc_libs" = "xyes") AC_ARG_ENABLE(minimal, [ --enable-minimal=LIST drop support for LIST subsystems. - LIST is a comma-separated list from: aot, profiler, decimal, pinvoke, debug, appdomains, verifier, dllmap, - reflection_emit, reflection_emit_save, large_code, logging, com, ssa, generics, attach, jit, interpreter, simd, soft_debug, perfcounters, normalization, desktop_loader, shared_perfcounters, remoting, - security, lldb, mdb, assert_messages, config, cfgdir_config, cleanup, sgen_marksweep_conc, sgen_split_nursery, sgen_gc_bridge, sgen_debug_helpers, sockets, gac, threads, processes, eventpipe.], + LIST is a comma-separated list from: aot, profiler, decimal, pinvoke, debug, appdomains, verifier, dllmap, reflection_emit, reflection_emit_save, large_code, logging, com, ssa, generics, attach, jit, interpreter, simd, soft_debug, perfcounters, normalization, desktop_loader, shared_perfcounters, remoting, security, lldb, mdb, assert_messages, config, cfgdir_config, cleanup, sgen_marksweep_conc, sgen_split_nursery, sgen_gc_bridge, sgen_toggleref, sgen_debug_helpers, sgen_binary_protocol, sockets, gac, threads, processes, eventpipe.], [ for feature in `echo "$enable_minimal" | sed -e "s/,/ /g"`; do eval "mono_feature_disable_$feature='yes'" @@ -1991,11 +1989,21 @@ if test "x$mono_feature_disable_sgen_gc_bridge" = "xyes"; then AC_MSG_NOTICE([Disabled gc bridge support in SGEN.]) fi +if test "x$mono_feature_disable_sgen_toggleref" = "xyes"; then + AC_DEFINE(DISABLE_SGEN_TOGGLEREF, 1, [Disable toggleref support in SGEN.]) + AC_MSG_NOTICE([Disabled toggleref support in SGEN.]) +fi + if test "x$mono_feature_disable_sgen_debug_helpers" = "xyes"; then AC_DEFINE(DISABLE_SGEN_DEBUG_HELPERS, 1, [Disable debug helpers in SGEN.]) AC_MSG_NOTICE([Disabled debug helpers in SGEN.]) fi +if test "x$mono_feature_disable_sgen_binary_protocol" = "xyes"; then + AC_DEFINE(DISABLE_SGEN_BINARY_PROTOCOL, 1, [Disable binary protocol logging in SGEN.]) + AC_MSG_NOTICE([Disabled binary protocol logging in SGEN.]) +fi + if test "x$mono_feature_disable_sockets" = "xyes"; then AC_DEFINE(DISABLE_SOCKETS, 1, [Disable sockets]) AC_MSG_NOTICE([Disabled sockets]) diff --git a/src/mono/mono.proj b/src/mono/mono.proj index 08c5c1e70c5a4a..a11853b47c527b 100644 --- a/src/mono/mono.proj +++ b/src/mono/mono.proj @@ -644,7 +644,7 @@ <_MonoConfigureParams Include="--disable-crash-reporting"/> <_MonoConfigureParams Include="--with-bitcode=yes"/> <_MonoConfigureParams Include="--with-static-icu=yes"/> - <_MonoConfigureParams Include="--enable-minimal=ssa,com,jit,reflection_emit_save,portability,assembly_remapping,attach,verifier,full_messages,appdomains,shadowcopy,security,sgen_marksweep_conc,sgen_split_nursery,sgen_gc_bridge,logging,remoting,shared_perfcounters,sgen_debug_helpers,soft_debug,interpreter,assert_messages,cleanup,mdb,gac,threads,eventpipe,$(_MonoEnableMinimal)"/> + <_MonoConfigureParams Include="--enable-minimal=ssa,com,jit,reflection_emit_save,portability,assembly_remapping,attach,verifier,full_messages,appdomains,shadowcopy,security,sgen_marksweep_conc,sgen_split_nursery,sgen_gc_bridge,sgen_toggleref,logging,remoting,shared_perfcounters,sgen_debug_helpers,sgen_binary_protocol,soft_debug,interpreter,assert_messages,cleanup,mdb,gac,threads,eventpipe,$(_MonoEnableMinimal)"/> <_MonoCFLAGS Include="-fexceptions" /> <_MonoCFLAGS Include="-I$(PkgMicrosoft_NETCore_Runtime_ICU_Transport)/runtimes/browser-wasm/native/include" /> <_MonoCXXFLAGS Include="-fexceptions" /> diff --git a/src/mono/mono/eglib/glib.h b/src/mono/mono/eglib/glib.h index a056e958989866..4272679aeb1331 100644 --- a/src/mono/mono/eglib/glib.h +++ b/src/mono/mono/eglib/glib.h @@ -779,6 +779,7 @@ GLogLevelFlags g_log_set_fatal_mask (const gchar *log_domain, GLogLevelFlags f void g_logv (const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, va_list args); G_EXTERN_C // Used by MonoPosixHelper or MonoSupportW, at least. void g_log (const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, ...); +void g_log_disabled (const gchar *log_domain, GLogLevelFlags log_level, const char *file, int line); G_EXTERN_C // Used by MonoPosixHelper or MonoSupportW, at least. void g_assertion_message (const gchar *format, ...) G_GNUC_NORETURN; void mono_assertion_message_disabled (const char *file, int line) G_GNUC_NORETURN; @@ -786,6 +787,7 @@ void mono_assertion_message (const char *file, int line, const char * void mono_assertion_message_unreachable (const char *file, int line) G_GNUC_NORETURN; const char * g_get_assertion_message (void); +#ifndef DISABLE_ASSERT_MESSAGES #ifdef HAVE_C99_SUPPORT /* The for (;;) tells gc thats g_error () doesn't return, avoiding warnings */ #define g_error(format, ...) do { g_log (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, format, __VA_ARGS__); for (;;); } while (0) @@ -800,6 +802,13 @@ const char * g_get_assertion_message (void); #define g_message(...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, __VA_ARGS__) #define g_debug(...) g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, __VA_ARGS__) #endif /* ndef HAVE_C99_SUPPORT */ +#else +#define g_error(...) do { g_log_disabled (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, __FILE__, __LINE__); for (;;); } while (0) +#define g_critical(...) g_log_disabled (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, __FILE__, __LINE__) +#define g_warning(...) g_log_disabled (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, __FILE__, __LINE__) +#define g_message(...) g_log_disabled (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, __FILE__, __LINE__) +#define g_debug(...) g_log_disabled (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, __FILE__, __LINE__) +#endif typedef void (*GLogFunc) (const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data); typedef void (*GPrintFunc) (const gchar *string); diff --git a/src/mono/mono/eglib/goutput.c b/src/mono/mono/eglib/goutput.c index f9da72dfe57de8..b54b1e0d8b5bd6 100644 --- a/src/mono/mono/eglib/goutput.c +++ b/src/mono/mono/eglib/goutput.c @@ -183,6 +183,12 @@ g_log (const gchar *log_domain, GLogLevelFlags log_level, const gchar *format, . va_end (args); } +void +g_log_disabled (const gchar *log_domain, GLogLevelFlags log_level, const char *file, int line) +{ + g_log (log_domain, log_level, "%s:%d ", file, line); +} + static char *failure_assertion = NULL; const char * diff --git a/src/mono/mono/metadata/sgen-toggleref.c b/src/mono/mono/metadata/sgen-toggleref.c index 831d0aaccfc19e..9a5d98e29339db 100644 --- a/src/mono/mono/metadata/sgen-toggleref.c +++ b/src/mono/mono/metadata/sgen-toggleref.c @@ -19,6 +19,7 @@ #include "sgen-toggleref.h" #include "sgen/sgen-client.h" +#ifndef DISABLE_SGEN_TOGGLEREF /*only one of the two can be non null at a given time*/ typedef struct { @@ -234,4 +235,18 @@ sgen_register_test_toggleref_callback (void) toggleref_callback = test_toggleref_callback; } +#else + +void +mono_gc_toggleref_register_callback (MonoToggleRefStatus (*proccess_toggleref) (MonoObject *obj)) +{ +} + +void +mono_gc_toggleref_add (MonoObject *object, mono_bool strong_ref) +{ +} + +#endif + #endif diff --git a/src/mono/mono/sgen/sgen-client.h b/src/mono/mono/sgen/sgen-client.h index 53a1a43f45de1d..7eb78f75fad5dd 100644 --- a/src/mono/mono/sgen/sgen-client.h +++ b/src/mono/mono/sgen/sgen-client.h @@ -207,12 +207,19 @@ void sgen_client_bridge_processing_finish (int generation); gboolean sgen_client_bridge_is_bridge_object (GCObject *obj); void sgen_client_bridge_register_finalized_object (GCObject *object); +#ifndef DISABLE_SGEN_TOGGLEREF /* * No action is necessary. */ void sgen_client_mark_togglerefs (char *start, char *end, ScanCopyContext ctx); void sgen_client_clear_togglerefs (char *start, char *end, ScanCopyContext ctx); void sgen_foreach_toggleref_root (void (*callback)(MonoObject*, gpointer), gpointer data); +#else +static inline void sgen_client_mark_togglerefs (char *start, char *end, ScanCopyContext ctx) { } +static inline void sgen_client_clear_togglerefs (char *start, char *end, ScanCopyContext ctx) { } +static inline void sgen_foreach_toggleref_root (void (*callback)(MonoObject*, gpointer), gpointer data) { } +#endif + /* * Called to handle `MONO_GC_PARAMS` and `MONO_GC_DEBUG` options. The `handle` functions diff --git a/src/mono/mono/sgen/sgen-conf.h b/src/mono/mono/sgen/sgen-conf.h index a955a46ab53eb5..fc6ee088dbf5ed 100644 --- a/src/mono/mono/sgen/sgen-conf.h +++ b/src/mono/mono/sgen/sgen-conf.h @@ -130,7 +130,12 @@ typedef target_mword SgenDescriptor; * Making this a constant enables us to put logging in a lot of places and * not pay its cost on release builds. */ +#ifndef DISABLE_SGEN_DEBUG_HELPERS #define SGEN_MAX_DEBUG_LEVEL 2 +#else +/* No logging support */ +#define SGEN_MAX_DEBUG_LEVEL (-1) +#endif /* * Maximum level of asserts to enable on this build. diff --git a/src/mono/mono/sgen/sgen-gc.c b/src/mono/mono/sgen/sgen-gc.c index d1330d0d502c68..e6719fae05854d 100644 --- a/src/mono/mono/sgen/sgen-gc.c +++ b/src/mono/mono/sgen/sgen-gc.c @@ -235,7 +235,12 @@ static gboolean disable_minor_collections = FALSE; static gboolean disable_major_collections = FALSE; static gboolean do_verify_nursery = FALSE; static gboolean do_dump_nursery_content = FALSE; + +#ifndef DISABLE_SGEN_DEBUG_HELPERS static gboolean enable_nursery_canaries = FALSE; +#else +static const gboolean enable_nursery_canaries = FALSE; +#endif static gboolean precleaning_enabled = TRUE; static gboolean dynamic_nursery = FALSE; @@ -378,7 +383,9 @@ static volatile mword highest_heap_address = 0; MonoCoopMutex sgen_interruption_mutex; int sgen_current_collection_generation = -1; +#ifndef DISABLE_SGEN_MAJOR_MARKSWEEP_CONC volatile gboolean sgen_concurrent_collection_in_progress = FALSE; +#endif /* objects that are ready to be finalized */ static SgenPointerQueue fin_ready_queue = SGEN_POINTER_QUEUE_INIT (INTERNAL_MEM_FINALIZE_READY); @@ -1359,6 +1366,7 @@ sgen_set_pinned_from_failed_allocation (mword objsize) bytes_pinned_from_failed_allocation += objsize; } +#ifndef DISABLE_SGEN_MAJOR_MARKSWEEP_CONC gboolean sgen_collection_is_concurrent (void) { @@ -1378,6 +1386,7 @@ sgen_get_concurrent_collection_in_progress (void) { return sgen_concurrent_collection_in_progress; } +#endif typedef struct { SgenThreadPoolJob job; @@ -2176,10 +2185,12 @@ major_start_collection (SgenGrayQueue *gc_thread_gray_queue, const char *reason, { SgenObjectOperations *object_ops_nopar, *object_ops_par = NULL; +#ifndef DISABLE_SGEN_MAJOR_MARKSWEEP_CONC if (concurrent) { g_assert (sgen_major_collector.is_concurrent); sgen_concurrent_collection_in_progress = TRUE; } +#endif sgen_binary_protocol_collection_begin (mono_atomic_load_i32 (&mono_gc_stats.major_gc_count), GENERATION_OLD); @@ -2366,8 +2377,10 @@ major_finish_collection (SgenGrayQueue *gc_thread_gray_queue, const char *reason sgen_binary_protocol_collection_end (mono_atomic_load_i32 (&mono_gc_stats.major_gc_count) - 1, GENERATION_OLD, counts.num_scanned_objects, counts.num_unique_scanned_objects); +#ifndef DISABLE_SGEN_MAJOR_MARKSWEEP_CONC if (sgen_concurrent_collection_in_progress) sgen_concurrent_collection_in_progress = FALSE; +#endif } static gboolean @@ -3729,7 +3742,11 @@ sgen_gc_init (void) sgen_binary_protocol_init (filename, (gint64)limit); } else if (!strcmp (opt, "nursery-canaries")) { do_verify_nursery = TRUE; +#ifndef DISABLE_SGEN_DEBUG_HELPERS enable_nursery_canaries = TRUE; +#else + g_error ("Sgen was built with canaries disabled"); +#endif /* If aot code is used, allocation from there won't expect the layout with canaries enabled */ sgen_set_use_managed_allocator (FALSE); } else if (!sgen_client_handle_gc_debug (opt)) { diff --git a/src/mono/mono/sgen/sgen-gc.h b/src/mono/mono/sgen/sgen-gc.h index 2478a0be511b13..900ed5b1f809a8 100644 --- a/src/mono/mono/sgen/sgen-gc.h +++ b/src/mono/mono/sgen/sgen-gc.h @@ -476,20 +476,37 @@ void sgen_free_internal (void *addr, int type); void* sgen_alloc_internal_dynamic (size_t size, int type, gboolean assert_on_failure); void sgen_free_internal_dynamic (void *addr, size_t size, int type); +#ifndef DISABLE_SGEN_DEBUG_HELPERS void sgen_pin_stats_enable (void); void sgen_pin_stats_register_object (GCObject *obj, int generation); void sgen_pin_stats_register_global_remset (GCObject *obj); void sgen_pin_stats_report (void); +#else +static inline void sgen_pin_stats_enable (void) { } +static inline void sgen_pin_stats_register_object (GCObject *obj, int generation) { } +static inline void sgen_pin_stats_register_global_remset (GCObject *obj) { } +static inline void sgen_pin_stats_report (void) { } +#endif +#ifndef DISABLE_SGEN_DEBUG_HELPERS void sgen_gchandle_stats_enable (void); void sgen_gchandle_stats_report (void); +#else +static inline void sgen_gchandle_stats_enable (void) { } +static inline void sgen_gchandle_stats_report (void) { } +#endif void sgen_sort_addresses (void **array, size_t size); void sgen_add_to_global_remset (gpointer ptr, GCObject *obj); int sgen_get_current_collection_generation (void); +#ifndef DISABLE_SGEN_MAJOR_MARKSWEEP_CONC gboolean sgen_collection_is_concurrent (void); gboolean sgen_get_concurrent_collection_in_progress (void); +#else +#define sgen_collection_is_concurrent() FALSE +#define sgen_get_concurrent_collection_in_progress() FALSE +#endif void sgen_set_bytes_allocated_attached (guint64 bytes); void sgen_increment_bytes_allocated_detached (guint64 bytes); @@ -837,8 +854,14 @@ void sgen_register_obj_with_weak_fields (GCObject *obj); void sgen_mark_togglerefs (char *start, char *end, ScanCopyContext ctx); void sgen_clear_togglerefs (char *start, char *end, ScanCopyContext ctx); +#ifndef DISABLE_SGEN_TOGGLEREF void sgen_process_togglerefs (void); void sgen_register_test_toggleref_callback (void); +#else +static inline void sgen_process_togglerefs (void) { } +static inline void sgen_register_test_toggleref_callback (void) { } +#endif + void sgen_mark_bridge_object (GCObject *obj) MONO_PERMIT (need (sgen_gc_locked)); @@ -1074,7 +1097,11 @@ extern mword sgen_total_promoted_size; extern mword sgen_total_allocated_major; extern volatile gboolean sgen_suspend_finalizers; extern MonoCoopMutex sgen_gc_mutex; +#ifndef DISABLE_SGEN_MAJOR_MARKSWEEP_CONC extern volatile gboolean sgen_concurrent_collection_in_progress; +#else +static const gboolean sgen_concurrent_collection_in_progress = FALSE; +#endif /* Nursery helpers. */ diff --git a/src/mono/mono/sgen/sgen-gchandles.c b/src/mono/mono/sgen/sgen-gchandles.c index 1ca10685a8c1fb..b802c439db6d96 100644 --- a/src/mono/mono/sgen/sgen-gchandles.c +++ b/src/mono/mono/sgen/sgen-gchandles.c @@ -523,6 +523,7 @@ sgen_register_obj_with_weak_fields (GCObject *obj) alloc_handle (gc_handles_for_type (HANDLE_WEAK_FIELDS), obj, FALSE); } +#ifndef DISABLE_SGEN_DEBUG_HELPERS void sgen_gchandle_stats_enable (void) { @@ -596,6 +597,7 @@ sgen_gchandle_stats_report (void) mono_gc_printf (sgen_gc_debug_file, "\n"); } SGEN_HASH_TABLE_FOREACH_END; } +#endif void sgen_init_gchandles (void) diff --git a/src/mono/mono/sgen/sgen-marksweep.c b/src/mono/mono/sgen/sgen-marksweep.c index 5fbd780144f467..7634caa5e21f39 100644 --- a/src/mono/mono/sgen/sgen-marksweep.c +++ b/src/mono/mono/sgen/sgen-marksweep.c @@ -197,7 +197,11 @@ typedef enum { static volatile int sweep_state = SWEEP_STATE_SWEPT; static gboolean concurrent_mark; +#ifndef DISABLE_SGEN_MAJOR_MARKSWEEP_CONC static gboolean concurrent_sweep = DEFAULT_SWEEP_MODE; +#else +static const gboolean concurrent_sweep = SGEN_SWEEP_SERIAL; +#endif static int sweep_pool_context = -1; @@ -908,6 +912,9 @@ static SgenThreadPoolJob * volatile sweep_blocks_job; static void major_finish_sweep_checking (void) { + if (!concurrent_sweep) + return; + guint32 block_index; SgenThreadPoolJob *job; @@ -2399,10 +2406,16 @@ major_handle_gc_param (const char *opt) lazy_sweep = FALSE; return TRUE; } else if (!strcmp (opt, "concurrent-sweep")) { +#ifndef DISABLE_SGEN_MAJOR_MARKSWEEP_CONC concurrent_sweep = TRUE; +#else + g_error ("Sgen was built with concurrent collector disabled"); +#endif return TRUE; } else if (!strcmp (opt, "no-concurrent-sweep")) { +#ifndef DISABLE_SGEN_MAJOR_MARKSWEEP_CONC concurrent_sweep = FALSE; +#endif return TRUE; } @@ -2884,7 +2897,9 @@ sgen_marksweep_init_internal (SgenMajorCollector *collector, gboolean is_concurr collector->alloc_degraded = major_alloc_degraded; collector->alloc_object = major_alloc_object; +#ifndef DISABLE_SGEN_MAJOR_MARKSWEEP_CONC collector->alloc_object_par = major_alloc_object_par; +#endif collector->free_pinned_object = free_pinned_object; collector->iterate_objects = major_iterate_objects; collector->free_non_pinned_object = major_free_non_pinned_object; @@ -2921,7 +2936,9 @@ sgen_marksweep_init_internal (SgenMajorCollector *collector, gboolean is_concurr collector->post_param_init = post_param_init; collector->is_valid_object = major_is_valid_object; collector->describe_pointer = major_describe_pointer; +#ifndef DISABLE_SGEN_BINARY_PROTOCOL collector->count_cards = major_count_cards; +#endif collector->init_block_free_lists = sgen_init_block_free_lists; collector->major_ops_serial.copy_or_mark_object = major_copy_or_mark_object_canonical; diff --git a/src/mono/mono/sgen/sgen-pinning-stats.c b/src/mono/mono/sgen/sgen-pinning-stats.c index f3e8631e991298..c8f0e0e22c29da 100644 --- a/src/mono/mono/sgen/sgen-pinning-stats.c +++ b/src/mono/mono/sgen/sgen-pinning-stats.c @@ -10,6 +10,8 @@ #include "config.h" #ifdef HAVE_SGEN_GC +#ifndef DISABLE_SGEN_DEBUG_HELPERS + #include #include "mono/sgen/sgen-gc.h" @@ -247,4 +249,6 @@ sgen_pin_stats_get_object_list (void) return &pinned_objects; } +#endif + #endif /* HAVE_SGEN_GC */ diff --git a/src/mono/mono/sgen/sgen-pinning.h b/src/mono/mono/sgen/sgen-pinning.h index 797e12b2614b29..d445b2b3486021 100644 --- a/src/mono/mono/sgen/sgen-pinning.h +++ b/src/mono/mono/sgen/sgen-pinning.h @@ -42,10 +42,17 @@ void sgen_pin_objects_in_section (GCMemSection *section, ScanCopyContext ctx); /* Pinning stats */ +#ifndef DISABLE_SGEN_DEBUG_HELPERS void sgen_pin_stats_register_address (char *addr, int pin_type); size_t sgen_pin_stats_get_pinned_byte_count (int pin_type); SgenPointerQueue *sgen_pin_stats_get_object_list (void); void sgen_pin_stats_reset (void); +#else +static inline void sgen_pin_stats_register_address (char *addr, int pin_type) { } +static inline size_t sgen_pin_stats_get_pinned_byte_count (int pin_type) { return 0; } +static inline SgenPointerQueue *sgen_pin_stats_get_object_list (void) { return NULL; } +static inline void sgen_pin_stats_reset (void) { } +#endif /* Perpetual pinning, aka cementing */ diff --git a/src/mono/mono/sgen/sgen-protocol.c b/src/mono/mono/sgen/sgen-protocol.c index 4afaf87e20d6d2..5fc013d6b57f3d 100644 --- a/src/mono/mono/sgen/sgen-protocol.c +++ b/src/mono/mono/sgen/sgen-protocol.c @@ -30,6 +30,8 @@ #include #endif +#ifndef DISABLE_SGEN_BINARY_PROTOCOL + #if defined(HOST_WIN32) static const HANDLE invalid_file_value = INVALID_HANDLE_VALUE; /* If valid, dump binary protocol to this file */ @@ -488,4 +490,6 @@ protocol_entry (unsigned char type, gpointer data, int size) #undef TYPE_POINTER #undef TYPE_BOOL +#endif + #endif /* HAVE_SGEN_GC */ diff --git a/src/mono/mono/sgen/sgen-protocol.h b/src/mono/mono/sgen/sgen-protocol.h index a29eb7d3e3d313..eff42b3206bdab 100644 --- a/src/mono/mono/sgen/sgen-protocol.h +++ b/src/mono/mono/sgen/sgen-protocol.h @@ -14,6 +14,8 @@ #include "sgen-gc.h" +#ifndef DISABLE_SGEN_BINARY_PROTOCOL + #define PROTOCOL_HEADER_CHECK 0xde7ec7ab1ec0de /* * The version needs to be bumped every time we introduce breaking changes (like @@ -244,4 +246,70 @@ gboolean sgen_binary_protocol_flush_buffers (gboolean force); #undef TYPE_POINTER #undef TYPE_BOOL +#else + +#ifndef TYPE_INT +#define TYPE_INT int +#endif +#ifndef TYPE_LONGLONG +#define TYPE_LONGLONG long long +#endif +#ifndef TYPE_SIZE +#define TYPE_SIZE size_t +#endif +#ifndef TYPE_POINTER +#define TYPE_POINTER gpointer +#endif +#ifndef TYPE_BOOL +#define TYPE_BOOL gboolean +#endif + +#define BEGIN_PROTOCOL_ENTRY0(method) \ + static inline void sgen_ ## method (void) {} +#define BEGIN_PROTOCOL_ENTRY1(method,t1,f1) \ + static inline void sgen_ ## method (t1 f1) {} +#define BEGIN_PROTOCOL_ENTRY2(method,t1,f1,t2,f2) \ + static inline void sgen_ ## method (t1 f1, t2 f2) {} +#define BEGIN_PROTOCOL_ENTRY3(method,t1,f1,t2,f2,t3,f3) \ + static inline void sgen_ ## method (t1 f1, t2 f2, t3 f3) {} +#define BEGIN_PROTOCOL_ENTRY4(method,t1,f1,t2,f2,t3,f3,t4,f4) \ + static inline void sgen_ ## method (t1 f1, t2 f2, t3 f3, t4 f4) {} +#define BEGIN_PROTOCOL_ENTRY5(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5) \ + static inline void sgen_ ## method (t1 f1, t2 f2, t3 f3, t4 f4, t5 f5) {} +#define BEGIN_PROTOCOL_ENTRY6(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6) \ + static inline void sgen_ ## method (t1 f1, t2 f2, t3 f3, t4 f4, t5 f5, t6 f6) {} +#define BEGIN_PROTOCOL_ENTRY_HEAVY0(method) \ + static inline void sgen_ ## method (void) {} +#define BEGIN_PROTOCOL_ENTRY_HEAVY1(method,t1,f1) \ + static inline void sgen_ ## method (t1 f1) {} +#define BEGIN_PROTOCOL_ENTRY_HEAVY2(method,t1,f1,t2,f2) \ + static inline void sgen_ ## method (t1 f1, t2 f2) {} +#define BEGIN_PROTOCOL_ENTRY_HEAVY3(method,t1,f1,t2,f2,t3,f3) \ + static inline void sgen_ ## method (t1 f1, t2 f2, t3 f3) {} +#define BEGIN_PROTOCOL_ENTRY_HEAVY4(method,t1,f1,t2,f2,t3,f3,t4,f4) \ + static inline void sgen_ ## method (t1 f1, t2 f2, t3 f3, t4 f4) {} +#define BEGIN_PROTOCOL_ENTRY_HEAVY5(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5) \ + static inline void sgen_ ## method (t1 f1, t2 f2, t3 f3, t4 f4, t5 f5) {} +#define BEGIN_PROTOCOL_ENTRY_HEAVY6(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6) \ + static inline void sgen_ ## method (t1 f1, t2 f2, t3 f3, t4 f4, t5 f5, t6 f6) {} +#define DEFAULT_PRINT() +#define CUSTOM_PRINT(_) + +#define IS_ALWAYS_MATCH(_) +#define MATCH_INDEX(_) +#define IS_VTABLE_MATCH(_) + +#define END_PROTOCOL_ENTRY +#define END_PROTOCOL_ENTRY_FLUSH +#define END_PROTOCOL_ENTRY_HEAVY + +#include "sgen-protocol-def.h" + +static inline void sgen_binary_protocol_init (const char *filename, long long limit) {} +static inline gboolean sgen_binary_protocol_is_enabled (void) { return FALSE; } +static inline gboolean sgen_binary_protocol_flush_buffers (gboolean force) { return FALSE; } +static inline gboolean sgen_binary_protocol_is_heavy_enabled () { return FALSE; } + +#endif + #endif diff --git a/src/mono/mono/sgen/sgen-thread-pool.c b/src/mono/mono/sgen/sgen-thread-pool.c index 656e561856791c..2cb408f7cbfe31 100644 --- a/src/mono/mono/sgen/sgen-thread-pool.c +++ b/src/mono/mono/sgen/sgen-thread-pool.c @@ -15,6 +15,8 @@ #include "mono/sgen/sgen-client.h" #include "mono/utils/mono-os-mutex.h" + +#ifndef DISABLE_SGEN_MAJOR_MARKSWEEP_CONC static mono_mutex_t lock; static mono_cond_t work_cond; static mono_cond_t done_cond; @@ -402,5 +404,71 @@ sgen_thread_pool_is_thread_pool_thread (MonoNativeThreadId some_thread) return 0; } +#else + +int +sgen_thread_pool_create_context (int num_threads, SgenThreadPoolThreadInitFunc init_func, SgenThreadPoolIdleJobFunc idle_func, SgenThreadPoolContinueIdleJobFunc continue_idle_func, SgenThreadPoolShouldWorkFunc should_work_func, void **thread_datas) +{ + return 0; +} + +void +sgen_thread_pool_start (void) +{ +} + +void +sgen_thread_pool_shutdown (void) +{ +} + +SgenThreadPoolJob* +sgen_thread_pool_job_alloc (const char *name, SgenThreadPoolJobFunc func, size_t size) +{ + SgenThreadPoolJob *job = (SgenThreadPoolJob *)sgen_alloc_internal_dynamic (size, INTERNAL_MEM_THREAD_POOL_JOB, TRUE); + job->name = name; + job->size = size; + job->func = func; + return job; +} + +void +sgen_thread_pool_job_free (SgenThreadPoolJob *job) +{ + sgen_free_internal_dynamic (job, job->size, INTERNAL_MEM_THREAD_POOL_JOB); +} + +void +sgen_thread_pool_job_enqueue (int context_id, SgenThreadPoolJob *job) +{ +} + +void +sgen_thread_pool_job_wait (int context_id, SgenThreadPoolJob *job) +{ +} + +void +sgen_thread_pool_idle_signal (int context_id) +{ +} + +void +sgen_thread_pool_idle_wait (int context_id, SgenThreadPoolContinueIdleWaitFunc continue_wait) +{ +} + +void +sgen_thread_pool_wait_for_all_jobs (int context_id) +{ +} + +int +sgen_thread_pool_is_thread_pool_thread (MonoNativeThreadId some_thread) +{ + return 0; +} + +#endif #endif diff --git a/src/mono/mono/sgen/sgen-workers.c b/src/mono/mono/sgen/sgen-workers.c index a8897d93dbb5e7..16e93d69a0f0a4 100644 --- a/src/mono/mono/sgen/sgen-workers.c +++ b/src/mono/mono/sgen/sgen-workers.c @@ -639,11 +639,6 @@ sgen_workers_assert_gray_queue_is_empty (int generation) { } -void -sgen_workers_foreach (int generation, SgenWorkerCallback callback) -{ -} - SgenObjectOperations* sgen_workers_get_idle_func_object_ops (WorkerData *worker) { @@ -685,11 +680,6 @@ sgen_workers_set_num_active_workers (int generation, int num_workers) { } -void -sgen_workers_start_all_workers (int generation, SgenObjectOperations *object_ops_nopar, SgenObjectOperations *object_ops_par, SgenWorkersFinishCallback callback) -{ -} - void sgen_workers_stop_all_workers (int generation) { diff --git a/src/mono/mono/sgen/sgen-workers.h b/src/mono/mono/sgen/sgen-workers.h index 14e68c93e2ae84..dce2364857be8c 100644 --- a/src/mono/mono/sgen/sgen-workers.h +++ b/src/mono/mono/sgen/sgen-workers.h @@ -78,7 +78,11 @@ struct _WorkerContext { void sgen_workers_create_context (int generation, int num_workers); void sgen_workers_stop_all_workers (int generation); void sgen_workers_set_num_active_workers (int generation, int num_workers); +#ifndef DISABLE_SGEN_MAJOR_MARKSWEEP_CONC void sgen_workers_start_all_workers (int generation, SgenObjectOperations *object_ops_nopar, SgenObjectOperations *object_ops_par, SgenWorkersFinishCallback finish_job); +#else +#define sgen_workers_start_all_workers(...) +#endif void sgen_workers_enqueue_job (int generation, SgenThreadPoolJob *job, gboolean enqueue); void sgen_workers_join (int generation); gboolean sgen_workers_have_idle_work (int generation); @@ -88,7 +92,11 @@ void sgen_workers_take_from_queue (int generation, SgenGrayQueue *queue); SgenObjectOperations* sgen_workers_get_idle_func_object_ops (WorkerData *worker); int sgen_workers_get_job_split_count (int generation); int sgen_workers_get_active_worker_count (int generation); +#ifndef DISABLE_SGEN_MAJOR_MARKSWEEP_CONC void sgen_workers_foreach (int generation, SgenWorkerCallback callback); +#else +#define sgen_workers_foreach(...) +#endif gboolean sgen_workers_is_worker_thread (MonoNativeThreadId id); #endif From f4e9146d1d2ba7cf48ab59022658619fc9dbaec3 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Sat, 18 Jul 2020 15:20:42 -0700 Subject: [PATCH 023/458] Test EmbeddedSignatureData api (#39329) - Add test to provide clarity about the behavior of the EmbeddedSignatureData api when examining the start of the signature for custom modifiers --- .../ILTestAssembly/Signature.il | 25 +++++++++++ .../SignatureTests.cs | 42 +++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ILTestAssembly/Signature.il b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ILTestAssembly/Signature.il index b28c850616f7cd..b895be9b24f484 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ILTestAssembly/Signature.il +++ b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ILTestAssembly/Signature.il @@ -1,6 +1,31 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +.class public auto ansi beforefieldinit ModOptTester + extends [CoreTestAssembly]System.Object +{ + .method public hidebysig specialname rtspecialname + instance void .ctor() cil managed + { + // Code size 8 (0x8) + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call instance void [CoreTestAssembly]System.Object::.ctor() + IL_0006: nop + IL_0007: ret + } // end of method I::.ctor + + .method public hidebysig instance int32 modopt([CoreTestAssembly]System.Void) modopt([CoreTestAssembly]System.Char) Method(int32 modopt(FooModifier)) cil managed + { + ret + } + + .method public hidebysig instance int32 modopt([CoreTestAssembly]System.Void) & modopt([CoreTestAssembly]System.Char) Method2(int32 modopt(FooModifier)) cil managed + { + ret + } +} + .class private auto ansi beforefieldinit Atom extends [CoreTestAssembly]System.Object { diff --git a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SignatureTests.cs b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SignatureTests.cs index cfaeef6ea437e3..e6a21525ee52c4 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SignatureTests.cs +++ b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SignatureTests.cs @@ -27,6 +27,48 @@ public SignatureTests() _testModule = _context.GetModuleForSimpleName("ILTestAssembly"); } + private static string GetModOptMethodSignatureInfo(MethodSignature signature) + { + if (!signature.HasEmbeddedSignatureData || signature.GetEmbeddedSignatureData() == null) + return ""; + + StringBuilder sb = new StringBuilder(); + foreach (EmbeddedSignatureData data in signature.GetEmbeddedSignatureData()) + { + sb.Append(data.kind.ToString()); + sb.Append(data.index); + sb.Append(((MetadataType)data.type).Name); + } + return sb.ToString(); + } + + [Fact] + public void TestSignatureMatches2ModOptsAtStartOfSig() + { + MetadataType modOptTester = _testModule.GetType("", "ModOptTester"); + MethodSignature methodWith2ModOptsAtStartOfSig = modOptTester.GetMethods().Single(m => string.Equals(m.Name, "Method")).Signature; + + // All modopts that are at the very beginning of the signature are given index 0.1.1.1 + // Both the index and the order in the modopt array are significant for signature comparison + Assert.Equal(MethodSignature.IndexOfCustomModifiersOnReturnType, methodWith2ModOptsAtStartOfSig.GetEmbeddedSignatureData()[0].index); + Assert.Equal(MethodSignature.IndexOfCustomModifiersOnReturnType, methodWith2ModOptsAtStartOfSig.GetEmbeddedSignatureData()[1].index); + Assert.NotEqual(MethodSignature.IndexOfCustomModifiersOnReturnType, methodWith2ModOptsAtStartOfSig.GetEmbeddedSignatureData()[2].index); + Assert.Equal("OptionalCustomModifier0.1.1.1CharOptionalCustomModifier0.1.1.1VoidOptionalCustomModifier0.1.2.1FooModifier", GetModOptMethodSignatureInfo(methodWith2ModOptsAtStartOfSig)); + } + + [Fact] + public void TestSignatureMatchesModOptAtStartOfSigAndAfterByRef() + { + MetadataType modOptTester = _testModule.GetType("", "ModOptTester"); + MethodSignature methodWithModOptAtStartOfSigAndAfterByRef = modOptTester.GetMethods().Single(m => string.Equals(m.Name, "Method2")).Signature; + + // A modopts after an E_T_BYREF will look like 0.1.1.2.1.1 + Assert.Equal(MethodSignature.IndexOfCustomModifiersOnReturnType, methodWithModOptAtStartOfSigAndAfterByRef.GetEmbeddedSignatureData()[0].index); + Assert.NotEqual(MethodSignature.IndexOfCustomModifiersOnReturnType, methodWithModOptAtStartOfSigAndAfterByRef.GetEmbeddedSignatureData()[1].index); + Assert.NotEqual(MethodSignature.IndexOfCustomModifiersOnReturnType, methodWithModOptAtStartOfSigAndAfterByRef.GetEmbeddedSignatureData()[2].index); + Assert.Equal("OptionalCustomModifier0.1.1.1CharOptionalCustomModifier0.1.1.2.1.1VoidOptionalCustomModifier0.1.2.1FooModifier", GetModOptMethodSignatureInfo(methodWithModOptAtStartOfSigAndAfterByRef)); + } + [Fact] public void TestSignatureMatches() { From 9a5ef961b9e6ef6fa3d88741189c96cc8c09e48d Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Mon, 20 Jul 2020 00:59:22 -0700 Subject: [PATCH 024/458] add SupportsTls11 and SupportsTls12 to PlatformDetection avoid OS versions in tests (#39482) * add SupportsTls11 and SupportsTls12 to avoid OS versions in tests * feedback from review * fix condition --- .../TestUtilities/System/PlatformDetection.cs | 3 +++ .../ServerAsyncAuthenticateTest.cs | 19 ++++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs index 68d07741e57a7a..7a4d50d540bbd7 100644 --- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs +++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs @@ -125,6 +125,9 @@ public static bool IsNonZeroLowerBoundArraySupported public static bool SupportsClientAlpn => SupportsAlpn || IsOSX || IsiOS || IstvOS; + // TLS 1.1 and 1.2 can work on Windows7 but it is not enabled by default. + public static bool SupportsTls11 => !IsWindows7 && !IsDebian10; + public static bool SupportsTls12 => !IsWindows7; // OpenSSL 1.1.1 and above. public static bool SupportsTls13 => GetTls13Support(); diff --git a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs index 1518cfc3fa545e..6695fc966ae5ab 100644 --- a/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs +++ b/src/libraries/System.Net.Security/tests/FunctionalTests/ServerAsyncAuthenticateTest.cs @@ -23,8 +23,6 @@ public class ServerAsyncAuthenticateTest : IDisposable private readonly ITestOutputHelper _logVerbose; private readonly X509Certificate2 _serverCertificate; - public static bool IsNotWindows7 => !PlatformDetection.IsWindows7; - public ServerAsyncAuthenticateTest(ITestOutputHelper output) { _log = output; @@ -99,9 +97,8 @@ public async Task ServerAsyncAuthenticate_SimpleSniOptions_Success() } } - [ConditionalTheory(nameof(IsNotWindows7))] - [InlineData(SslProtocols.Tls11)] - [InlineData(SslProtocols.Tls12)] + [Theory] + [MemberData(nameof(SupportedProtocolData))] public async Task ServerAsyncAuthenticate_SniSetVersion_Success(SslProtocols version) { var serverOptions = new SslServerAuthenticationOptions() { ServerCertificate = _serverCertificate, EnabledSslProtocols = version }; @@ -247,6 +244,18 @@ public static IEnumerable ProtocolMismatchData() yield return new object[] { SslProtocols.Tls12, SslProtocols.Tls11, typeof(AuthenticationException) }; } + public static IEnumerable SupportedProtocolData() + { + if (PlatformDetection.SupportsTls11) + { + yield return new object[] { SslProtocols.Tls11 }; + } + + if (PlatformDetection.SupportsTls12) + { + yield return new object[] { SslProtocols.Tls12 }; + } + } #region Helpers private async Task ServerAsyncSslHelper( From 0e23ef47ff8a2de6a5b5898a849ba00303aba8df Mon Sep 17 00:00:00 2001 From: David Mason Date: Mon, 20 Jul 2020 02:41:26 -0700 Subject: [PATCH 025/458] Reenable gcdump test (#39555) lower gcdump thresholds to make test pass on all platforms/architectures --- src/coreclr/tests/issues.targets | 3 --- src/tests/tracing/eventpipe/gcdump/gcdump.cs | 22 +++++++++----------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/coreclr/tests/issues.targets b/src/coreclr/tests/issues.targets index e19d521e42a47f..eb1f6be60e89f4 100644 --- a/src/coreclr/tests/issues.targets +++ b/src/coreclr/tests/issues.targets @@ -5,9 +5,6 @@ https://github.com/dotnet/runtime/issues/11204 - - https://github.com/dotnet/runtime/issues/39361 - timeout diff --git a/src/tests/tracing/eventpipe/gcdump/gcdump.cs b/src/tests/tracing/eventpipe/gcdump/gcdump.cs index 1ee96f83781c71..963544d9e308c9 100644 --- a/src/tests/tracing/eventpipe/gcdump/gcdump.cs +++ b/src/tests/tracing/eventpipe/gcdump/gcdump.cs @@ -82,17 +82,15 @@ public static int Main(string[] args) return () => { - // These values are ~80% (rounded to nice whole numbers) of the values - // I saw when writing the test. The idea is that I want to catch - // any real deviation in the number of types, but don't want to have - // to maintain this test as the number of types varies. (And they will vary due to - // framework code changes). If this test needs any sort of ongoing maintenance - // just change all these values to a low number like 10 and move on. - if (_bulkTypeCount > 125 - && _bulkNodeCount > 600 - && _bulkEdgeCount > 850 - && _bulkRootEdgeCount > 250 - && _bulkRootStaticVarCount > 70) + // Hopefully it is low enough to be resilient to changes in the runtime + // and high enough to catch issues. There should be between hundreds and thousands + // for each, but the number is variable and the point of the test is to verify + // that we get any events at all. + if (_bulkTypeCount > 50 + && _bulkNodeCount > 50 + && _bulkEdgeCount > 50 + && _bulkRootEdgeCount > 50 + && _bulkRootStaticVarCount > 50) { return 100; } @@ -108,4 +106,4 @@ public static int Main(string[] args) }; }; } -} \ No newline at end of file +} From 0e0e648770e54b12c2fa81a77538ce1a72fca8af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Mon, 20 Jul 2020 14:51:46 +0200 Subject: [PATCH 026/458] Synchronize dataflow annotations accross virtual methods (#39458) --- .../System/Reflection/Emit/AssemblyBuilder.cs | 4 ++ .../src/System/Reflection/Emit/EnumBuilder.cs | 16 +++++ .../Emit/GenericTypeParameterBuilder.cs | 16 +++++ .../System/Reflection/Emit/ModuleBuilder.cs | 14 ++++ .../src/System/Reflection/Emit/SymbolType.cs | 16 +++++ .../src/System/Reflection/Emit/TypeBuilder.cs | 16 +++++ .../Emit/TypeBuilderInstantiation.cs | 33 ++++++++++ .../src/System/Reflection/RuntimeAssembly.cs | 6 ++ .../src/System/Reflection/RuntimeModule.cs | 13 ++++ .../src/System/RuntimeType.CoreCLR.cs | 15 +++++ .../src/System/Reflection/IReflect.cs | 12 ++++ .../src/System/Reflection/SignatureType.cs | 48 ++++++++++++++ .../src/System/Reflection/TypeDelegator.cs | 22 +++++++ .../ref/System.Reflection.Emit.cs | 64 +++++++++++++++++++ .../System.Runtime/ref/System.Runtime.cs | 27 ++++++++ .../Reflection/Emit/AssemblyBuilder.Mono.cs | 3 + .../Reflection/Emit/DerivedTypes.Mono.cs | 16 +++++ .../Reflection/Emit/EnumBuilder.Mono.cs | 16 +++++ .../Emit/GenericTypeParameterBuilder.cs | 16 +++++ .../Reflection/Emit/ModuleBuilder.Mono.cs | 8 +++ .../Reflection/Emit/TypeBuilder.Mono.cs | 14 ++++ .../Emit/TypeBuilderInstantiation.cs | 14 ++++ .../src/System/Reflection/RuntimeAssembly.cs | 3 + .../src/System/Reflection/RuntimeModule.cs | 8 +++ .../src/System/RuntimeType.Mono.cs | 14 +++- 25 files changed, 433 insertions(+), 1 deletion(-) diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs index e1ce8a9f61f926..60d6791a057262 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.cs @@ -105,6 +105,7 @@ public override FileStream[] GetFiles(bool getResourceModules) public override string? CodeBase => throw new NotSupportedException(SR.NotSupported_DynamicAssembly); + [RequiresUnreferencedCode("Types might be removed")] public override Type[] GetExportedTypes() { throw new NotSupportedException(SR.NotSupported_DynamicAssembly); @@ -477,12 +478,14 @@ public override FileStream[] GetFiles(bool getResourceModules) /// /// Get an array of all the public types defined in this assembly. /// + [RequiresUnreferencedCode("Types might be removed")] public override Type[] GetExportedTypes() => InternalAssembly.GetExportedTypes(); public override AssemblyName GetName(bool copiedName) => InternalAssembly.GetName(copiedName); public override string? FullName => InternalAssembly.FullName; + [RequiresUnreferencedCode("Types might be removed")] public override Type? GetType(string name, bool throwOnError, bool ignoreCase) { return InternalAssembly.GetType(name, throwOnError, ignoreCase); @@ -494,6 +497,7 @@ public override FileStream[] GetFiles(bool getResourceModules) public override Module? GetModule(string name) => InternalAssembly.GetModule(name); + [RequiresUnreferencedCode("Types might be removed")] public override AssemblyName[] GetReferencedAssemblies() { return InternalAssembly.GetReferencedAssemblies(); diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.cs index 788969f7209774..4d52ddcb876f81 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.cs @@ -63,6 +63,7 @@ public FieldBuilder DefineLiteral(string literalName, object? literalValue) /// public override Guid GUID => m_typeBuilder.GUID; + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override object? InvokeMember( string name, BindingFlags invokeAttr, @@ -92,6 +93,7 @@ public FieldBuilder DefineLiteral(string literalName, object? literalValue) public override bool IsByRefLike => false; + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] protected override ConstructorInfo? GetConstructorImpl(BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[] types, ParameterModifier[]? modifiers) { @@ -99,11 +101,13 @@ public FieldBuilder DefineLiteral(string literalName, object? literalValue) types, modifiers); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) { return m_typeBuilder.GetConstructors(bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] protected override MethodInfo? GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers) { @@ -113,16 +117,19 @@ public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) return m_typeBuilder.GetMethod(name, bindingAttr, binder, callConvention, types, modifiers); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] public override MethodInfo[] GetMethods(BindingFlags bindingAttr) { return m_typeBuilder.GetMethods(bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo? GetField(string name, BindingFlags bindingAttr) { return m_typeBuilder.GetField(name, bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo[] GetFields(BindingFlags bindingAttr) { return m_typeBuilder.GetFields(bindingAttr); @@ -138,42 +145,50 @@ public override Type[] GetInterfaces() return m_typeBuilder.GetInterfaces(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo? GetEvent(string name, BindingFlags bindingAttr) { return m_typeBuilder.GetEvent(name, bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents)] public override EventInfo[] GetEvents() { return m_typeBuilder.GetEvents(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder? binder, Type? returnType, Type[]? types, ParameterModifier[]? modifiers) { throw new NotSupportedException(SR.NotSupported_DynamicModule); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) { return m_typeBuilder.GetProperties(bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type[] GetNestedTypes(BindingFlags bindingAttr) { return m_typeBuilder.GetNestedTypes(bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type? GetNestedType(string name, BindingFlags bindingAttr) { return m_typeBuilder.GetNestedType(name, bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) { return m_typeBuilder.GetMember(name, type, bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override MemberInfo[] GetMembers(BindingFlags bindingAttr) { return m_typeBuilder.GetMembers(bindingAttr); @@ -184,6 +199,7 @@ public override InterfaceMapping GetInterfaceMap(Type interfaceType) return m_typeBuilder.GetInterfaceMap(interfaceType); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo[] GetEvents(BindingFlags bindingAttr) { return m_typeBuilder.GetEvents(bindingAttr); diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs index ffa61eaa0a706f..e21b2c1a6a84bd 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs @@ -82,6 +82,7 @@ public override Type MakeArrayType(int rank) public override Guid GUID => throw new NotSupportedException(); + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override object InvokeMember(string name, BindingFlags invokeAttr, Binder? binder, object? target, object?[]? args, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParameters) { throw new NotSupportedException(); } public override Assembly Assembly => m_type.Assembly; @@ -96,40 +97,55 @@ public override Type MakeArrayType(int rank) public override Type? BaseType => m_type.BaseType; + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[] types, ParameterModifier[]? modifiers) { throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) { throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers) { throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] public override MethodInfo[] GetMethods(BindingFlags bindingAttr) { throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo GetField(string name, BindingFlags bindingAttr) { throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo[] GetFields(BindingFlags bindingAttr) { throw new NotSupportedException(); } public override Type GetInterface(string name, bool ignoreCase) { throw new NotSupportedException(); } public override Type[] GetInterfaces() { throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo GetEvent(string name, BindingFlags bindingAttr) { throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents)] public override EventInfo[] GetEvents() { throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder? binder, Type? returnType, Type[]? types, ParameterModifier[]? modifiers) { throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) { throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type[] GetNestedTypes(BindingFlags bindingAttr) { throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type GetNestedType(string name, BindingFlags bindingAttr) { throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) { throw new NotSupportedException(); } public override InterfaceMapping GetInterfaceMap(Type interfaceType) { throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo[] GetEvents(BindingFlags bindingAttr) { throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override MemberInfo[] GetMembers(BindingFlags bindingAttr) { throw new NotSupportedException(); } protected override TypeAttributes GetAttributeFlagsImpl() { return TypeAttributes.Public; } diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs index 4a719065ba42c5..c1ed6b887a02e1 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.cs @@ -524,6 +524,7 @@ public override IList GetCustomAttributesData() #region Module Overrides + [RequiresUnreferencedCode("Types might be removed")] public override Type[] GetTypes() { lock (SyncRoot) @@ -558,16 +559,19 @@ internal Type[] GetTypesNoLock() return typeList; } + [RequiresUnreferencedCode("Types might be removed")] public override Type? GetType(string className) { return GetType(className, false, false); } + [RequiresUnreferencedCode("Types might be removed")] public override Type? GetType(string className, bool ignoreCase) { return GetType(className, false, ignoreCase); } + [RequiresUnreferencedCode("Types might be removed")] public override Type? GetType(string className, bool throwOnError, bool ignoreCase) { lock (SyncRoot) @@ -677,31 +681,37 @@ internal Type[] GetTypesNoLock() public override string FullyQualifiedName => _moduleData._moduleName; + [RequiresUnreferencedCode("Trimming changes metadata tokens")] public override byte[] ResolveSignature(int metadataToken) { return InternalModule.ResolveSignature(metadataToken); } + [RequiresUnreferencedCode("Trimming changes metadata tokens")] public override MethodBase? ResolveMethod(int metadataToken, Type[]? genericTypeArguments, Type[]? genericMethodArguments) { return InternalModule.ResolveMethod(metadataToken, genericTypeArguments, genericMethodArguments); } + [RequiresUnreferencedCode("Trimming changes metadata tokens")] public override FieldInfo? ResolveField(int metadataToken, Type[]? genericTypeArguments, Type[]? genericMethodArguments) { return InternalModule.ResolveField(metadataToken, genericTypeArguments, genericMethodArguments); } + [RequiresUnreferencedCode("Trimming changes metadata tokens")] public override Type ResolveType(int metadataToken, Type[]? genericTypeArguments, Type[]? genericMethodArguments) { return InternalModule.ResolveType(metadataToken, genericTypeArguments, genericMethodArguments); } + [RequiresUnreferencedCode("Trimming changes metadata tokens")] public override MemberInfo? ResolveMember(int metadataToken, Type[]? genericTypeArguments, Type[]? genericMethodArguments) { return InternalModule.ResolveMember(metadataToken, genericTypeArguments, genericMethodArguments); } + [RequiresUnreferencedCode("Trimming changes metadata tokens")] public override string ResolveString(int metadataToken) { return InternalModule.ResolveString(metadataToken); @@ -720,21 +730,25 @@ public override void GetPEKind(out PortableExecutableKinds peKind, out ImageFile public override bool IsResource() => InternalModule.IsResource(); + [RequiresUnreferencedCode("Fields might be removed")] public override FieldInfo[] GetFields(BindingFlags bindingFlags) { return InternalModule.GetFields(bindingFlags); } + [RequiresUnreferencedCode("Fields might be removed")] public override FieldInfo? GetField(string name, BindingFlags bindingAttr) { return InternalModule.GetField(name, bindingAttr); } + [RequiresUnreferencedCode("Fields might be removed")] public override MethodInfo[] GetMethods(BindingFlags bindingFlags) { return InternalModule.GetMethods(bindingFlags); } + [RequiresUnreferencedCode("Fields might be removed")] protected override MethodInfo? GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers) { diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/SymbolType.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/SymbolType.cs index fa49a2256681e7..fbd9102b894beb 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/SymbolType.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/SymbolType.cs @@ -300,6 +300,7 @@ public override int GetArrayRank() public override Guid GUID => throw new NotSupportedException(SR.NotSupported_NonReflectedType); + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override object InvokeMember(string name, BindingFlags invokeAttr, Binder? binder, object? target, object?[]? args, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParameters) { @@ -358,33 +359,39 @@ public override string ToString() public override Type BaseType => typeof(System.Array); + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[] types, ParameterModifier[]? modifiers) { throw new NotSupportedException(SR.NotSupported_NonReflectedType); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) { throw new NotSupportedException(SR.NotSupported_NonReflectedType); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers) { throw new NotSupportedException(SR.NotSupported_NonReflectedType); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] public override MethodInfo[] GetMethods(BindingFlags bindingAttr) { throw new NotSupportedException(SR.NotSupported_NonReflectedType); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo GetField(string name, BindingFlags bindingAttr) { throw new NotSupportedException(SR.NotSupported_NonReflectedType); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo[] GetFields(BindingFlags bindingAttr) { throw new NotSupportedException(SR.NotSupported_NonReflectedType); @@ -400,42 +407,50 @@ public override Type[] GetInterfaces() throw new NotSupportedException(SR.NotSupported_NonReflectedType); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo GetEvent(string name, BindingFlags bindingAttr) { throw new NotSupportedException(SR.NotSupported_NonReflectedType); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents)] public override EventInfo[] GetEvents() { throw new NotSupportedException(SR.NotSupported_NonReflectedType); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder? binder, Type? returnType, Type[]? types, ParameterModifier[]? modifiers) { throw new NotSupportedException(SR.NotSupported_NonReflectedType); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) { throw new NotSupportedException(SR.NotSupported_NonReflectedType); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type[] GetNestedTypes(BindingFlags bindingAttr) { throw new NotSupportedException(SR.NotSupported_NonReflectedType); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type GetNestedType(string name, BindingFlags bindingAttr) { throw new NotSupportedException(SR.NotSupported_NonReflectedType); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) { throw new NotSupportedException(SR.NotSupported_NonReflectedType); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override MemberInfo[] GetMembers(BindingFlags bindingAttr) { throw new NotSupportedException(SR.NotSupported_NonReflectedType); @@ -446,6 +461,7 @@ public override InterfaceMapping GetInterfaceMap(Type interfaceType) throw new NotSupportedException(SR.NotSupported_NonReflectedType); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo[] GetEvents(BindingFlags bindingAttr) { throw new NotSupportedException(SR.NotSupported_NonReflectedType); diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs index 47c3dea104ee3c..5b2acd1605bb24 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs @@ -744,6 +744,7 @@ public override Guid GUID } } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override object? InvokeMember(string name, BindingFlags invokeAttr, Binder? binder, object? target, object?[]? args, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParameters) { @@ -765,6 +766,7 @@ public override Guid GUID public override Type? BaseType => m_typeParent; + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] protected override ConstructorInfo? GetConstructorImpl(BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[] types, ParameterModifier[]? modifiers) { @@ -774,6 +776,7 @@ public override Guid GUID return m_bakedRuntimeType.GetConstructor(bindingAttr, binder, callConvention, types, modifiers); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) { if (!IsCreated()) @@ -782,6 +785,7 @@ public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) return m_bakedRuntimeType.GetConstructors(bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] protected override MethodInfo? GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers) { @@ -798,6 +802,7 @@ public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) } } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] public override MethodInfo[] GetMethods(BindingFlags bindingAttr) { if (!IsCreated()) @@ -806,6 +811,7 @@ public override MethodInfo[] GetMethods(BindingFlags bindingAttr) return m_bakedRuntimeType.GetMethods(bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo? GetField(string name, BindingFlags bindingAttr) { if (!IsCreated()) @@ -814,6 +820,7 @@ public override MethodInfo[] GetMethods(BindingFlags bindingAttr) return m_bakedRuntimeType.GetField(name, bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo[] GetFields(BindingFlags bindingAttr) { if (!IsCreated()) @@ -845,6 +852,7 @@ public override Type[] GetInterfaces() return m_typeInterfaces.ToArray(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo? GetEvent(string name, BindingFlags bindingAttr) { if (!IsCreated()) @@ -853,6 +861,7 @@ public override Type[] GetInterfaces() return m_bakedRuntimeType.GetEvent(name, bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents)] public override EventInfo[] GetEvents() { if (!IsCreated()) @@ -861,12 +870,14 @@ public override EventInfo[] GetEvents() return m_bakedRuntimeType.GetEvents(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder? binder, Type? returnType, Type[]? types, ParameterModifier[]? modifiers) { throw new NotSupportedException(SR.NotSupported_DynamicModule); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) { if (!IsCreated()) @@ -875,6 +886,7 @@ public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) return m_bakedRuntimeType.GetProperties(bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type[] GetNestedTypes(BindingFlags bindingAttr) { if (!IsCreated()) @@ -883,6 +895,7 @@ public override Type[] GetNestedTypes(BindingFlags bindingAttr) return m_bakedRuntimeType.GetNestedTypes(bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type? GetNestedType(string name, BindingFlags bindingAttr) { if (!IsCreated()) @@ -891,6 +904,7 @@ public override Type[] GetNestedTypes(BindingFlags bindingAttr) return m_bakedRuntimeType.GetNestedType(name, bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) { if (!IsCreated()) @@ -907,6 +921,7 @@ public override InterfaceMapping GetInterfaceMap(Type interfaceType) return m_bakedRuntimeType.GetInterfaceMap(interfaceType); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo[] GetEvents(BindingFlags bindingAttr) { if (!IsCreated()) @@ -915,6 +930,7 @@ public override EventInfo[] GetEvents(BindingFlags bindingAttr) return m_bakedRuntimeType.GetEvents(bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override MemberInfo[] GetMembers(BindingFlags bindingAttr) { if (!IsCreated()) diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs index 1a6e10196af898..4e3844dac940cd 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs @@ -97,7 +97,10 @@ public override Type MakeArrayType(int rank) return SymbolType.FormCompoundType(s, this, 0)!; } public override Guid GUID => throw new NotSupportedException(); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override object InvokeMember(string name, BindingFlags invokeAttr, Binder? binder, object? target, object?[]? args, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParameters) { throw new NotSupportedException(); } + public override Assembly Assembly => m_type.Assembly; public override RuntimeTypeHandle TypeHandle => throw new NotSupportedException(); public override string? FullName => m_strFullQualName ??= TypeNameBuilder.ToString(this, TypeNameBuilder.Format.FullName); @@ -152,26 +155,56 @@ public override Type? BaseType return typeBldrBaseAs.Substitute(GetGenericArguments()); } } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[] types, ParameterModifier[]? modifiers) { throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) { throw new NotSupportedException(); } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers) { throw new NotSupportedException(); } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] public override MethodInfo[] GetMethods(BindingFlags bindingAttr) { throw new NotSupportedException(); } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo GetField(string name, BindingFlags bindingAttr) { throw new NotSupportedException(); } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo[] GetFields(BindingFlags bindingAttr) { throw new NotSupportedException(); } + public override Type GetInterface(string name, bool ignoreCase) { throw new NotSupportedException(); } public override Type[] GetInterfaces() { throw new NotSupportedException(); } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo GetEvent(string name, BindingFlags bindingAttr) { throw new NotSupportedException(); } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents)] public override EventInfo[] GetEvents() { throw new NotSupportedException(); } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder? binder, Type? returnType, Type[]? types, ParameterModifier[]? modifiers) { throw new NotSupportedException(); } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) { throw new NotSupportedException(); } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type[] GetNestedTypes(BindingFlags bindingAttr) { throw new NotSupportedException(); } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type GetNestedType(string name, BindingFlags bindingAttr) { throw new NotSupportedException(); } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) { throw new NotSupportedException(); } public override InterfaceMapping GetInterfaceMap(Type interfaceType) { throw new NotSupportedException(); } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo[] GetEvents(BindingFlags bindingAttr) { throw new NotSupportedException(); } + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override MemberInfo[] GetMembers(BindingFlags bindingAttr) { throw new NotSupportedException(); } + protected override TypeAttributes GetAttributeFlagsImpl() { return m_type.Attributes; } public override bool IsTypeDefinition => false; diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs index 4aa7b486c723fa..d2476660973fd3 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using CultureInfo = System.Globalization.CultureInfo; using System.IO; using System.Configuration.Assemblies; @@ -158,6 +159,7 @@ private static extern void GetType(QCallAssembly assembly, ObjectHandleOnStack keepAlive, ObjectHandleOnStack assemblyLoadContext); + [RequiresUnreferencedCode("Types might be removed")] public override Type? GetType(string name, bool throwOnError, bool ignoreCase) { // throw on null strings regardless of the value of "throwOnError" @@ -184,6 +186,7 @@ private static extern void GetType(QCallAssembly assembly, [DllImport(RuntimeHelpers.QCall, CharSet = CharSet.Unicode)] private static extern void GetExportedTypes(QCallAssembly assembly, ObjectHandleOnStack retTypes); + [RequiresUnreferencedCode("Types might be removed")] public override Type[] GetExportedTypes() { Type[]? types = null; @@ -194,6 +197,7 @@ public override Type[] GetExportedTypes() public override IEnumerable DefinedTypes { + [RequiresUnreferencedCode("Types might be removed")] get { RuntimeModule[] modules = GetModulesInternal(true, false); @@ -394,6 +398,7 @@ public override string[] GetManifestResourceNames() [MethodImpl(MethodImplOptions.InternalCall)] private static extern AssemblyName[] GetReferencedAssemblies(RuntimeAssembly assembly); + [RequiresUnreferencedCode("Assembly references might be removed")] public override AssemblyName[] GetReferencedAssemblies() { return GetReferencedAssemblies(GetNativeHandle()); @@ -607,6 +612,7 @@ public override Module[] GetLoadedModules(bool getResourceModules) [MethodImpl(MethodImplOptions.InternalCall)] internal static extern int GetToken(RuntimeAssembly assembly); + [RequiresUnreferencedCode("Types might be removed")] public sealed override Type[] GetForwardedTypes() { List types = new List(); diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs index 3835866b99bfd5..990b52854a05fb 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Collections.Generic; @@ -60,6 +61,7 @@ internal RuntimeType[] GetDefinedTypes() return typeHandleArgs; } + [RequiresUnreferencedCode("Trimming changes metadata tokens")] public override byte[] ResolveSignature(int metadataToken) { MetadataToken tk = new MetadataToken(metadataToken); @@ -86,6 +88,7 @@ public override byte[] ResolveSignature(int metadataToken) return sig; } + [RequiresUnreferencedCode("Trimming changes metadata tokens")] public override MethodBase? ResolveMethod(int metadataToken, Type[]? genericTypeArguments, Type[]? genericMethodArguments) { MetadataToken tk = new MetadataToken(metadataToken); @@ -165,6 +168,7 @@ public override byte[] ResolveSignature(int metadataToken) } } + [RequiresUnreferencedCode("Trimming changes metadata tokens")] public override FieldInfo? ResolveField(int metadataToken, Type[]? genericTypeArguments, Type[]? genericMethodArguments) { MetadataToken tk = new MetadataToken(metadataToken); @@ -219,6 +223,7 @@ public override byte[] ResolveSignature(int metadataToken) } } + [RequiresUnreferencedCode("Trimming changes metadata tokens")] public override Type ResolveType(int metadataToken, Type[]? genericTypeArguments, Type[]? genericMethodArguments) { MetadataToken tk = new MetadataToken(metadataToken); @@ -251,6 +256,7 @@ public override Type ResolveType(int metadataToken, Type[]? genericTypeArguments } } + [RequiresUnreferencedCode("Trimming changes metadata tokens")] public override MemberInfo? ResolveMember(int metadataToken, Type[]? genericTypeArguments, Type[]? genericMethodArguments) { MetadataToken tk = new MetadataToken(metadataToken); @@ -295,6 +301,7 @@ public override Type ResolveType(int metadataToken, Type[]? genericTypeArguments nameof(metadataToken)); } + [RequiresUnreferencedCode("Trimming changes metadata tokens")] public override string ResolveString(int metadataToken) { MetadataToken tk = new MetadataToken(metadataToken); @@ -336,6 +343,7 @@ public override void GetPEKind(out PortableExecutableKinds peKind, out ImageFile #endregion #region Protected Virtuals + [RequiresUnreferencedCode("Methods might be removed")] protected override MethodInfo? GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers) { @@ -415,6 +423,7 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont throw new PlatformNotSupportedException(); } + [RequiresUnreferencedCode("Types might be removed")] public override Type? GetType(string className, bool throwOnError, bool ignoreCase) { // throw on null strings regardless of the value of "throwOnError" @@ -439,6 +448,7 @@ internal string GetFullyQualifiedName() public override string FullyQualifiedName => GetFullyQualifiedName(); + [RequiresUnreferencedCode("Types might be removed")] public override Type[] GetTypes() { return GetTypes(GetNativeHandle()); @@ -464,6 +474,7 @@ public override bool IsResource() return IsResource(GetNativeHandle()); } + [RequiresUnreferencedCode("Fields might be removed")] public override FieldInfo[] GetFields(BindingFlags bindingFlags) { if (RuntimeType == null) @@ -472,6 +483,7 @@ public override FieldInfo[] GetFields(BindingFlags bindingFlags) return RuntimeType.GetFields(bindingFlags); } + [RequiresUnreferencedCode("Fields might be removed")] public override FieldInfo? GetField(string name, BindingFlags bindingAttr) { if (name == null) @@ -483,6 +495,7 @@ public override FieldInfo[] GetFields(BindingFlags bindingFlags) return RuntimeType.GetField(name, bindingAttr); } + [RequiresUnreferencedCode("Methods might be removed")] public override MethodInfo[] GetMethods(BindingFlags bindingFlags) { if (RuntimeType == null) diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs index f4e9ac9829664a..a883bad112b3ad 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs @@ -2532,26 +2532,31 @@ private ListBuilder GetNestedTypeCandidates(string? fullname, BindingFlags #endregion #region Get All XXXInfos + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] public override MethodInfo[] GetMethods(BindingFlags bindingAttr) { return GetMethodCandidates(null, GenericParameterCountAny, bindingAttr, CallingConventions.Any, null, false).ToArray(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) { return GetConstructorCandidates(null, bindingAttr, CallingConventions.Any, null, false).ToArray(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) { return GetPropertyCandidates(null, bindingAttr, null, false).ToArray(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo[] GetEvents(BindingFlags bindingAttr) { return GetEventCandidates(null, bindingAttr, false).ToArray(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo[] GetFields(BindingFlags bindingAttr) { return GetFieldCandidates(null, bindingAttr, false).ToArray(); @@ -2563,11 +2568,13 @@ public override Type[] GetInterfaces() return new ReadOnlySpan(candidates).ToArray(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type[] GetNestedTypes(BindingFlags bindingAttr) { return GetNestedTypeCandidates(null, bindingAttr, false).ToArray(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override MemberInfo[] GetMembers(BindingFlags bindingAttr) { ListBuilder methods = GetMethodCandidates(null, GenericParameterCountAny, bindingAttr, CallingConventions.Any, null, false); @@ -2663,6 +2670,7 @@ public override InterfaceMapping GetInterfaceMap(Type ifaceType) #region Find XXXInfo + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] protected override MethodInfo? GetMethodImpl( string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConv, Type[]? types, ParameterModifier[]? modifiers) @@ -2670,6 +2678,7 @@ public override InterfaceMapping GetInterfaceMap(Type ifaceType) return GetMethodImplCommon(name, GenericParameterCountAny, bindingAttr, binder, callConv, types, modifiers); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] protected override MethodInfo? GetMethodImpl( string name, int genericParameterCount, BindingFlags bindingAttr, Binder? binder, CallingConventions callConv, Type[]? types, ParameterModifier[]? modifiers) @@ -2714,6 +2723,7 @@ public override InterfaceMapping GetInterfaceMap(Type ifaceType) return binder.SelectMethod(bindingAttr, candidates.ToArray(), types, modifiers) as MethodInfo; } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] protected override ConstructorInfo? GetConstructorImpl( BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[] types, ParameterModifier[]? modifiers) @@ -2741,6 +2751,7 @@ public override InterfaceMapping GetInterfaceMap(Type ifaceType) return binder.SelectMethod(bindingAttr, candidates.ToArray(), types, modifiers) as ConstructorInfo; } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] protected override PropertyInfo? GetPropertyImpl( string name, BindingFlags bindingAttr, Binder? binder, Type? returnType, Type[]? types, ParameterModifier[]? modifiers) { @@ -2778,6 +2789,7 @@ public override InterfaceMapping GetInterfaceMap(Type ifaceType) return binder.SelectProperty(bindingAttr, candidates.ToArray(), returnType, types, modifiers); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo? GetEvent(string name, BindingFlags bindingAttr) { if (name is null) throw new ArgumentNullException(nameof(name)); @@ -2804,6 +2816,7 @@ public override InterfaceMapping GetInterfaceMap(Type ifaceType) return match; } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo? GetField(string name, BindingFlags bindingAttr) { if (name is null) throw new ArgumentNullException(); @@ -2875,6 +2888,7 @@ public override InterfaceMapping GetInterfaceMap(Type ifaceType) return match; } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type? GetNestedType(string fullname, BindingFlags bindingAttr) { if (fullname is null) throw new ArgumentNullException(nameof(fullname)); @@ -2903,6 +2917,7 @@ public override InterfaceMapping GetInterfaceMap(Type ifaceType) return match; } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) { if (name is null) throw new ArgumentNullException(nameof(name)); diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/IReflect.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/IReflect.cs index e46a69c432fd5c..b7e1786d3e9bf5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/IReflect.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/IReflect.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using System.Globalization; namespace System.Reflection @@ -10,39 +11,49 @@ public interface IReflect // Return the requested method if it is implemented by the Reflection object. The // match is based upon the name and DescriptorInfo which describes the signature // of the method. + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] MethodInfo? GetMethod(string name, BindingFlags bindingAttr, Binder? binder, Type[] types, ParameterModifier[]? modifiers); // Return the requested method if it is implemented by the Reflection object. The // match is based upon the name of the method. If the object implementes multiple methods // with the same name an AmbiguousMatchException is thrown. + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] MethodInfo? GetMethod(string name, BindingFlags bindingAttr); + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] MethodInfo[] GetMethods(BindingFlags bindingAttr); // Return the requestion field if it is implemented by the Reflection object. The // match is based upon a name. There cannot be more than a single field with // a name. + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] FieldInfo? GetField(string name, BindingFlags bindingAttr); + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] FieldInfo[] GetFields(BindingFlags bindingAttr); // Return the property based upon name. If more than one property has the given // name an AmbiguousMatchException will be thrown. Returns null if no property // is found. + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] PropertyInfo? GetProperty(string name, BindingFlags bindingAttr); // Return the property based upon the name and Descriptor info describing the property // indexing. Return null if no property is found. + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] PropertyInfo? GetProperty(string name, BindingFlags bindingAttr, Binder? binder, Type? returnType, Type[] types, ParameterModifier[]? modifiers); // Returns an array of PropertyInfos for all the properties defined on // the Reflection object. + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] PropertyInfo[] GetProperties(BindingFlags bindingAttr); // Return an array of members which match the passed in name. + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] MemberInfo[] GetMember(string name, BindingFlags bindingAttr); // Return an array of all of the members defined for this object. + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] MemberInfo[] GetMembers(BindingFlags bindingAttr); // Description of the Binding Process. @@ -66,6 +77,7 @@ public interface IReflect // For the default binder, the most specific method will be selected. // // This will invoke a specific member... + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] object? InvokeMember(string name, BindingFlags invokeAttr, Binder? binder, object? target, object?[]? args, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParameters); // Return the underlying Type that represents the IReflect Object. For expando object, diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/SignatureType.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/SignatureType.cs index f84668ecf55cdb..b8e5e18462c4e4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/SignatureType.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/SignatureType.cs @@ -97,31 +97,79 @@ public sealed override Type MakeArrayType(int rank) public sealed override Guid GUID => throw new NotSupportedException(SR.NotSupported_SignatureType); protected sealed override TypeCode GetTypeCodeImpl() => throw new NotSupportedException(SR.NotSupported_SignatureType); protected sealed override TypeAttributes GetAttributeFlagsImpl() => throw new NotSupportedException(SR.NotSupported_SignatureType); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] public sealed override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) => throw new NotSupportedException(SR.NotSupported_SignatureType); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public sealed override EventInfo GetEvent(string name, BindingFlags bindingAttr) => throw new NotSupportedException(SR.NotSupported_SignatureType); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public sealed override EventInfo[] GetEvents(BindingFlags bindingAttr) => throw new NotSupportedException(SR.NotSupported_SignatureType); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public sealed override FieldInfo GetField(string name, BindingFlags bindingAttr) => throw new NotSupportedException(SR.NotSupported_SignatureType); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public sealed override FieldInfo[] GetFields(BindingFlags bindingAttr) => throw new NotSupportedException(SR.NotSupported_SignatureType); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public sealed override MemberInfo[] GetMembers(BindingFlags bindingAttr) => throw new NotSupportedException(SR.NotSupported_SignatureType); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] public sealed override MethodInfo[] GetMethods(BindingFlags bindingAttr) => throw new NotSupportedException(SR.NotSupported_SignatureType); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public sealed override Type GetNestedType(string name, BindingFlags bindingAttr) => throw new NotSupportedException(SR.NotSupported_SignatureType); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public sealed override Type[] GetNestedTypes(BindingFlags bindingAttr) => throw new NotSupportedException(SR.NotSupported_SignatureType); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] public sealed override PropertyInfo[] GetProperties(BindingFlags bindingAttr) => throw new NotSupportedException(SR.NotSupported_SignatureType); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public sealed override object InvokeMember(string name, BindingFlags invokeAttr, Binder? binder, object? target, object?[]? args, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParameters) => throw new NotSupportedException(SR.NotSupported_SignatureType); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] protected sealed override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers) => throw new NotSupportedException(SR.NotSupported_SignatureType); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] protected sealed override MethodInfo GetMethodImpl(string name, int genericParameterCount, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers) => throw new NotSupportedException(SR.NotSupported_SignatureType); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] protected sealed override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder? binder, Type? returnType, Type[]? types, ParameterModifier[]? modifiers) => throw new NotSupportedException(SR.NotSupported_SignatureType); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public sealed override MemberInfo[] FindMembers(MemberTypes memberType, BindingFlags bindingAttr, MemberFilter? filter, object? filterCriteria) => throw new NotSupportedException(SR.NotSupported_SignatureType); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public sealed override MemberInfo[] GetMember(string name, BindingFlags bindingAttr) => throw new NotSupportedException(SR.NotSupported_SignatureType); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public sealed override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) => throw new NotSupportedException(SR.NotSupported_SignatureType); + + [DynamicallyAccessedMembers( + DynamicallyAccessedMemberTypes.PublicFields + | DynamicallyAccessedMemberTypes.PublicMethods + | DynamicallyAccessedMemberTypes.PublicEvents + | DynamicallyAccessedMemberTypes.PublicProperties + | DynamicallyAccessedMemberTypes.PublicConstructors + | DynamicallyAccessedMemberTypes.PublicNestedTypes)] public sealed override MemberInfo[] GetDefaultMembers() => throw new NotSupportedException(SR.NotSupported_SignatureType); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents)] public sealed override EventInfo[] GetEvents() => throw new NotSupportedException(SR.NotSupported_SignatureType); + public sealed override object[] GetCustomAttributes(bool inherit) => throw new NotSupportedException(SR.NotSupported_SignatureType); public sealed override object[] GetCustomAttributes(Type attributeType, bool inherit) => throw new NotSupportedException(SR.NotSupported_SignatureType); public sealed override bool IsDefined(Type attributeType, bool inherit) => throw new NotSupportedException(SR.NotSupported_SignatureType); public sealed override IList GetCustomAttributesData() => throw new NotSupportedException(SR.NotSupported_SignatureType); public sealed override Type GetInterface(string name, bool ignoreCase) => throw new NotSupportedException(SR.NotSupported_SignatureType); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] protected sealed override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[] types, ParameterModifier[]? modifiers) => throw new NotSupportedException(SR.NotSupported_SignatureType); + protected sealed override bool IsCOMObjectImpl() => throw new NotSupportedException(SR.NotSupported_SignatureType); protected sealed override bool IsPrimitiveImpl() => throw new NotSupportedException(SR.NotSupported_SignatureType); public sealed override IEnumerable CustomAttributes => throw new NotSupportedException(SR.NotSupported_SignatureType); diff --git a/src/libraries/System.Private.CoreLib/src/System/Reflection/TypeDelegator.cs b/src/libraries/System.Private.CoreLib/src/System/Reflection/TypeDelegator.cs index 5461da5198959c..9c0cf16aa5c5af 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Reflection/TypeDelegator.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Reflection/TypeDelegator.cs @@ -38,6 +38,7 @@ public TypeDelegator([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes. public override Guid GUID => typeImpl.GUID; public override int MetadataToken => typeImpl.MetadataToken; + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override object? InvokeMember(string name, BindingFlags invokeAttr, Binder? binder, object? target, object?[]? args, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParameters) { @@ -53,14 +54,17 @@ public TypeDelegator([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes. public override string? AssemblyQualifiedName => typeImpl.AssemblyQualifiedName; public override Type? BaseType => typeImpl.BaseType; + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] protected override ConstructorInfo? GetConstructorImpl(BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[] types, ParameterModifier[]? modifiers) { return typeImpl.GetConstructor(bindingAttr, binder, callConvention, types, modifiers); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) => typeImpl.GetConstructors(bindingAttr); + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] protected override MethodInfo? GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers) { @@ -72,19 +76,26 @@ public TypeDelegator([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes. return typeImpl.GetMethod(name, bindingAttr, binder, callConvention, types, modifiers); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] public override MethodInfo[] GetMethods(BindingFlags bindingAttr) => typeImpl.GetMethods(bindingAttr); + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo? GetField(string name, BindingFlags bindingAttr) => typeImpl.GetField(name, bindingAttr); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo[] GetFields(BindingFlags bindingAttr) => typeImpl.GetFields(bindingAttr); public override Type? GetInterface(string name, bool ignoreCase) => typeImpl.GetInterface(name, ignoreCase); public override Type[] GetInterfaces() => typeImpl.GetInterfaces(); + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo? GetEvent(string name, BindingFlags bindingAttr) => typeImpl.GetEvent(name, bindingAttr); + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents)] public override EventInfo[] GetEvents() => typeImpl.GetEvents(); + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] protected override PropertyInfo? GetPropertyImpl(string name, BindingFlags bindingAttr, Binder? binder, Type? returnType, Type[]? types, ParameterModifier[]? modifiers) { @@ -94,11 +105,22 @@ public TypeDelegator([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes. return typeImpl.GetProperty(name, bindingAttr, binder, returnType, types!, modifiers); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) => typeImpl.GetProperties(bindingAttr); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo[] GetEvents(BindingFlags bindingAttr) => typeImpl.GetEvents(bindingAttr); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type[] GetNestedTypes(BindingFlags bindingAttr) => typeImpl.GetNestedTypes(bindingAttr); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type? GetNestedType(string name, BindingFlags bindingAttr) => typeImpl.GetNestedType(name, bindingAttr); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) => typeImpl.GetMember(name, type, bindingAttr); + + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override MemberInfo[] GetMembers(BindingFlags bindingAttr) => typeImpl.GetMembers(bindingAttr); protected override TypeAttributes GetAttributeFlagsImpl() => typeImpl.Attributes; diff --git a/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs b/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs index bd34fa007dcee7..2031b7df5495a3 100644 --- a/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs +++ b/src/libraries/System.Reflection.Emit/ref/System.Reflection.Emit.cs @@ -28,6 +28,7 @@ internal AssemblyBuilder() { } public override object[] GetCustomAttributes(System.Type attributeType, bool inherit) { throw null; } public override System.Collections.Generic.IList GetCustomAttributesData() { throw null; } public System.Reflection.Emit.ModuleBuilder? GetDynamicModule(string name) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")] public override System.Type[] GetExportedTypes() { throw null; } public override System.IO.FileStream GetFile(string name) { throw null; } public override System.IO.FileStream[] GetFiles(bool getResourceModules) { throw null; } @@ -40,9 +41,11 @@ internal AssemblyBuilder() { } public override System.Reflection.Module? GetModule(string name) { throw null; } public override System.Reflection.Module[] GetModules(bool getResourceModules) { throw null; } public override System.Reflection.AssemblyName GetName(bool copiedName) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")] public override System.Reflection.AssemblyName[] GetReferencedAssemblies() { throw null; } public override System.Reflection.Assembly GetSatelliteAssembly(System.Globalization.CultureInfo culture) { throw null; } public override System.Reflection.Assembly GetSatelliteAssembly(System.Globalization.CultureInfo culture, System.Version? version) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")] public override System.Type? GetType(string name, bool throwOnError, bool ignoreCase) { throw null; } public override bool IsDefined(System.Type attributeType, bool inherit) { throw null; } public void SetCustomAttribute(System.Reflection.ConstructorInfo con, byte[] binaryAttribute) { } @@ -104,29 +107,45 @@ internal EnumBuilder() { } public System.Reflection.TypeInfo? CreateTypeInfo() { throw null; } public System.Reflection.Emit.FieldBuilder DefineLiteral(string literalName, object? literalValue) { throw null; } protected override System.Reflection.TypeAttributes GetAttributeFlagsImpl() { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] protected override System.Reflection.ConstructorInfo? GetConstructorImpl(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, System.Reflection.CallingConventions callConvention, System.Type[] types, System.Reflection.ParameterModifier[]? modifiers) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] public override System.Reflection.ConstructorInfo[] GetConstructors(System.Reflection.BindingFlags bindingAttr) { throw null; } public override object[] GetCustomAttributes(bool inherit) { throw null; } public override object[] GetCustomAttributes(System.Type attributeType, bool inherit) { throw null; } public override System.Type? GetElementType() { throw null; } public override System.Type GetEnumUnderlyingType() { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicEvents | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicEvents)] public override System.Reflection.EventInfo? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicEvents)] public override System.Reflection.EventInfo[] GetEvents() { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicEvents | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicEvents)] public override System.Reflection.EventInfo[] GetEvents(System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields)] public override System.Reflection.FieldInfo? GetField(string name, System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields)] public override System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingAttr) { throw null; } public override System.Type? GetInterface(string name, bool ignoreCase) { throw null; } public override System.Reflection.InterfaceMapping GetInterfaceMap(System.Type interfaceType) { throw null; } public override System.Type[] GetInterfaces() { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] public override System.Reflection.MemberInfo[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] public override System.Reflection.MemberInfo[] GetMembers(System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicMethods | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] protected override System.Reflection.MethodInfo? GetMethodImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, System.Reflection.CallingConventions callConvention, System.Type[]? types, System.Reflection.ParameterModifier[]? modifiers) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicMethods | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] public override System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicNestedTypes | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicNestedTypes)] public override System.Type? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicNestedTypes | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicNestedTypes)] public override System.Type[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicProperties | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] public override System.Reflection.PropertyInfo[] GetProperties(System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicProperties | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] protected override System.Reflection.PropertyInfo GetPropertyImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, System.Type? returnType, System.Type[]? types, System.Reflection.ParameterModifier[]? modifiers) { throw null; } protected override bool HasElementTypeImpl() { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] public override object? InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder? binder, object? target, object?[]? args, System.Reflection.ParameterModifier[]? modifiers, System.Globalization.CultureInfo? culture, string[]? namedParameters) { throw null; } protected override bool IsArrayImpl() { throw null; } protected override bool IsByRefImpl() { throw null; } @@ -201,15 +220,22 @@ internal GenericTypeParameterBuilder() { } public override System.Type UnderlyingSystemType { get { throw null; } } public override bool Equals(object? o) { throw null; } protected override System.Reflection.TypeAttributes GetAttributeFlagsImpl() { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] protected override System.Reflection.ConstructorInfo GetConstructorImpl(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, System.Reflection.CallingConventions callConvention, System.Type[] types, System.Reflection.ParameterModifier[]? modifiers) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] public override System.Reflection.ConstructorInfo[] GetConstructors(System.Reflection.BindingFlags bindingAttr) { throw null; } public override object[] GetCustomAttributes(bool inherit) { throw null; } public override object[] GetCustomAttributes(System.Type attributeType, bool inherit) { throw null; } public override System.Type GetElementType() { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicEvents | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicEvents)] public override System.Reflection.EventInfo GetEvent(string name, System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicEvents)] public override System.Reflection.EventInfo[] GetEvents() { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicEvents | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicEvents)] public override System.Reflection.EventInfo[] GetEvents(System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields)] public override System.Reflection.FieldInfo GetField(string name, System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields)] public override System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingAttr) { throw null; } public override System.Type[] GetGenericArguments() { throw null; } public override System.Type GetGenericTypeDefinition() { throw null; } @@ -217,15 +243,24 @@ internal GenericTypeParameterBuilder() { } public override System.Type GetInterface(string name, bool ignoreCase) { throw null; } public override System.Reflection.InterfaceMapping GetInterfaceMap(System.Type interfaceType) { throw null; } public override System.Type[] GetInterfaces() { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] public override System.Reflection.MemberInfo[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] public override System.Reflection.MemberInfo[] GetMembers(System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicMethods | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] protected override System.Reflection.MethodInfo GetMethodImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, System.Reflection.CallingConventions callConvention, System.Type[]? types, System.Reflection.ParameterModifier[]? modifiers) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicMethods | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] public override System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicNestedTypes | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicNestedTypes)] public override System.Type GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicNestedTypes | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicNestedTypes)] public override System.Type[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicProperties | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] public override System.Reflection.PropertyInfo[] GetProperties(System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicProperties | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] protected override System.Reflection.PropertyInfo GetPropertyImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, System.Type? returnType, System.Type[]? types, System.Reflection.ParameterModifier[]? modifiers) { throw null; } protected override bool HasElementTypeImpl() { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] public override object InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder? binder, object? target, object?[]? args, System.Reflection.ParameterModifier[]? modifiers, System.Globalization.CultureInfo? culture, string[]? namedParameters) { throw null; } protected override bool IsArrayImpl() { throw null; } public override bool IsAssignableFrom([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] System.Type? c) { throw null; } @@ -324,22 +359,35 @@ public void CreateGlobalFunctions() { } public override object[] GetCustomAttributes(bool inherit) { throw null; } public override object[] GetCustomAttributes(System.Type attributeType, bool inherit) { throw null; } public override System.Collections.Generic.IList GetCustomAttributesData() { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Fields might be removed")] public override System.Reflection.FieldInfo? GetField(string name, System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Fields might be removed")] public override System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingFlags) { throw null; } public override int GetHashCode() { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Fields might be removed")] public override System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingFlags) { throw null; } public override void GetPEKind(out System.Reflection.PortableExecutableKinds peKind, out System.Reflection.ImageFileMachine machine) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")] public override System.Type? GetType(string className) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")] public override System.Type? GetType(string className, bool ignoreCase) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")] public override System.Type? GetType(string className, bool throwOnError, bool ignoreCase) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Types might be removed")] public override System.Type[] GetTypes() { throw null; } public override bool IsDefined(System.Type attributeType, bool inherit) { throw null; } public override bool IsResource() { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Trimming changes metadata tokens")] public override System.Reflection.FieldInfo? ResolveField(int metadataToken, System.Type[]? genericTypeArguments, System.Type[]? genericMethodArguments) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Trimming changes metadata tokens")] public override System.Reflection.MemberInfo? ResolveMember(int metadataToken, System.Type[]? genericTypeArguments, System.Type[]? genericMethodArguments) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Trimming changes metadata tokens")] public override System.Reflection.MethodBase? ResolveMethod(int metadataToken, System.Type[]? genericTypeArguments, System.Type[]? genericMethodArguments) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Trimming changes metadata tokens")] public override byte[] ResolveSignature(int metadataToken) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Trimming changes metadata tokens")] public override string ResolveString(int metadataToken) { throw null; } + [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("Trimming changes metadata tokens")] public override System.Type ResolveType(int metadataToken, System.Type[]? genericTypeArguments, System.Type[]? genericMethodArguments) { throw null; } public void SetCustomAttribute(System.Reflection.ConstructorInfo con, byte[] binaryAttribute) { } public void SetCustomAttribute(System.Reflection.Emit.CustomAttributeBuilder customBuilder) { } @@ -440,32 +488,48 @@ public void DefineMethodOverride(System.Reflection.MethodInfo methodInfoBody, Sy public System.Reflection.Emit.FieldBuilder DefineUninitializedData(string name, int size, System.Reflection.FieldAttributes attributes) { throw null; } protected override System.Reflection.TypeAttributes GetAttributeFlagsImpl() { throw null; } public static System.Reflection.ConstructorInfo GetConstructor(System.Type type, System.Reflection.ConstructorInfo constructor) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] protected override System.Reflection.ConstructorInfo? GetConstructorImpl(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, System.Reflection.CallingConventions callConvention, System.Type[] types, System.Reflection.ParameterModifier[]? modifiers) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] public override System.Reflection.ConstructorInfo[] GetConstructors(System.Reflection.BindingFlags bindingAttr) { throw null; } public override object[] GetCustomAttributes(bool inherit) { throw null; } public override object[] GetCustomAttributes(System.Type attributeType, bool inherit) { throw null; } public override System.Type GetElementType() { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicEvents | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicEvents)] public override System.Reflection.EventInfo? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicEvents)] public override System.Reflection.EventInfo[] GetEvents() { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicEvents | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicEvents)] public override System.Reflection.EventInfo[] GetEvents(System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields)] public override System.Reflection.FieldInfo? GetField(string name, System.Reflection.BindingFlags bindingAttr) { throw null; } public static System.Reflection.FieldInfo GetField(System.Type type, System.Reflection.FieldInfo field) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields)] public override System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingAttr) { throw null; } public override System.Type[] GetGenericArguments() { throw null; } public override System.Type GetGenericTypeDefinition() { throw null; } public override System.Type? GetInterface(string name, bool ignoreCase) { throw null; } public override System.Reflection.InterfaceMapping GetInterfaceMap(System.Type interfaceType) { throw null; } public override System.Type[] GetInterfaces() { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] public override System.Reflection.MemberInfo[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] public override System.Reflection.MemberInfo[] GetMembers(System.Reflection.BindingFlags bindingAttr) { throw null; } public static System.Reflection.MethodInfo GetMethod(System.Type type, System.Reflection.MethodInfo method) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicMethods | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] protected override System.Reflection.MethodInfo? GetMethodImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, System.Reflection.CallingConventions callConvention, System.Type[]? types, System.Reflection.ParameterModifier[]? modifiers) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicMethods | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] public override System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicNestedTypes | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicNestedTypes)] public override System.Type? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicNestedTypes | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicNestedTypes)] public override System.Type[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicProperties | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] public override System.Reflection.PropertyInfo[] GetProperties(System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicProperties | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] protected override System.Reflection.PropertyInfo GetPropertyImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, System.Type? returnType, System.Type[]? types, System.Reflection.ParameterModifier[]? modifiers) { throw null; } protected override bool HasElementTypeImpl() { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] public override object? InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder? binder, object? target, object?[]? args, System.Reflection.ParameterModifier[]? modifiers, System.Globalization.CultureInfo? culture, string[]? namedParameters) { throw null; } protected override bool IsArrayImpl() { throw null; } public override bool IsAssignableFrom([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] System.Type? c) { throw null; } diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 8140f3c8fa4de2..212f8aa9feb67c 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -8152,16 +8152,27 @@ public InvalidFilterCriteriaException(string? message, System.Exception? inner) public partial interface IReflect { System.Type UnderlyingSystemType { get; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields)] System.Reflection.FieldInfo? GetField(string name, System.Reflection.BindingFlags bindingAttr); + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields)] System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingAttr); + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] System.Reflection.MemberInfo[] GetMember(string name, System.Reflection.BindingFlags bindingAttr); + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] System.Reflection.MemberInfo[] GetMembers(System.Reflection.BindingFlags bindingAttr); + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicMethods | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] System.Reflection.MethodInfo? GetMethod(string name, System.Reflection.BindingFlags bindingAttr); + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicMethods | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] System.Reflection.MethodInfo? GetMethod(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, System.Type[] types, System.Reflection.ParameterModifier[]? modifiers); + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicMethods | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingAttr); + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicProperties | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] System.Reflection.PropertyInfo[] GetProperties(System.Reflection.BindingFlags bindingAttr); + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicProperties | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] System.Reflection.PropertyInfo? GetProperty(string name, System.Reflection.BindingFlags bindingAttr); + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicProperties | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] System.Reflection.PropertyInfo? GetProperty(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, System.Type? returnType, System.Type[] types, System.Reflection.ParameterModifier[]? modifiers); + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] object? InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder? binder, object? target, object?[]? args, System.Reflection.ParameterModifier[]? modifiers, System.Globalization.CultureInfo? culture, string[]? namedParameters); } public partial interface IReflectableType @@ -8698,28 +8709,44 @@ public TypeDelegator([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers public override System.RuntimeTypeHandle TypeHandle { get { throw null; } } public override System.Type UnderlyingSystemType { get { throw null; } } protected override System.Reflection.TypeAttributes GetAttributeFlagsImpl() { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] protected override System.Reflection.ConstructorInfo? GetConstructorImpl(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, System.Reflection.CallingConventions callConvention, System.Type[] types, System.Reflection.ParameterModifier[]? modifiers) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicConstructors | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] public override System.Reflection.ConstructorInfo[] GetConstructors(System.Reflection.BindingFlags bindingAttr) { throw null; } public override object[] GetCustomAttributes(bool inherit) { throw null; } public override object[] GetCustomAttributes(System.Type attributeType, bool inherit) { throw null; } public override System.Type? GetElementType() { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicEvents | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicEvents)] public override System.Reflection.EventInfo? GetEvent(string name, System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicEvents)] public override System.Reflection.EventInfo[] GetEvents() { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicEvents | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicEvents)] public override System.Reflection.EventInfo[] GetEvents(System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields)] public override System.Reflection.FieldInfo? GetField(string name, System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicFields | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicFields)] public override System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingAttr) { throw null; } public override System.Type? GetInterface(string name, bool ignoreCase) { throw null; } public override System.Reflection.InterfaceMapping GetInterfaceMap(System.Type interfaceType) { throw null; } public override System.Type[] GetInterfaces() { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] public override System.Reflection.MemberInfo[] GetMember(string name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] public override System.Reflection.MemberInfo[] GetMembers(System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicMethods | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] protected override System.Reflection.MethodInfo? GetMethodImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, System.Reflection.CallingConventions callConvention, System.Type[]? types, System.Reflection.ParameterModifier[]? modifiers) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicMethods | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods)] public override System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicNestedTypes | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicNestedTypes)] public override System.Type? GetNestedType(string name, System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicNestedTypes | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicNestedTypes)] public override System.Type[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicProperties | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] public override System.Reflection.PropertyInfo[] GetProperties(System.Reflection.BindingFlags bindingAttr) { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicProperties | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicProperties)] protected override System.Reflection.PropertyInfo? GetPropertyImpl(string name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder? binder, System.Type? returnType, System.Type[]? types, System.Reflection.ParameterModifier[]? modifiers) { throw null; } protected override bool HasElementTypeImpl() { throw null; } + [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] public override object? InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder? binder, object? target, object?[]? args, System.Reflection.ParameterModifier[]? modifiers, System.Globalization.CultureInfo? culture, string[]? namedParameters) { throw null; } protected override bool IsArrayImpl() { throw null; } public override bool IsAssignableFrom([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] System.Reflection.TypeInfo? typeInfo) { throw null; } diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.Mono.cs index feedd6aded355b..845968fc6c0cf8 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/AssemblyBuilder.Mono.cs @@ -335,6 +335,7 @@ public ModuleBuilder DefineDynamicModule(string name, bool emitSymbolInfo) return null; } + [RequiresUnreferencedCode("Types might be removed")] public override Type[] GetExportedTypes() { throw not_supported(); @@ -476,6 +477,7 @@ internal Type MakeGenericType(Type gtd, Type[] typeArguments) return new TypeBuilderInstantiation(gtd, typeArguments); } + [RequiresUnreferencedCode("Types might be removed")] public override Type? GetType(string name, bool throwOnError, bool ignoreCase) { if (name == null) @@ -522,6 +524,7 @@ public override AssemblyName GetName(bool copiedName) return AssemblyName.Create(_mono_assembly, null); } + [RequiresUnreferencedCode("Assembly references might be removed")] public override AssemblyName[] GetReferencedAssemblies() => RuntimeAssembly.GetReferencedAssemblies (this); public override Module[] GetLoadedModules(bool getResourceModules) diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/DerivedTypes.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/DerivedTypes.Mono.cs index 6a72c177444a02..9c9130f1f52fc9 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/DerivedTypes.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/DerivedTypes.Mono.cs @@ -150,6 +150,7 @@ public override Guid GUID get { throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); } } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override object? InvokeMember(string name, BindingFlags invokeAttr, Binder? binder, object? target, object?[]? args, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParameters) { @@ -194,33 +195,39 @@ public override Type BaseType get { return typeof(System.Array); } } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] protected override ConstructorInfo? GetConstructorImpl(BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] protected override MethodInfo? GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] public override MethodInfo[] GetMethods(BindingFlags bindingAttr) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo GetField(string name, BindingFlags bindingAttr) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo[] GetFields(BindingFlags bindingAttr) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); @@ -236,42 +243,50 @@ public override Type[] GetInterfaces() throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo GetEvent(string name, BindingFlags bindingAttr) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents)] public override EventInfo[] GetEvents() { throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] protected override PropertyInfo? GetPropertyImpl(string name, BindingFlags bindingAttr, Binder? binder, Type? returnType, Type[]? types, ParameterModifier[]? modifiers) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type[] GetNestedTypes(BindingFlags bindingAttr) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type GetNestedType(string name, BindingFlags bindingAttr) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override MemberInfo[] GetMembers(BindingFlags bindingAttr) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); @@ -282,6 +297,7 @@ public override InterfaceMapping GetInterfaceMap(Type interfaceType) throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo[] GetEvents(BindingFlags bindingAttr) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.Mono.cs index 66a9cf4fd30fe4..ce8e677d417a63 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/EnumBuilder.Mono.cs @@ -224,6 +224,7 @@ protected override TypeAttributes GetAttributeFlagsImpl() return _tb.attrs; } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] protected override ConstructorInfo? GetConstructorImpl( BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[] types, ParameterModifier[]? modifiers) @@ -232,6 +233,7 @@ protected override TypeAttributes GetAttributeFlagsImpl() } [ComVisible(true)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) { return _tb.GetConstructors(bindingAttr); @@ -255,26 +257,31 @@ public override object[] GetCustomAttributes(Type attributeType, bool inherit) return _tb.GetElementType(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo? GetEvent(string name, BindingFlags bindingAttr) { return _tb.GetEvent(name, bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents)] public override EventInfo[] GetEvents() { return _tb.GetEvents(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo[] GetEvents(BindingFlags bindingAttr) { return _tb.GetEvents(bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo? GetField(string name, BindingFlags bindingAttr) { return _tb.GetField(name, bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo[] GetFields(BindingFlags bindingAttr) { return _tb.GetFields(bindingAttr); @@ -296,16 +303,19 @@ public override Type[] GetInterfaces() return _tb.GetInterfaces(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) { return _tb.GetMember(name, type, bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override MemberInfo[] GetMembers(BindingFlags bindingAttr) { return _tb.GetMembers(bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] protected override MethodInfo? GetMethodImpl( string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, @@ -320,26 +330,31 @@ public override MemberInfo[] GetMembers(BindingFlags bindingAttr) callConvention, types, modifiers); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] public override MethodInfo[] GetMethods(BindingFlags bindingAttr) { return _tb.GetMethods(bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type? GetNestedType(string name, BindingFlags bindingAttr) { return _tb.GetNestedType(name, bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type[] GetNestedTypes(BindingFlags bindingAttr) { return _tb.GetNestedTypes(bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) { return _tb.GetProperties(bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] protected override PropertyInfo? GetPropertyImpl( string name, BindingFlags bindingAttr, Binder? binder, Type? returnType, Type[]? types, @@ -353,6 +368,7 @@ protected override bool HasElementTypeImpl() return _tb.HasElementType; } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override object? InvokeMember( string name, BindingFlags invokeAttr, Binder? binder, object? target, object?[]? args, diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs index 74d3dac2dfa7e9..f6c73e84d7fee3 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs @@ -103,6 +103,7 @@ protected override TypeAttributes GetAttributeFlagsImpl() return TypeAttributes.Public; } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] protected override ConstructorInfo? GetConstructorImpl(BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, @@ -113,31 +114,37 @@ protected override TypeAttributes GetAttributeFlagsImpl() } [ComVisible(true)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) { throw not_supported(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo GetEvent(string name, BindingFlags bindingAttr) { throw not_supported(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents)] public override EventInfo[] GetEvents() { throw not_supported(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo[] GetEvents(BindingFlags bindingAttr) { throw not_supported(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo GetField(string name, BindingFlags bindingAttr) { throw not_supported(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo[] GetFields(BindingFlags bindingAttr) { throw not_supported(); @@ -153,21 +160,25 @@ public override Type[] GetInterfaces() throw not_supported(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override MemberInfo[] GetMembers(BindingFlags bindingAttr) { throw not_supported(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) { throw not_supported(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] public override MethodInfo[] GetMethods(BindingFlags bindingAttr) { throw not_supported(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] protected override MethodInfo? GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, @@ -176,21 +187,25 @@ public override MethodInfo[] GetMethods(BindingFlags bindingAttr) throw not_supported(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type GetNestedType(string name, BindingFlags bindingAttr) { throw not_supported(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type[] GetNestedTypes(BindingFlags bindingAttr) { throw not_supported(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) { throw not_supported(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] protected override PropertyInfo? GetPropertyImpl(string name, BindingFlags bindingAttr, Binder? binder, Type? returnType, Type[]? types, @@ -260,6 +275,7 @@ public override bool IsSZArray } } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override object? InvokeMember(string name, BindingFlags invokeAttr, Binder? binder, object? target, object?[]? args, ParameterModifier[]? modifiers, diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.Mono.cs index 1be005b6b8e516..cc430047f2c11a 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/ModuleBuilder.Mono.cs @@ -410,6 +410,7 @@ public EnumBuilder DefineEnum(string name, TypeAttributes visibility, Type under return result; } + [RequiresUnreferencedCode("Types might be removed")] [ComVisible(true)] public override Type? GetType(string className, bool throwOnError, bool ignoreCase) { @@ -525,6 +526,7 @@ public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) return null; } */ + [RequiresUnreferencedCode("Types might be removed")] public override Type[] GetTypes() { if (types == null) @@ -862,11 +864,13 @@ public override bool IsResource() return global_type_created.GetMethod(name, bindingAttr, binder, callConvention, types, modifiers); } + [RequiresUnreferencedCode("Trimming changes metadata tokens")] public override FieldInfo? ResolveField(int metadataToken, Type[]? genericTypeArguments, Type[]? genericMethodArguments) { return RuntimeModule.ResolveField(this, _impl, metadataToken, genericTypeArguments, genericMethodArguments); } + [RequiresUnreferencedCode("Trimming changes metadata tokens")] public override MemberInfo? ResolveMember(int metadataToken, Type[]? genericTypeArguments, Type[]? genericMethodArguments) { return RuntimeModule.ResolveMember(this, _impl, metadataToken, genericTypeArguments, genericMethodArguments); @@ -886,21 +890,25 @@ internal MemberInfo ResolveOrGetRegisteredToken(int metadataToken, Type[] generi return m; } + [RequiresUnreferencedCode("Trimming changes metadata tokens")] public override MethodBase? ResolveMethod(int metadataToken, Type[]? genericTypeArguments, Type[]? genericMethodArguments) { return RuntimeModule.ResolveMethod(this, _impl, metadataToken, genericTypeArguments, genericMethodArguments); } + [RequiresUnreferencedCode("Trimming changes metadata tokens")] public override string ResolveString(int metadataToken) { return RuntimeModule.ResolveString(this, _impl, metadataToken); } + [RequiresUnreferencedCode("Trimming changes metadata tokens")] public override byte[] ResolveSignature(int metadataToken) { return RuntimeModule.ResolveSignature(this, _impl, metadataToken); } + [RequiresUnreferencedCode("Trimming changes metadata tokens")] public override Type ResolveType(int metadataToken, Type[]? genericTypeArguments, Type[]? genericMethodArguments) { return RuntimeModule.ResolveType(this, _impl, metadataToken, genericTypeArguments, genericMethodArguments); diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.Mono.cs index 197a76f40e34d9..346c559144982a 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.Mono.cs @@ -987,6 +987,7 @@ internal void GenerateDebugInfo (ISymbolWriter symbolWriter) } */ [ComVisible(true)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) { if (is_created) @@ -1042,6 +1043,7 @@ public override Type GetElementType() throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo? GetEvent(string name, BindingFlags bindingAttr) { check_created(); @@ -1058,6 +1060,7 @@ public override EventInfo[] GetEvents() return GetEvents(DefaultBindingFlags); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo[] GetEvents(BindingFlags bindingAttr) { if (is_created) @@ -1065,12 +1068,14 @@ public override EventInfo[] GetEvents(BindingFlags bindingAttr) throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo? GetField(string name, BindingFlags bindingAttr) { check_created(); return created!.GetField(name, bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo[] GetFields(BindingFlags bindingAttr) { check_created(); @@ -1100,6 +1105,7 @@ public override Type[] GetInterfaces() } } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) { @@ -1107,6 +1113,7 @@ public override MemberInfo[] GetMember(string name, MemberTypes type, return created!.GetMember(name, type, bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override MemberInfo[] GetMembers(BindingFlags bindingAttr) { check_created(); @@ -1208,6 +1215,7 @@ private MethodInfo[] GetMethodsByName(string? name, BindingFlags bindingAttr, bo return result.ToArray(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] public override MethodInfo[] GetMethods(BindingFlags bindingAttr) { check_created(); @@ -1215,6 +1223,7 @@ public override MethodInfo[] GetMethods(BindingFlags bindingAttr) return GetMethodsByName(null, bindingAttr, false, this); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] protected override MethodInfo? GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, @@ -1228,6 +1237,7 @@ public override MethodInfo[] GetMethods(BindingFlags bindingAttr) return created!.GetMethod(name, bindingAttr, binder, callConvention, types, modifiers); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type? GetNestedType(string name, BindingFlags bindingAttr) { check_created(); @@ -1256,6 +1266,7 @@ public override MethodInfo[] GetMethods(BindingFlags bindingAttr) return null; } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type[] GetNestedTypes(BindingFlags bindingAttr) { if (!is_created) @@ -1286,12 +1297,14 @@ public override Type[] GetNestedTypes(BindingFlags bindingAttr) return result.ToArray(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) { check_created(); return created!.GetProperties(bindingAttr); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] protected override PropertyInfo? GetPropertyImpl(string name, BindingFlags bindingAttr, Binder? binder, Type? returnType, Type[]? types, ParameterModifier[]? modifiers) { throw not_supported(); @@ -1306,6 +1319,7 @@ protected override bool HasElementTypeImpl() return created!.HasElementType; } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override object? InvokeMember(string name, BindingFlags invokeAttr, Binder? binder, object? target, object?[]? args, ParameterModifier[]? modifiers, CultureInfo? culture, string[]? namedParameters) { check_created(); diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs index 88204f50ada936..86f847299ae415 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs @@ -200,31 +200,37 @@ internal override FieldInfo GetField(FieldInfo fromNoninstanciated) return fields[fromNoninstanciated]!; } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] public override MethodInfo[] GetMethods(BindingFlags bf) { throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] public override ConstructorInfo[] GetConstructors(BindingFlags bf) { throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo[] GetFields(BindingFlags bf) { throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] public override PropertyInfo[] GetProperties(BindingFlags bf) { throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo[] GetEvents(BindingFlags bf) { throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type[] GetNestedTypes(BindingFlags bf) { throw new NotSupportedException(); @@ -437,26 +443,31 @@ public override Type GetInterface(string name, bool ignoreCase) throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo GetEvent(string name, BindingFlags bindingAttr) { throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo GetField(string name, BindingFlags bindingAttr) { throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override MemberInfo[] GetMembers(BindingFlags bindingAttr) { throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type GetNestedType(string name, BindingFlags bindingAttr) { throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override object? InvokeMember(string name, BindingFlags invokeAttr, Binder? binder, object? target, object?[]? args, ParameterModifier[]? modifiers, @@ -465,6 +476,7 @@ public override Type GetNestedType(string name, BindingFlags bindingAttr) throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] protected override MethodInfo? GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers) @@ -472,12 +484,14 @@ public override Type GetNestedType(string name, BindingFlags bindingAttr) throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] protected override PropertyInfo? GetPropertyImpl(string name, BindingFlags bindingAttr, Binder? binder, Type? returnType, Type[]? types, ParameterModifier[]? modifiers) { throw new NotSupportedException(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] protected override ConstructorInfo? GetConstructorImpl(BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs index e1f386a4d2eae1..7154236a265eef 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs @@ -151,6 +151,7 @@ public override string Location [MethodImplAttribute(MethodImplOptions.InternalCall)] public extern override string[] GetManifestResourceNames(); + [RequiresUnreferencedCode("Types might be removed")] [MethodImplAttribute(MethodImplOptions.InternalCall)] public extern override Type[] GetExportedTypes(); @@ -253,6 +254,7 @@ public override AssemblyName GetName(bool copiedName) return AssemblyName.Create(_mono_assembly, CodeBase); } + [RequiresUnreferencedCode("Types might be removed")] public override Type GetType(string name, bool throwOnError, bool ignoreCase) { if (name == null) @@ -359,6 +361,7 @@ internal static AssemblyName[] GetReferencedAssemblies(Assembly assembly) } } + [RequiresUnreferencedCode("Assembly references might be removed")] public override AssemblyName[] GetReferencedAssemblies() => RuntimeAssembly.GetReferencedAssemblies (this); public override Assembly GetSatelliteAssembly(CultureInfo culture) diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs index 65f4f7278bb1ef..bc2b062df8d728 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs @@ -200,6 +200,7 @@ void GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine) GetPEKind(_impl, out peKind, out machine); } + [RequiresUnreferencedCode("Types might be removed")] public override Type GetType(string className, bool throwOnError, bool ignoreCase) { @@ -216,6 +217,7 @@ bool IsDefined(Type attributeType, bool inherit) return CustomAttribute.IsDefined(this, attributeType, inherit); } + [RequiresUnreferencedCode("Trimming changes metadata tokens")] public override FieldInfo ResolveField(int metadataToken, Type[]? genericTypeArguments, Type[]? genericMethodArguments) @@ -234,6 +236,7 @@ internal static FieldInfo ResolveField(Module module, IntPtr monoModule, int met return FieldInfo.GetFieldFromHandle(new RuntimeFieldHandle(handle)); } + [RequiresUnreferencedCode("Trimming changes metadata tokens")] public override MemberInfo ResolveMember(int metadataToken, Type[]? genericTypeArguments, Type[]? genericMethodArguments) @@ -252,6 +255,7 @@ internal static MemberInfo ResolveMember(Module module, IntPtr monoModule, int m return m; } + [RequiresUnreferencedCode("Trimming changes metadata tokens")] public override MethodBase ResolveMethod(int metadataToken, Type[]? genericTypeArguments, Type[]? genericMethodArguments) @@ -270,6 +274,7 @@ internal static MethodBase ResolveMethod(Module module, IntPtr monoModule, int m return RuntimeMethodInfo.GetMethodFromHandleNoGenericCheck(new RuntimeMethodHandle(handle)); } + [RequiresUnreferencedCode("Trimming changes metadata tokens")] public override string ResolveString(int metadataToken) @@ -288,6 +293,7 @@ internal static string ResolveString(Module module, IntPtr monoModule, int metad return s; } + [RequiresUnreferencedCode("Trimming changes metadata tokens")] public override Type ResolveType(int metadataToken, Type[]? genericTypeArguments, Type[]? genericMethodArguments) @@ -306,6 +312,7 @@ internal static Type ResolveType(Module module, IntPtr monoModule, int metadataT return Type.GetTypeFromHandle(new RuntimeTypeHandle(handle)); } + [RequiresUnreferencedCode("Trimming changes metadata tokens")] public override byte[] ResolveSignature(int metadataToken) @@ -324,6 +331,7 @@ internal static byte[] ResolveSignature(Module module, IntPtr monoModule, int me return res; } + [RequiresUnreferencedCode("Types might be removed")] public override Type[] GetTypes() { diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/RuntimeType.Mono.cs b/src/mono/netcore/System.Private.CoreLib/src/System/RuntimeType.Mono.cs index c665878637c35e..fdd6b9d36ccc69 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/RuntimeType.Mono.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/RuntimeType.Mono.cs @@ -737,37 +737,44 @@ private ListBuilder GetNestedTypeCandidates(string? fullname, BindingFlags #endregion #region Get All XXXInfos + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] public override MethodInfo[] GetMethods(BindingFlags bindingAttr) { return GetMethodCandidates(null, bindingAttr, CallingConventions.Any, null, -1, false).ToArray(); } [ComVisible(true)] + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) { return GetConstructorCandidates(null, bindingAttr, CallingConventions.Any, null, false).ToArray(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) { return GetPropertyCandidates(null, bindingAttr, null, false).ToArray(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo[] GetEvents(BindingFlags bindingAttr) { return GetEventCandidates(null, bindingAttr, false).ToArray(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo[] GetFields(BindingFlags bindingAttr) { return GetFieldCandidates(null, bindingAttr, false).ToArray(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type[] GetNestedTypes(BindingFlags bindingAttr) { return GetNestedTypeCandidates(null, bindingAttr, false).ToArray(); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override MemberInfo[] GetMembers(BindingFlags bindingAttr) { ListBuilder methods = GetMethodCandidates(null, bindingAttr, CallingConventions.Any, null, -1, false); @@ -843,6 +850,7 @@ public override MemberInfo[] GetMembers(BindingFlags bindingAttr) return binder.SelectMethod(bindingAttr, candidates.ToArray(), types, modifiers) as MethodInfo; } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] protected override ConstructorInfo? GetConstructorImpl( BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[] types, ParameterModifier[]? modifiers) @@ -872,7 +880,7 @@ public override MemberInfo[] GetMembers(BindingFlags bindingAttr) return binder.SelectMethod(bindingAttr, candidates.ToArray(), types, modifiers) as ConstructorInfo; } - + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)] protected override PropertyInfo? GetPropertyImpl( string name, BindingFlags bindingAttr, Binder? binder, Type? returnType, Type[]? types, ParameterModifier[]? modifiers) { @@ -912,6 +920,7 @@ public override MemberInfo[] GetMembers(BindingFlags bindingAttr) return binder.SelectProperty(bindingAttr, candidates.ToArray(), returnType, types, modifiers); } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicEvents | DynamicallyAccessedMemberTypes.NonPublicEvents)] public override EventInfo? GetEvent(string name, BindingFlags bindingAttr) { if (name == null) throw new ArgumentNullException(nameof(name)); @@ -940,6 +949,7 @@ public override MemberInfo[] GetMembers(BindingFlags bindingAttr) return match; } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] public override FieldInfo? GetField(string name, BindingFlags bindingAttr) { if (name == null) throw new ArgumentNullException(); @@ -1032,6 +1042,7 @@ public override MemberInfo[] GetMembers(BindingFlags bindingAttr) return match; } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.NonPublicNestedTypes)] public override Type? GetNestedType(string fullname, BindingFlags bindingAttr) { if (fullname == null) throw new ArgumentNullException(nameof(fullname)); @@ -1060,6 +1071,7 @@ public override MemberInfo[] GetMembers(BindingFlags bindingAttr) return match; } + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] public override MemberInfo[] GetMember(string name, MemberTypes type, BindingFlags bindingAttr) { if (name == null) throw new ArgumentNullException(nameof(name)); From 06700b4e81566a7285e3f184dc04d848ea81667b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Mon, 20 Jul 2020 14:57:09 +0200 Subject: [PATCH 027/458] Sync shared compiler file (#39164) --- ...ompiler.TypeSystem.ReadyToRun.Tests.csproj | 1 + ...eticVirtualOverrideTests.DiagnosticName.cs | 28 +++++++++++++++++++ .../SyntheticVirtualOverrideTests.cs | 12 ++------ 3 files changed, 31 insertions(+), 10 deletions(-) create mode 100644 src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SyntheticVirtualOverrideTests.DiagnosticName.cs diff --git a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ILCompiler.TypeSystem.ReadyToRun.Tests.csproj b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ILCompiler.TypeSystem.ReadyToRun.Tests.csproj index c65d2b0b54dd55..7567ab173f5db3 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ILCompiler.TypeSystem.ReadyToRun.Tests.csproj +++ b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/ILCompiler.TypeSystem.ReadyToRun.Tests.csproj @@ -47,6 +47,7 @@ + diff --git a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SyntheticVirtualOverrideTests.DiagnosticName.cs b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SyntheticVirtualOverrideTests.DiagnosticName.cs new file mode 100644 index 00000000000000..0ffbdd8a4c0a09 --- /dev/null +++ b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SyntheticVirtualOverrideTests.DiagnosticName.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.Collections.Generic; +using System.Linq; + +using Internal.TypeSystem; + +using Xunit; + + +namespace TypeSystemTests +{ + public partial class SyntheticVirtualOverrideTests + { + private partial class SyntheticMethod : MethodDesc + { + public override string DiagnosticName + { + get + { + return _name; + } + } + } + } +} diff --git a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SyntheticVirtualOverrideTests.cs b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SyntheticVirtualOverrideTests.cs index 11e0741684899d..9fc3b9bf7d0d0b 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SyntheticVirtualOverrideTests.cs +++ b/src/coreclr/src/tools/aot/ILCompiler.TypeSystem.ReadyToRun.Tests/SyntheticVirtualOverrideTests.cs @@ -12,7 +12,7 @@ namespace TypeSystemTests { - public class SyntheticVirtualOverrideTests + public partial class SyntheticVirtualOverrideTests { TestTypeSystemContext _context; ModuleDesc _testModule; @@ -155,7 +155,7 @@ protected override IEnumerable GetAllMethods(TypeDesc type) } } - private class SyntheticMethod : MethodDesc + private partial class SyntheticMethod : MethodDesc { private TypeDesc _owningType; private MethodSignature _signature; @@ -205,14 +205,6 @@ public override string Name } } - public override string DiagnosticName - { - get - { - return _name; - } - } - public override TypeDesc OwningType { get From 628d99b624f338b0eaca031adc50952b4c2d509d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marie=20P=C3=ADchov=C3=A1?= <11718369+ManickaP@users.noreply.github.com> Date: Mon, 20 Jul 2020 15:57:16 +0200 Subject: [PATCH 028/458] Properly map exceptions from NetworkStream ctor. (#39514) --- .../src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs index 31b33df8c6b36d..48d530c2a03e54 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/ConnectHelper.cs @@ -96,14 +96,14 @@ private static Stream Connect(string host, int port, CancellationToken cancellat { socket.Connect(new DnsEndPoint(host, port)); } + + return new NetworkStream(socket, ownsSocket: true); } catch (Exception e) { socket.Dispose(); throw CreateWrappedException(e, host, port, cancellationToken); } - - return new NetworkStream(socket, ownsSocket: true); } /// SocketAsyncEventArgs that carries with it additional state for a Task builder and a CancellationToken. From 867ad8d20402e3bee580e0af6577f87912103c78 Mon Sep 17 00:00:00 2001 From: Thays Grazia Date: Mon, 20 Jul 2020 11:22:56 -0300 Subject: [PATCH 029/458] [wasm][debugger] Don't download unnecessary assemblies to DebugProxy (#39530) Don't download unnecessary assemblies to DebugProxy --- src/mono/wasm/runtime/driver.c | 6 ++++-- src/mono/wasm/runtime/library_mono.js | 19 ++++++++++++++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/mono/wasm/runtime/driver.c b/src/mono/wasm/runtime/driver.c index e4456ee6b59583..32383d7c9bc5d0 100644 --- a/src/mono/wasm/runtime/driver.c +++ b/src/mono/wasm/runtime/driver.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -137,7 +138,7 @@ struct WasmAssembly_ { static WasmAssembly *assemblies; static int assembly_count; -EMSCRIPTEN_KEEPALIVE void +EMSCRIPTEN_KEEPALIVE int mono_wasm_add_assembly (const char *name, const unsigned char *data, unsigned int size) { int len = strlen (name); @@ -146,7 +147,7 @@ mono_wasm_add_assembly (const char *name, const unsigned char *data, unsigned in //FIXME handle debugging assemblies with .exe extension strcpy (&new_name [len - 3], "dll"); mono_register_symfile_for_assembly (new_name, data, size); - return; + return 1; } WasmAssembly *entry = g_new0 (WasmAssembly, 1); entry->assembly.name = strdup (name); @@ -155,6 +156,7 @@ mono_wasm_add_assembly (const char *name, const unsigned char *data, unsigned in entry->next = assemblies; assemblies = entry; ++assembly_count; + return mono_has_pdb_checksum (data, size); } EMSCRIPTEN_KEEPALIVE void diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index e137e8940a0c82..b1be6e6bc6b419 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -601,7 +601,7 @@ var MonoSupportLib = { switch (asset.behavior) { case "assembly": - ctx.loaded_files.push (url); + ctx.loaded_files.push ({ url: url, file: virtualName}); case "heap": case "icu": offset = this.mono_wasm_load_bytes_into_heap (bytes); @@ -645,8 +645,14 @@ var MonoSupportLib = { throw new Error ("Unrecognized asset behavior:", asset.behavior, "for asset", asset.name); } - if (asset.behavior === "assembly") - ctx.mono_wasm_add_assembly (virtualName, offset, bytes.length); + if (asset.behavior === "assembly") { + var hasPpdb = ctx.mono_wasm_add_assembly (virtualName, offset, bytes.length); + + if (!hasPpdb) { + var index = ctx.loaded_files.findIndex(element => element.file == virtualName); + ctx.loaded_files.splice(index, 1); + } + } else if (asset.behavior === "icu") { if (this.mono_wasm_load_icu_data (offset)) ctx.num_icu_assets_loaded_successfully += 1; @@ -753,8 +759,11 @@ var MonoSupportLib = { }, _finalize_startup: function (args, ctx) { + var loaded_files_with_debug_info = []; + MONO.loaded_assets = ctx.loaded_assets; - MONO.loaded_files = ctx.loaded_files; + ctx.loaded_files.forEach(value => loaded_files_with_debug_info.push(value.url)); + MONO.loaded_files = loaded_files_with_debug_info; if (ctx.tracing) { console.log ("MONO_WASM: loaded_assets: " + JSON.stringify(ctx.loaded_assets)); console.log ("MONO_WASM: loaded_files: " + JSON.stringify(ctx.loaded_files)); @@ -799,7 +808,7 @@ var MonoSupportLib = { var ctx = { tracing: args.diagnostic_tracing || false, pending_count: args.assets.length, - mono_wasm_add_assembly: Module.cwrap ('mono_wasm_add_assembly', null, ['string', 'number', 'number']), + mono_wasm_add_assembly: Module.cwrap ('mono_wasm_add_assembly', 'number', ['string', 'number', 'number']), loaded_assets: Object.create (null), // dlls and pdbs, used by blazor and the debugger loaded_files: [], From 945beee7efff52decf353a022ba85a6aebf386e7 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Mon, 20 Jul 2020 11:40:17 -0500 Subject: [PATCH 030/458] [wasm] Include data archives and timezone data by default (#39586) * Add data archive loading to the generic loading logic --- eng/testing/tests.mobile.targets | 2 +- src/mono/wasm/runtime-test.js | 23 -------- src/mono/wasm/runtime/library_mono.js | 52 +++++++++++-------- .../WasmAppBuilder/WasmAppBuilder.cs | 2 +- 4 files changed, 33 insertions(+), 46 deletions(-) diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets index 266a6d37be6518..284ae301d88880 100644 --- a/eng/testing/tests.mobile.targets +++ b/eng/testing/tests.mobile.targets @@ -14,7 +14,7 @@ - $HARNESS_RUNNER wasm test --engine=$(JSEngine) $(JSEngineArgs) --js-file=runtime.js -v --output-directory=$XHARNESS_OUT -- --enable-zoneinfo --run WasmTestRunner.dll $(AssemblyName).dll + $HARNESS_RUNNER wasm test --engine=$(JSEngine) $(JSEngineArgs) --js-file=runtime.js -v --output-directory=$XHARNESS_OUT -- --run WasmTestRunner.dll $(AssemblyName).dll diff --git a/src/mono/wasm/runtime-test.js b/src/mono/wasm/runtime-test.js index b63c8fc6ca3e0b..a2a66b6f85f626 100644 --- a/src/mono/wasm/runtime-test.js +++ b/src/mono/wasm/runtime-test.js @@ -130,9 +130,6 @@ while (true) { } else if (args [0] == "--disable-on-demand-gc") { enable_gc = false; args = args.slice (1); - } else if (args [0] == "--enable-zoneinfo") { - enable_zoneinfo = true; - args = args.slice (1); } else { break; } @@ -173,26 +170,6 @@ var Module = { if (!enable_gc) { Module.ccall ('mono_wasm_enable_on_demand_gc', 'void', ['number'], [0]); } - if (enable_zoneinfo) { - // The timezone file is generated by https://github.com/dotnet/blazor/tree/master/src/TimeZoneData. - // The file format of the TZ file look like so - // - // [4-byte magic number] - // [4 - byte length of manifest] - // [json manifest] - // [data bytes] - // - // The json manifest is an array that looks like so: - // - // [...["America/Fort_Nelson",2249],["America/Glace_Bay",2206]..] - // - // where the first token in each array is the relative path of the file on disk, and the second is the - // length of the file. The starting offset of a file can be calculated using the lengths of all files - // that appear prior to it. - var zonedata = new Uint8Array(read ("dotnet.timezones.blat", "binary")); - MONO.mono_wasm_load_data (zonedata, "/usr/share/zoneinfo"); - } - config.loaded_cb = function () { App.init (); diff --git a/src/mono/wasm/runtime/library_mono.js b/src/mono/wasm/runtime/library_mono.js index b1be6e6bc6b419..f47c0f8ec6db5b 100644 --- a/src/mono/wasm/runtime/library_mono.js +++ b/src/mono/wasm/runtime/library_mono.js @@ -619,7 +619,6 @@ var MonoSupportLib = { : virtualName; if (fileName.startsWith("/")) fileName = fileName.substr(1); - if (parentDirectory) { if (ctx.tracing) console.log ("MONO_WASM: Creating directory '" + parentDirectory + "'"); @@ -634,11 +633,12 @@ var MonoSupportLib = { if (ctx.tracing) console.log ("MONO_WASM: Creating file '" + fileName + "' in directory '" + parentDirectory + "'"); - var fileRet = ctx.createDataFile ( - parentDirectory, fileName, - bytes, true /* canRead */, true /* canWrite */, true /* canOwn */ - ); - + if (!this.mono_wasm_load_data_archive (bytes, parentDirectory)) { + var fileRet = ctx.createDataFile ( + parentDirectory, fileName, + bytes, true /* canRead */, true /* canWrite */, true /* canOwn */ + ); + } break; default: @@ -1110,16 +1110,30 @@ var MonoSupportLib = { return className.replace(/\//g, '.').replace(/`\d+/g, ''); }, - mono_wasm_load_data: function (data, prefix) { + mono_wasm_load_data_archive: function (data, prefix) { + if (data.length < 8) + return false; + var dataview = new DataView(data.buffer); var magic = dataview.getUint32(0, true); // get magic number if (magic != 0x626c6174) { - throw new Error ("File is of wrong type"); + return false; } var manifestSize = dataview.getUint32(4, true); - var manifestContent = Module.UTF8ArrayToString(data, 8, manifestSize); - var manifest = JSON.parse(manifestContent); + if (manifestSize == 0 || data.length < manifestSize + 8) + return false; + + var manifest; + try { + manifestContent = Module.UTF8ArrayToString(data, 8, manifestSize); + manifest = JSON.parse(manifestContent); + if (!(manifest instanceof Array)) + return false; + } catch (exc) { + return false; + } + data = data.slice(manifestSize+8); // Create the folder structure @@ -1127,18 +1141,13 @@ var MonoSupportLib = { // /usr/share/zoneinfo/Africa // /usr/share/zoneinfo/Asia // .. - var p = prefix.slice(1).split('/'); - p.forEach((v, i) => { - FS.mkdir(v); - Module['FS_createPath']("/" + p.slice(0, i).join('/'), v, true, true); - }) + var folders = new Set() manifest.filter(m => { - m = m[0].split('/') - if (m!= null) { - if (m.length > 2) folders.add(m.slice(0,m.length-1).join('/')); - folders.add(m[0]); - } + var file = m[0]; + var last = file.lastIndexOf ("/"); + var directory = file.slice (0, last); + folders.add(directory); }); folders.forEach(folder => { Module['FS_createPath'](prefix, folder, true, true); @@ -1148,9 +1157,10 @@ var MonoSupportLib = { var name = row[0]; var length = row[1]; var bytes = data.slice(0, length); - Module['FS_createDataFile'](`${prefix}/${name}`, null, bytes, true, true); + Module['FS_createDataFile'](prefix, name, bytes, true, true); data = data.slice(length); } + return true; } }, diff --git a/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs b/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs index 9a5d51cea5ccf4..668d4efeffc5c0 100644 --- a/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs +++ b/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs @@ -121,7 +121,7 @@ public override bool Execute () var sEnableRemote = enableRemote ? "true" : "false"; sw.WriteLine($"\t\t{{ behavior: \"icu\", name: \"icudt.dat\", load_remote: {sEnableRemote} }},"); - + sw.WriteLine($"\t\t{{ behavior: \"vfs\", name: \"dotnet.timezones.blat\", virtual_path: \"/usr/share/zoneinfo/\" }}"); sw.WriteLine ("\t],"); if (enableRemote) { From a366d638d880823ad63d28c22ddee0aeafbbcfc1 Mon Sep 17 00:00:00 2001 From: Mitchell Hwang Date: Mon, 20 Jul 2020 12:52:02 -0400 Subject: [PATCH 031/458] [wasm] Sort Assembly List in WASM Apps (#39374) Co-authored-by: Mitchell Hwang --- .../tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs b/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs index 668d4efeffc5c0..c16e13d1a0073c 100644 --- a/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs +++ b/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs @@ -31,7 +31,7 @@ public class WasmAppBuilder : Task public ITaskItem[]? FilesToIncludeInFileSystem { get; set; } public ITaskItem[]? RemoteSources { get; set; } - Dictionary? _assemblies; + SortedDictionary? _assemblies; Resolver? _resolver; public override bool Execute () @@ -42,7 +42,7 @@ public override bool Execute () throw new ArgumentException($"File MainJS='{MainJS}' doesn't exist."); var paths = new List(); - _assemblies = new Dictionary(); + _assemblies = new SortedDictionary(); // Collect and load assemblies used by the app foreach (var v in AssemblySearchPaths!) From 0655692a6db0734b6d08598cb056bd0b50f57fde Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Mon, 20 Jul 2020 21:38:01 +0300 Subject: [PATCH 032/458] [mono] Update ICU version, disable some tests for Browser (#39596) --- eng/Version.Details.xml | 4 +- eng/Versions.props | 2 +- .../CultureInfo/CultureInfoEnglishName.cs | 14 +++++- .../CultureInfo/CultureInfoNativeName.cs | 14 +++++- .../DateTimeFormatInfoTests.cs | 7 ++- .../NumberFormatInfoNumberGroupSizes.cs | 4 +- .../System/Globalization/RegionInfoTests.cs | 45 ++++++++++++++++--- 7 files changed, 73 insertions(+), 17 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 098240ee26cbd9..0d7aad96f5897b 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -4,9 +4,9 @@ https://github.com/dotnet/standard cfe95a23647c7de1fe1a349343115bd7720d6949 - + https://github.com/dotnet/icu - 7247fa0d9e8faee2cceee6f04856b2c447f41bca + 797c523dd8d75096319f3591958f703b8d74d04b diff --git a/eng/Versions.props b/eng/Versions.props index 8366710273c7d5..94c0d597cd5715 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -118,7 +118,7 @@ 5.0.0-preview.3.20363.5 - 5.0.0-preview.8.20365.1 + 5.0.0-preview.8.20370.1 9.0.1-alpha.1.20356.1 9.0.1-alpha.1.20356.1 diff --git a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoEnglishName.cs b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoEnglishName.cs index 23c2032c51cd41..fdb6e4b189fcee 100644 --- a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoEnglishName.cs +++ b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoEnglishName.cs @@ -11,8 +11,18 @@ public class CultureInfoEnglishName public static IEnumerable EnglishName_TestData() { yield return new object[] { CultureInfo.CurrentCulture.Name, CultureInfo.CurrentCulture.EnglishName }; - yield return new object[] { "en-US", "English (United States)" }; - yield return new object[] { "fr-FR", "French (France)" }; + + if (PlatformDetection.IsNotBrowser) + { + yield return new object[] { "en-US", "English (United States)" }; + yield return new object[] { "fr-FR", "French (France)" }; + } + else + { + // Browser's ICU doesn't contain CultureInfo.EnglishName + yield return new object[] { "en-US", "en (US)" }; + yield return new object[] { "fr-FR", "fr (FR)" }; + } } [Theory] diff --git a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoNativeName.cs b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoNativeName.cs index b97a645b8b2a57..58429b132138cc 100644 --- a/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoNativeName.cs +++ b/src/libraries/System.Globalization/tests/CultureInfo/CultureInfoNativeName.cs @@ -11,8 +11,18 @@ public class CultureInfoNativeName public static IEnumerable NativeName_TestData() { yield return new object[] { CultureInfo.CurrentCulture.Name, CultureInfo.CurrentCulture.NativeName }; - yield return new object[] { "en-US", "English (United States)" }; - yield return new object[] { "en-CA", "English (Canada)" }; + + if (PlatformDetection.IsNotBrowser) + { + yield return new object[] { "en-US", "English (United States)" }; + yield return new object[] { "en-CA", "English (Canada)" }; + } + else + { + // Browser's ICU doesn't contain CultureInfo.NativeName + yield return new object[] { "en-US", "en (US)" }; + yield return new object[] { "en-CA", "en (CA)" }; + } } [Theory] diff --git a/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs b/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs index 1689c9e312d2db..52cda26a787aef 100644 --- a/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs +++ b/src/libraries/System.Globalization/tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs @@ -66,7 +66,12 @@ public void NativeCalendarName_Get_ReturnsExpected(DateTimeFormatInfo dtfi, Cale try { dtfi.Calendar = calendar; - Assert.Equal(nativeCalendarName, dtfi.NativeCalendarName); + + if (PlatformDetection.IsNotBrowser) + { + // Browser's ICU doesn't contain NativeCalendarName, + Assert.Equal(nativeCalendarName, dtfi.NativeCalendarName); + } } catch { diff --git a/src/libraries/System.Globalization/tests/NumberFormatInfo/NumberFormatInfoNumberGroupSizes.cs b/src/libraries/System.Globalization/tests/NumberFormatInfo/NumberFormatInfoNumberGroupSizes.cs index 045d3e0b585be7..62ae02d3aa4a4c 100644 --- a/src/libraries/System.Globalization/tests/NumberFormatInfo/NumberFormatInfoNumberGroupSizes.cs +++ b/src/libraries/System.Globalization/tests/NumberFormatInfo/NumberFormatInfoNumberGroupSizes.cs @@ -13,8 +13,8 @@ public static IEnumerable NumberGroupSizes_TestData() yield return new object[] { NumberFormatInfo.InvariantInfo, new int[] { 3 } }; yield return new object[] { CultureInfo.GetCultureInfo("en-US").NumberFormat, new int[] { 3 } }; - // Culture does not exist on Windows 7 - if (!PlatformDetection.IsWindows7) + // Culture does not exist on Windows 7 and in Browser's ICU + if (!PlatformDetection.IsWindows7 && PlatformDetection.IsNotBrowser) { yield return new object[] { CultureInfo.GetCultureInfo("ur-IN").NumberFormat, NumberFormatInfoData.UrINNumberGroupSizes() }; } diff --git a/src/libraries/System.Globalization/tests/System/Globalization/RegionInfoTests.cs b/src/libraries/System.Globalization/tests/System/Globalization/RegionInfoTests.cs index dd99a40e94ca83..2cb86dc56da24c 100644 --- a/src/libraries/System.Globalization/tests/System/Globalization/RegionInfoTests.cs +++ b/src/libraries/System.Globalization/tests/System/Globalization/RegionInfoTests.cs @@ -90,20 +90,51 @@ public void DisplayName(string name, string expected) } } + public static IEnumerable NativeName_TestData() + { + if (PlatformDetection.IsNotBrowser) + { + yield return new object[] { "GB", "United Kingdom" }; + yield return new object[] { "SE", "Sverige" }; + yield return new object[] { "FR", "France" }; + } + else + { + // Browser's ICU doesn't contain RegionInfo.NativeName + yield return new object[] { "GB", "GB" }; + yield return new object[] { "SE", "SE" }; + yield return new object[] { "FR", "FR" }; + } + } + [Theory] - [InlineData("GB", "United Kingdom")] - [InlineData("SE", "Sverige")] - [InlineData("FR", "France")] + [MemberData(nameof(NativeName_TestData))] public void NativeName(string name, string expected) { Assert.Equal(expected, new RegionInfo(name).NativeName); } + public static IEnumerable EnglishName_TestData() + { + if (PlatformDetection.IsNotBrowser) + { + yield return new object[] { "en-US", new string[] { "United States" } }; + yield return new object[] { "US", new string[] { "United States" } }; + yield return new object[] { "zh-CN", new string[] { "China", "People's Republic of China", "China mainland" }}; + yield return new object[] { "CN", new string[] { "China", "People's Republic of China", "China mainland" } }; + } + else + { + // Browser's ICU doesn't contain RegionInfo.EnglishName + yield return new object[] { "en-US", new string[] { "US" } }; + yield return new object[] { "US", new string[] { "US" } }; + yield return new object[] { "zh-CN", new string[] { "CN" }}; + yield return new object[] { "CN", new string[] { "CN" } }; + } + } + [Theory] - [InlineData("en-US", new string[] { "United States" })] - [InlineData("US", new string[] { "United States" })] - [InlineData("zh-CN", new string[] { "China", "People's Republic of China", "China mainland" })] - [InlineData("CN", new string[] { "China", "People's Republic of China", "China mainland" })] + [MemberData(nameof(EnglishName_TestData))] public void EnglishName(string name, string[] expected) { string result = new RegionInfo(name).EnglishName; From d8d4d9ef0e67e7bbac454faef4b1413b8e011635 Mon Sep 17 00:00:00 2001 From: David Cantu Date: Mon, 20 Jul 2020 11:39:32 -0700 Subject: [PATCH 033/458] Create and add instance reference inside ResolveMetadata* (#39330) * Create and add instance reference on ResolveMetadata * Address suggestions --- .../Collection/DictionaryDefaultConverter.cs | 17 +- .../Collection/IEnumerableDefaultConverter.cs | 41 +--- .../Collection/IEnumerableOfTConverter.cs | 2 +- .../Object/ObjectDefaultConverter.cs | 22 +- .../Text/Json/Serialization/JsonConverter.cs | 5 + .../JsonSerializer.Read.HandleMetadata.cs | 227 ++++++++++++++---- .../JsonSerializer.Write.HandleMetadata.cs | 4 +- .../Text/Json/Serialization/ReadStackFrame.cs | 6 +- .../Text/Json/ThrowHelper.Serialization.cs | 16 +- 9 files changed, 220 insertions(+), 120 deletions(-) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs index cd20a06206db83..c992d01eefb1ea 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs @@ -137,7 +137,7 @@ internal sealed override bool OnTryRead( bool preserveReferences = options.ReferenceHandler != null; if (preserveReferences && state.Current.ObjectState < StackFrameObjectState.PropertyValue) { - if (JsonSerializer.ResolveMetadata(this, ref reader, ref state)) + if (JsonSerializer.ResolveMetadataForJsonObject(ref reader, ref state, options)) { if (state.Current.ObjectState == StackFrameObjectState.ReadRefEndObject) { @@ -156,18 +156,6 @@ internal sealed override bool OnTryRead( if (state.Current.ObjectState < StackFrameObjectState.CreatedObject) { CreateCollection(ref reader, ref state); - - if (state.Current.MetadataId != null) - { - Debug.Assert(CanHaveIdMetadata); - - value = (TCollection)state.Current.ReturnValue!; - state.ReferenceResolver.AddReference(state.Current.MetadataId, value); - // Clear metadata name, if the next read fails - // we want to point the JSON path to the property's object. - state.Current.JsonPropertyName = null; - } - state.Current.ObjectState = StackFrameObjectState.CreatedObject; } @@ -308,5 +296,8 @@ internal sealed override bool OnTryWrite( return success; } + + internal sealed override void CreateInstanceForReferenceResolver(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) + => CreateCollection(ref reader, ref state); } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableDefaultConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableDefaultConverter.cs index dbe43be8bdc808..e59b4c8f95bee1 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableDefaultConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableDefaultConverter.cs @@ -113,7 +113,7 @@ internal override bool OnTryRead( // Handle the metadata properties. if (preserveReferences && state.Current.ObjectState < StackFrameObjectState.PropertyValue) { - if (JsonSerializer.ResolveMetadata(this, ref reader, ref state)) + if (JsonSerializer.ResolveMetadataForJsonArray(ref reader, ref state, options)) { if (state.Current.ObjectState == StackFrameObjectState.ReadRefEndObject) { @@ -131,23 +131,6 @@ internal override bool OnTryRead( if (state.Current.ObjectState < StackFrameObjectState.CreatedObject) { CreateCollection(ref reader, ref state, options); - - if (state.Current.MetadataId != null) - { - value = (TCollection)state.Current.ReturnValue!; - - // TODO: https://github.com/dotnet/runtime/issues/37168 - //Separate logic for IEnumerable to call AddReference when the reader is at `$id`, in order to avoid remembering the last metadata. - - // Remember the prior metadata and temporarily use '$id' to write it in the path in case AddReference throws - // in this case, the last property seen will be '$values' when we reach this point. - byte[]? lastMetadataProperty = state.Current.JsonPropertyName; - state.Current.JsonPropertyName = JsonSerializer.s_idPropertyName; - - state.ReferenceResolver.AddReference(state.Current.MetadataId, value); - state.Current.JsonPropertyName = lastMetadataProperty; - } - state.Current.JsonPropertyInfo = state.Current.JsonClassInfo.ElementClassInfo!.PropertyInfoForClassInfo; state.Current.ObjectState = StackFrameObjectState.CreatedObject; } @@ -203,34 +186,25 @@ internal override bool OnTryRead( { state.Current.ObjectState = StackFrameObjectState.EndToken; - // Read the EndObject for $values. - if (state.Current.MetadataId != null) + // Read the EndObject token for an array with preserve semantics. + if (state.Current.ValidateEndTokenOnArray) { if (!reader.Read()) { value = default; return false; } - - if (reader.TokenType != JsonTokenType.EndObject) - { - if (reader.TokenType == JsonTokenType.PropertyName) - { - state.Current.JsonPropertyName = reader.GetSpan().ToArray(); - } - - ThrowHelper.ThrowJsonException_MetadataPreservedArrayInvalidProperty(typeToConvert, reader); - } } } if (state.Current.ObjectState < StackFrameObjectState.EndTokenValidation) { - if (state.Current.MetadataId != null) + if (state.Current.ValidateEndTokenOnArray) { if (reader.TokenType != JsonTokenType.EndObject) { - ThrowHelper.ThrowJsonException_MetadataPreservedArrayInvalidProperty(typeToConvert, reader); + Debug.Assert(reader.TokenType == JsonTokenType.PropertyName); + ThrowHelper.ThrowJsonException_MetadataPreservedArrayInvalidProperty(ref state, typeToConvert, reader); } } } @@ -299,5 +273,8 @@ internal sealed override bool OnTryWrite( } protected abstract bool OnWriteResume(Utf8JsonWriter writer, TCollection value, JsonSerializerOptions options, ref WriteStack state); + + internal sealed override void CreateInstanceForReferenceResolver(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) + => CreateCollection(ref reader, ref state, options); } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableOfTConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableOfTConverter.cs index 23c0e958fe0476..d4a3738f2f5968 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableOfTConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableOfTConverter.cs @@ -18,7 +18,7 @@ protected override void Add(in TElement value, ref ReadStack state) ((List)state.Current.ReturnValue!).Add(value); } - protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) + protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) { if (!TypeToConvert.IsAssignableFrom(RuntimeType)) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectDefaultConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectDefaultConverter.cs index 25bbcb0dc103a5..008e9ad3eb54c8 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectDefaultConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectDefaultConverter.cs @@ -77,7 +77,7 @@ internal override bool OnTryRead(ref Utf8JsonReader reader, Type typeToConvert, { if (options.ReferenceHandler != null) { - if (JsonSerializer.ResolveMetadata(this, ref reader, ref state)) + if (JsonSerializer.ResolveMetadataForJsonObject(ref reader, ref state, options)) { if (state.Current.ObjectState == StackFrameObjectState.ReadRefEndObject) { @@ -91,8 +91,6 @@ internal override bool OnTryRead(ref Utf8JsonReader reader, Type typeToConvert, return false; } } - - state.Current.ObjectState = StackFrameObjectState.PropertyValue; } if (state.Current.ObjectState < StackFrameObjectState.CreatedObject) @@ -103,13 +101,6 @@ internal override bool OnTryRead(ref Utf8JsonReader reader, Type typeToConvert, } obj = state.Current.JsonClassInfo.CreateObject!()!; - if (state.Current.MetadataId != null) - { - state.ReferenceResolver.AddReference(state.Current.MetadataId, obj); - // Clear metadata name, if the next read fails - // we want to point the JSON path to the property's object. - state.Current.JsonPropertyName = null; - } state.Current.ReturnValue = obj; state.Current.ObjectState = StackFrameObjectState.CreatedObject; @@ -416,5 +407,16 @@ protected bool ReadAheadPropertyValue(ref ReadStack state, ref Utf8JsonReader re return true; } + + internal sealed override void CreateInstanceForReferenceResolver(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) + { + if (state.Current.JsonClassInfo.CreateObject == null) + { + ThrowHelper.ThrowNotSupportedException_DeserializeNoConstructor(state.Current.JsonClassInfo.Type, ref reader, ref state); + } + + object obj = state.Current.JsonClassInfo.CreateObject!()!; + state.Current.ReturnValue = obj; + } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverter.cs index b2c34e14599a1d..b775aec8c85ce7 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverter.cs @@ -81,5 +81,10 @@ internal bool ShouldFlush(Utf8JsonWriter writer, ref WriteStack state) internal ConstructorInfo? ConstructorInfo { get; set; } internal virtual void Initialize(JsonSerializerOptions options) { } + + /// + /// Creates the instance and assigns it to state.Current.ReturnValue. + /// + internal virtual void CreateInstanceForReferenceResolver(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options) { } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleMetadata.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleMetadata.cs index 26a2fb116088f0..2fd7942ddc914e 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleMetadata.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandleMetadata.cs @@ -12,18 +12,24 @@ public static partial class JsonSerializer internal static readonly byte[] s_idPropertyName = new byte[] { (byte)'$', (byte)'i', (byte)'d' }; - internal static ReadOnlySpan s_refPropertyName - => new byte[] { (byte)'$', (byte)'r', (byte)'e', (byte)'f' }; + internal static readonly byte[] s_refPropertyName + = new byte[] { (byte)'$', (byte)'r', (byte)'e', (byte)'f' }; + + internal static readonly byte[] s_valuesPropertyName + = new byte[] { (byte)'$', (byte)'v', (byte)'a', (byte)'l', (byte)'u', (byte)'e', (byte)'s' }; /// /// Returns true if successful, false is the reader ran out of buffer. - /// Sets state.Current.ReturnValue to the $ref target for MetadataRefProperty cases. + /// Sets state.Current.ReturnValue to the reference target for $ref cases; + /// Sets state.Current.ReturnValue to a new instance for $id cases. /// - internal static bool ResolveMetadata( - JsonConverter converter, + internal static bool ResolveMetadataForJsonObject( ref Utf8JsonReader reader, - ref ReadStack state) + ref ReadStack state, + JsonSerializerOptions options) { + JsonConverter converter = state.Current.JsonClassInfo.PropertyInfoForClassInfo.ConverterBase; + if (state.Current.ObjectState < StackFrameObjectState.ReadAheadNameOrEndObject) { // Read the first metadata property name. @@ -37,18 +43,10 @@ internal static bool ResolveMetadata( { if (reader.TokenType != JsonTokenType.PropertyName) { - // An enumerable needs metadata since it starts with StartObject. - if (converter.ClassType == ClassType.Enumerable) - { - ThrowHelper.ThrowJsonException_MetadataPreservedArrayValuesNotFound(converter.TypeToConvert); - } - - // The reader should have detected other invalid cases. - Debug.Assert(reader.TokenType == JsonTokenType.EndObject); - + // Since this was an empty object, we are done reading metadata. + state.Current.ObjectState = StackFrameObjectState.PropertyValue; // Skip the read of the first property name, since we already read it above. state.Current.PropertyState = StackFramePropertyState.ReadName; - return true; } @@ -56,7 +54,8 @@ internal static bool ResolveMetadata( MetadataPropertyName metadata = GetMetadataPropertyName(propertyName); if (metadata == MetadataPropertyName.Id) { - state.Current.JsonPropertyName = propertyName.ToArray(); + state.Current.JsonPropertyName = s_idPropertyName; + if (!converter.CanHaveIdMetadata) { ThrowHelper.ThrowJsonException_MetadataCannotParsePreservedObjectIntoImmutable(converter.TypeToConvert); @@ -66,7 +65,8 @@ internal static bool ResolveMetadata( } else if (metadata == MetadataPropertyName.Ref) { - state.Current.JsonPropertyName = propertyName.ToArray(); + state.Current.JsonPropertyName = s_refPropertyName; + if (converter.IsValueType) { ThrowHelper.ThrowJsonException_MetadataInvalidReferenceToValueType(converter.TypeToConvert); @@ -76,27 +76,13 @@ internal static bool ResolveMetadata( } else if (metadata == MetadataPropertyName.Values) { - state.Current.JsonPropertyName = propertyName.ToArray(); - if (converter.ClassType == ClassType.Enumerable) - { - ThrowHelper.ThrowJsonException_MetadataMissingIdBeforeValues(); - } - else - { - ThrowHelper.ThrowJsonException_MetadataInvalidPropertyWithLeadingDollarSign(propertyName, ref state, reader); - } + ThrowHelper.ThrowJsonException_MetadataInvalidPropertyWithLeadingDollarSign(propertyName, ref state, reader); } else { Debug.Assert(metadata == MetadataPropertyName.NoMetadata); - - // Having a StartObject without metadata properties is not allowed. - if (converter.ClassType == ClassType.Enumerable) - { - state.Current.JsonPropertyName = propertyName.ToArray(); - ThrowHelper.ThrowJsonException_MetadataPreservedArrayInvalidProperty(converter.TypeToConvert, reader); - } - + // We are done reading metadata, the object didn't contain any. + state.Current.ObjectState = StackFrameObjectState.PropertyValue; // Skip the read of the first property name, since we already read it above. state.Current.PropertyState = StackFramePropertyState.ReadName; return true; @@ -125,10 +111,11 @@ internal static bool ResolveMetadata( ThrowHelper.ThrowJsonException_MetadataValueWasNotString(reader.TokenType); } - string key = reader.GetString()!; + string referenceId = reader.GetString()!; // todo: https://github.com/dotnet/runtime/issues/32354 - state.Current.ReturnValue = state.ReferenceResolver.ResolveReference(key); + state.Current.ReturnValue = state.ReferenceResolver.ResolveReference(referenceId); + state.Current.ObjectState = StackFrameObjectState.ReadAheadRefEndObject; } else if (state.Current.ObjectState == StackFrameObjectState.ReadIdValue) @@ -138,21 +125,157 @@ internal static bool ResolveMetadata( ThrowHelper.ThrowJsonException_MetadataValueWasNotString(reader.TokenType); } - state.Current.MetadataId = reader.GetString(); + converter.CreateInstanceForReferenceResolver(ref reader, ref state, options); + + string referenceId = reader.GetString()!; + state.ReferenceResolver.AddReference(referenceId, state.Current.ReturnValue!); + + // We are done reading metadata plus we instantiated the object. + state.Current.ObjectState = StackFrameObjectState.CreatedObject; + } + + // Clear the metadata property name that was set in case of failure on ResolveReference/AddReference. + state.Current.JsonPropertyName = null; + + if (state.Current.ObjectState == StackFrameObjectState.ReadAheadRefEndObject) + { + if (!TryReadAheadMetadataAndSetState(ref reader, ref state, StackFrameObjectState.ReadRefEndObject)) + { + return false; + } + } + + if (state.Current.ObjectState == StackFrameObjectState.ReadRefEndObject) + { + if (reader.TokenType != JsonTokenType.EndObject) + { + // We just read a property. The only valid next tokens are EndObject and PropertyName. + Debug.Assert(reader.TokenType == JsonTokenType.PropertyName); + + ThrowHelper.ThrowJsonException_MetadataReferenceObjectCannotContainOtherProperties(reader.GetSpan(), ref state); + } + } + + return true; + } + + /// + /// Returns true if successful, false is the reader ran out of buffer. + /// Sets state.Current.ReturnValue to the reference target for $ref cases; + /// Sets state.Current.ReturnValue to a new instance for $id cases. + /// + internal static bool ResolveMetadataForJsonArray( + ref Utf8JsonReader reader, + ref ReadStack state, + JsonSerializerOptions options) + { + JsonConverter converter = state.Current.JsonClassInfo.PropertyInfoForClassInfo.ConverterBase; + + if (state.Current.ObjectState < StackFrameObjectState.ReadAheadNameOrEndObject) + { + // Read the first metadata property name. + if (!TryReadAheadMetadataAndSetState(ref reader, ref state, StackFrameObjectState.ReadNameOrEndObject)) + { + return false; + } + } - if (converter.ClassType == ClassType.Enumerable) + if (state.Current.ObjectState == StackFrameObjectState.ReadNameOrEndObject) + { + if (reader.TokenType != JsonTokenType.PropertyName) { - // Need to Read $values property name. - state.Current.ObjectState = StackFrameObjectState.ReadAheadValuesName; + // The reader should have detected other invalid cases. + Debug.Assert(reader.TokenType == JsonTokenType.EndObject); + + // An enumerable needs metadata since it starts with StartObject. + ThrowHelper.ThrowJsonException_MetadataPreservedArrayValuesNotFound(ref state, converter.TypeToConvert); + } + + + ReadOnlySpan propertyName = reader.GetSpan(); + MetadataPropertyName metadata = GetMetadataPropertyName(propertyName); + if (metadata == MetadataPropertyName.Id) + { + state.Current.JsonPropertyName = s_idPropertyName; + + if (!converter.CanHaveIdMetadata) + { + ThrowHelper.ThrowJsonException_MetadataCannotParsePreservedObjectIntoImmutable(converter.TypeToConvert); + } + + state.Current.ObjectState = StackFrameObjectState.ReadAheadIdValue; + } + else if (metadata == MetadataPropertyName.Ref) + { + state.Current.JsonPropertyName = s_refPropertyName; + + if (converter.IsValueType) + { + ThrowHelper.ThrowJsonException_MetadataInvalidReferenceToValueType(converter.TypeToConvert); + } + + state.Current.ObjectState = StackFrameObjectState.ReadAheadRefValue; + } + else if (metadata == MetadataPropertyName.Values) + { + ThrowHelper.ThrowJsonException_MetadataMissingIdBeforeValues(ref state, propertyName); } else { - // We are done reading metadata. - state.Current.ObjectState = StackFrameObjectState.PropertyValue; - return true; + Debug.Assert(metadata == MetadataPropertyName.NoMetadata); + + // Having a StartObject without metadata properties is not allowed. + ThrowHelper.ThrowJsonException_MetadataPreservedArrayInvalidProperty(ref state, converter.TypeToConvert, reader); } } + if (state.Current.ObjectState == StackFrameObjectState.ReadAheadRefValue) + { + if (!TryReadAheadMetadataAndSetState(ref reader, ref state, StackFrameObjectState.ReadRefValue)) + { + return false; + } + } + else if (state.Current.ObjectState == StackFrameObjectState.ReadAheadIdValue) + { + if (!TryReadAheadMetadataAndSetState(ref reader, ref state, StackFrameObjectState.ReadIdValue)) + { + return false; + } + } + + if (state.Current.ObjectState == StackFrameObjectState.ReadRefValue) + { + if (reader.TokenType != JsonTokenType.String) + { + ThrowHelper.ThrowJsonException_MetadataValueWasNotString(reader.TokenType); + } + + string key = reader.GetString()!; + + // todo: https://github.com/dotnet/runtime/issues/32354 + state.Current.ReturnValue = state.ReferenceResolver.ResolveReference(key); + state.Current.ObjectState = StackFrameObjectState.ReadAheadRefEndObject; + } + else if (state.Current.ObjectState == StackFrameObjectState.ReadIdValue) + { + if (reader.TokenType != JsonTokenType.String) + { + ThrowHelper.ThrowJsonException_MetadataValueWasNotString(reader.TokenType); + } + + converter.CreateInstanceForReferenceResolver(ref reader, ref state, options); + + string referenceId = reader.GetString()!; + state.ReferenceResolver.AddReference(referenceId, state.Current.ReturnValue!); + + // Need to Read $values property name. + state.Current.ObjectState = StackFrameObjectState.ReadAheadValuesName; + } + + // Clear the metadata property name that was set in case of failure on ResolverReference/AddReference. + state.Current.JsonPropertyName = null; + if (state.Current.ObjectState == StackFrameObjectState.ReadAheadRefEndObject) { if (!TryReadAheadMetadataAndSetState(ref reader, ref state, StackFrameObjectState.ReadRefEndObject)) @@ -186,21 +309,19 @@ internal static bool ResolveMetadata( { if (reader.TokenType != JsonTokenType.PropertyName) { - // Missing $values, JSON path should point to the property's object. - state.Current.JsonPropertyName = null; - ThrowHelper.ThrowJsonException_MetadataPreservedArrayValuesNotFound(converter.TypeToConvert); + ThrowHelper.ThrowJsonException_MetadataPreservedArrayValuesNotFound(ref state, converter.TypeToConvert); } ReadOnlySpan propertyName = reader.GetSpan(); - // Remember the property in case we get an exception. - state.Current.JsonPropertyName = propertyName.ToArray(); - if (GetMetadataPropertyName(propertyName) != MetadataPropertyName.Values) { - ThrowHelper.ThrowJsonException_MetadataPreservedArrayInvalidProperty(converter.TypeToConvert, reader); + ThrowHelper.ThrowJsonException_MetadataPreservedArrayInvalidProperty(ref state, converter.TypeToConvert, reader); } + // Remember the property in case we get an exception in one of the array elements. + state.Current.JsonPropertyName = s_valuesPropertyName; + state.Current.ObjectState = StackFrameObjectState.ReadAheadValuesStartArray; } @@ -218,8 +339,8 @@ internal static bool ResolveMetadata( { ThrowHelper.ThrowJsonException_MetadataValuesInvalidToken(reader.TokenType); } - - state.Current.ObjectState = StackFrameObjectState.PropertyValue; + state.Current.ValidateEndTokenOnArray = true; + state.Current.ObjectState = StackFrameObjectState.CreatedObject; } return true; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.HandleMetadata.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.HandleMetadata.cs index dccf453a2c175f..45c1462ea68f3a 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.HandleMetadata.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.HandleMetadata.cs @@ -28,7 +28,6 @@ internal static MetadataPropertyName WriteReferenceForObject( } else { - string referenceId = state.ReferenceResolver.GetReference(currentValue, out bool alreadyExists); Debug.Assert(referenceId != null); @@ -65,10 +64,10 @@ internal static MetadataPropertyName WriteReferenceForCollection( else { string referenceId = state.ReferenceResolver.GetReference(currentValue, out bool alreadyExists); + Debug.Assert(referenceId != null); if (alreadyExists) { - Debug.Assert(referenceId != null); writer.WriteStartObject(); writer.WriteString(s_metadataRef, referenceId); writer.WriteEndObject(); @@ -76,7 +75,6 @@ internal static MetadataPropertyName WriteReferenceForCollection( } else { - Debug.Assert(referenceId != null); writer.WriteStartObject(); writer.WriteString(s_metadataId, referenceId); writer.WriteStartArray(s_metadataValues); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStackFrame.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStackFrame.cs index b0c333568bda35..3331e02990fe0d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStackFrame.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStackFrame.cs @@ -32,8 +32,8 @@ internal struct ReadStackFrame public JsonClassInfo JsonClassInfo; public StackFrameObjectState ObjectState; // State tracking the current object. - // Preserve reference. - public string? MetadataId; + // Validate EndObject token on array with preserve semantics. + public bool ValidateEndTokenOnArray; // For performance, we order the properties by the first deserialize and PropertyIndex helps find the right slot quicker. public int PropertyIndex; @@ -56,7 +56,7 @@ public void EndProperty() JsonPropertyName = null; JsonPropertyNameAsString = null; PropertyState = StackFramePropertyState.None; - MetadataId = null; + ValidateEndTokenOnArray = false; // No need to clear these since they are overwritten each time: // UseExtensionProperty diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs b/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs index 2194ab03fab145..ce4f554a37dc71 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Buffers; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Reflection; @@ -506,8 +507,9 @@ public static void ThrowJsonException_MetadataIdIsNotFirstProperty(ReadOnlySpan< [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] - public static void ThrowJsonException_MetadataMissingIdBeforeValues() + public static void ThrowJsonException_MetadataMissingIdBeforeValues(ref ReadStack state, ReadOnlySpan propertyName) { + state.Current.JsonPropertyName = propertyName.ToArray(); ThrowJsonException(SR.MetadataPreservedArrayPropertyNotFound); } @@ -544,19 +546,23 @@ public static void ThrowJsonException_MetadataInvalidReferenceToValueType(Type p [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] - public static void ThrowJsonException_MetadataPreservedArrayInvalidProperty(Type propertyType, in Utf8JsonReader reader) + public static void ThrowJsonException_MetadataPreservedArrayInvalidProperty(ref ReadStack state, Type propertyType, in Utf8JsonReader reader) { - string propertyName = reader.GetString()!; + state.Current.JsonPropertyName = reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan.ToArray(); + string propertyNameAsString = reader.GetString()!; ThrowJsonException(SR.Format(SR.MetadataPreservedArrayFailed, - SR.Format(SR.MetadataPreservedArrayInvalidProperty, propertyName), + SR.Format(SR.MetadataPreservedArrayInvalidProperty, propertyNameAsString), SR.Format(SR.DeserializeUnableToConvertValue, propertyType))); } [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] - public static void ThrowJsonException_MetadataPreservedArrayValuesNotFound(Type propertyType) + public static void ThrowJsonException_MetadataPreservedArrayValuesNotFound(ref ReadStack state, Type propertyType) { + // Missing $values, JSON path should point to the property's object. + state.Current.JsonPropertyName = null; + ThrowJsonException(SR.Format(SR.MetadataPreservedArrayFailed, SR.MetadataPreservedArrayPropertyNotFound, SR.Format(SR.DeserializeUnableToConvertValue, propertyType))); From c6520585b6f48d80228241320198b2efdb8e0fe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Mon, 20 Jul 2020 20:53:20 +0200 Subject: [PATCH 034/458] Add PNSE on non-Browser for S.R.I.JavaScript and clean up references (#39629) Fixes https://github.com/dotnet/runtime/issues/39593 --- .../src/System.Net.Http.csproj | 4 +- .../src/System.Net.WebSockets.Client.csproj | 4 +- ...stem.Runtime.InteropServices.JavaScript.cs | 341 ++++++++++++++++++ ....Runtime.InteropServices.JavaScript.csproj | 12 + .../src/Resources/Strings.resx | 123 +++++++ ....Runtime.InteropServices.JavaScript.csproj | 70 ++-- src/libraries/pkg/baseline/packageIndex.json | 5 + 7 files changed, 521 insertions(+), 38 deletions(-) create mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/ref/System.Runtime.InteropServices.JavaScript.cs create mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/ref/System.Runtime.InteropServices.JavaScript.csproj create mode 100644 src/libraries/System.Runtime.InteropServices.JavaScript/src/Resources/Strings.resx diff --git a/src/libraries/System.Net.Http/src/System.Net.Http.csproj b/src/libraries/System.Net.Http/src/System.Net.Http.csproj index 65d63c045bbf58..e6c23001804d4c 100644 --- a/src/libraries/System.Net.Http/src/System.Net.Http.csproj +++ b/src/libraries/System.Net.Http/src/System.Net.Http.csproj @@ -683,6 +683,7 @@ + @@ -721,7 +722,4 @@ - - - diff --git a/src/libraries/System.Net.WebSockets.Client/src/System.Net.WebSockets.Client.csproj b/src/libraries/System.Net.WebSockets.Client/src/System.Net.WebSockets.Client.csproj index 83b4c5a2a91bcd..1f44cb14836494 100644 --- a/src/libraries/System.Net.WebSockets.Client/src/System.Net.WebSockets.Client.csproj +++ b/src/libraries/System.Net.WebSockets.Client/src/System.Net.WebSockets.Client.csproj @@ -37,8 +37,6 @@ + - - - diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/ref/System.Runtime.InteropServices.JavaScript.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/ref/System.Runtime.InteropServices.JavaScript.cs new file mode 100644 index 00000000000000..dc2ac4c65c87a2 --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/ref/System.Runtime.InteropServices.JavaScript.cs @@ -0,0 +1,341 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// ------------------------------------------------------------------------------ +// Changes to this file must follow the https://aka.ms/api-review process. +// ------------------------------------------------------------------------------ + +namespace System.Runtime.InteropServices.JavaScript +{ + public abstract partial class AnyRef : Microsoft.Win32.SafeHandles.SafeHandleMinusOneIsInvalid + { + internal AnyRef() : base (default(bool)) { } + public int JSHandle { get { throw null; } } + protected void FreeGCHandle() { } + } + public partial class Array : System.Runtime.InteropServices.JavaScript.CoreObject + { + public Array(params object[] _params) : base (default(int)) { } + public object this[int i] { get { throw null; } set { } } + public int IndexOf(object searchElement, int fromIndex = 0) { throw null; } + public int LastIndexOf(object searchElement) { throw null; } + public int LastIndexOf(object searchElement, int endIndex) { throw null; } + public object Pop() { throw null; } + public int Push(params object[] elements) { throw null; } + public object Shift() { throw null; } + public int UnShift(params object[] elements) { throw null; } + } + public partial class ArrayBuffer : System.Runtime.InteropServices.JavaScript.CoreObject + { + public ArrayBuffer() : base (default(int)) { } + public ArrayBuffer(int length) : base (default(int)) { } + public int ByteLength { get { throw null; } } + public bool IsView { get { throw null; } } + public System.Runtime.InteropServices.JavaScript.ArrayBuffer Slice(int begin) { throw null; } + public System.Runtime.InteropServices.JavaScript.ArrayBuffer Slice(int begin, int end) { throw null; } + } + public abstract partial class CoreObject : System.Runtime.InteropServices.JavaScript.JSObject + { + protected CoreObject(int jsHandle) { } + } + public partial class DataView : System.Runtime.InteropServices.JavaScript.CoreObject + { + public DataView(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer) : base (default(int)) { } + public DataView(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer, int byteOffset) : base (default(int)) { } + public DataView(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer, int byteOffset, int byteLength) : base (default(int)) { } + public DataView(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer) : base (default(int)) { } + public DataView(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer, int byteOffset) : base (default(int)) { } + public DataView(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer, int byteOffset, int byteLength) : base (default(int)) { } + public System.Runtime.InteropServices.JavaScript.ArrayBuffer Buffer { get { throw null; } } + public int ByteLength { get { throw null; } } + public int ByteOffset { get { throw null; } } + public float GetFloat32(int byteOffset, bool littleEndian = false) { throw null; } + public double GetFloat64(int byteOffset, bool littleEndian = false) { throw null; } + public short GetInt16(int byteOffset, bool littleEndian = false) { throw null; } + public int GetInt32(int byteOffset, bool littleEndian = false) { throw null; } + [System.CLSCompliantAttribute(false)] + public sbyte GetInt8(int byteOffset, bool littleEndian = false) { throw null; } + [System.CLSCompliantAttribute(false)] + public ushort GetUint16(int byteOffset, bool littleEndian = false) { throw null; } + [System.CLSCompliantAttribute(false)] + public uint GetUint32(int byteOffset, bool littleEndian = false) { throw null; } + public byte GetUint8(int byteOffset, bool littleEndian = false) { throw null; } + public void SetFloat32(int byteOffset, float value, bool littleEndian = false) { } + public void SetFloat64(int byteOffset, double value, bool littleEndian = false) { } + public void SetInt16(int byteOffset, short value, bool littleEndian = false) { } + public void SetInt32(int byteOffset, int value, bool littleEndian = false) { } + [System.CLSCompliantAttribute(false)] + public void SetInt8(int byteOffset, sbyte value, bool littleEndian = false) { } + [System.CLSCompliantAttribute(false)] + public void SetUint16(int byteOffset, ushort value, bool littleEndian = false) { } + [System.CLSCompliantAttribute(false)] + public void SetUint32(int byteOffset, uint value, bool littleEndian = false) { } + public void SetUint8(int byteOffset, byte value, bool littleEndian = false) { } + } + public sealed partial class Float32Array : System.Runtime.InteropServices.JavaScript.TypedArray + { + public Float32Array() { } + public Float32Array(int length) { } + public Float32Array(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer) { } + public Float32Array(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer, int byteOffset) { } + public Float32Array(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer, int byteOffset, int length) { } + public Float32Array(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer) { } + public Float32Array(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer, int byteOffset) { } + public Float32Array(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer, int byteOffset, int length) { } + public static implicit operator System.Span (System.Runtime.InteropServices.JavaScript.Float32Array typedarray) { throw null; } + public static implicit operator System.Runtime.InteropServices.JavaScript.Float32Array (System.Span span) { throw null; } + } + public sealed partial class Float64Array : System.Runtime.InteropServices.JavaScript.TypedArray + { + public Float64Array() { } + public Float64Array(int length) { } + public Float64Array(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer) { } + public Float64Array(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer, int byteOffset) { } + public Float64Array(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer, int byteOffset, int length) { } + public Float64Array(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer) { } + public Float64Array(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer, int byteOffset) { } + public Float64Array(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer, int byteOffset, int length) { } + public static implicit operator System.Span (System.Runtime.InteropServices.JavaScript.Float64Array typedarray) { throw null; } + public static implicit operator System.Runtime.InteropServices.JavaScript.Float64Array (System.Span span) { throw null; } + } + public partial class Function : System.Runtime.InteropServices.JavaScript.CoreObject + { + public Function(params object[] args) : base (default(int)) { } + public object Apply(object? thisArg = null, object[]? argsArray = null) { throw null; } + public System.Runtime.InteropServices.JavaScript.Function Bind(object? thisArg = null, object[]? argsArray = null) { throw null; } + public object Call(object? thisArg = null, params object[] argsArray) { throw null; } + } + public partial class HostObject : System.Runtime.InteropServices.JavaScript.HostObjectBase + { + public HostObject(string hostName, params object[] _params) : base (default(int)) { } + } + public abstract partial class HostObjectBase : System.Runtime.InteropServices.JavaScript.JSObject, System.Runtime.InteropServices.JavaScript.IHostObject + { + protected HostObjectBase(int jHandle) { } + } + public partial interface IHostObject + { + } + public partial interface IJSObject + { + int JSHandle { get; } + int Length { get; } + } + public sealed partial class Int16Array : System.Runtime.InteropServices.JavaScript.TypedArray + { + public Int16Array() { } + public Int16Array(int length) { } + public Int16Array(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer) { } + public Int16Array(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer, int byteOffset) { } + public Int16Array(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer, int byteOffset, int length) { } + public Int16Array(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer) { } + public Int16Array(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer, int byteOffset) { } + public Int16Array(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer, int byteOffset, int length) { } + [System.CLSCompliantAttribute(false)] + public static implicit operator System.Span (System.Runtime.InteropServices.JavaScript.Int16Array typedarray) { throw null; } + public static implicit operator System.Runtime.InteropServices.JavaScript.Int16Array (System.Span span) { throw null; } + } + public sealed partial class Int32Array : System.Runtime.InteropServices.JavaScript.TypedArray + { + public Int32Array() { } + public Int32Array(int length) { } + public Int32Array(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer) { } + public Int32Array(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer, int byteOffset) { } + public Int32Array(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer, int byteOffset, int length) { } + public Int32Array(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer) { } + public Int32Array(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer, int byteOffset) { } + public Int32Array(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer, int byteOffset, int length) { } + public static implicit operator System.Span (System.Runtime.InteropServices.JavaScript.Int32Array typedarray) { throw null; } + public static implicit operator System.Runtime.InteropServices.JavaScript.Int32Array (System.Span span) { throw null; } + } + [System.CLSCompliantAttribute(false)] + public sealed partial class Int8Array : System.Runtime.InteropServices.JavaScript.TypedArray + { + public Int8Array() { } + public Int8Array(int length) { } + public Int8Array(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer) { } + public Int8Array(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer, int byteOffset) { } + public Int8Array(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer, int byteOffset, int length) { } + public Int8Array(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer) { } + public Int8Array(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer, int byteOffset) { } + public Int8Array(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer, int byteOffset, int length) { } + [System.CLSCompliantAttribute(false)] + public static implicit operator System.Span (System.Runtime.InteropServices.JavaScript.Int8Array typedarray) { throw null; } + [System.CLSCompliantAttribute(false)] + public static implicit operator System.Runtime.InteropServices.JavaScript.Int8Array (System.Span span) { throw null; } + } + public partial interface ITypedArray + { + System.Runtime.InteropServices.JavaScript.ArrayBuffer Buffer { get; } + int ByteLength { get; } + int BytesPerElement { get; } + string Name { get; } + System.Runtime.InteropServices.JavaScript.TypedArrayTypeCode GetTypedArrayType(); + void Set(System.Runtime.InteropServices.JavaScript.Array array); + void Set(System.Runtime.InteropServices.JavaScript.Array array, int offset); + void Set(System.Runtime.InteropServices.JavaScript.ITypedArray typedArray); + void Set(System.Runtime.InteropServices.JavaScript.ITypedArray typedArray, int offset); + } + public partial interface ITypedArray where U : struct + { + T Slice(); + T Slice(int begin); + T Slice(int begin, int end); + T SubArray(); + T SubArray(int begin); + T SubArray(int begin, int end); + } + public partial class JSException : System.Exception + { + public JSException(string msg) { } + } + public partial class JSObject : System.Runtime.InteropServices.JavaScript.AnyRef, System.IDisposable, System.Runtime.InteropServices.JavaScript.IJSObject + { + public JSObject() { } + public bool IsDisposed { get { throw null; } } + public int Length { get { throw null; } set { } } + public override bool Equals(object? obj) { throw null; } + public override int GetHashCode() { throw null; } + public object GetObjectProperty(string name) { throw null; } + public bool HasOwnProperty(string prop) { throw null; } + public object Invoke(string method, params object?[] args) { throw null; } + public bool PropertyIsEnumerable(string prop) { throw null; } + protected override bool ReleaseHandle() { throw null; } + public void SetObjectProperty(string name, object value, bool createIfNotExists = true, bool hasOwnProperty = false) { } + public override string ToString() { throw null; } + } + public partial class Map : System.Runtime.InteropServices.JavaScript.CoreObject, System.Collections.ICollection, System.Collections.IDictionary, System.Collections.IEnumerable + { + public Map() : base (default(int)) { } + public int Count { get { throw null; } } + public bool IsFixedSize { get { throw null; } } + public bool IsReadOnly { get { throw null; } } + public bool IsSynchronized { get { throw null; } } + public object? this[object key] { get { throw null; } set { } } + public System.Collections.ICollection Keys { get { throw null; } } + public object SyncRoot { get { throw null; } } + public System.Collections.ICollection Values { get { throw null; } } + public void Add(object key, object? value) { } + public void Clear() { } + public bool Contains(object key) { throw null; } + public void CopyTo(System.Array array, int index) { } + public System.Collections.IDictionaryEnumerator GetEnumerator() { throw null; } + public void Remove(object key) { } + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; } + } + public static partial class Runtime + { + public static System.Runtime.InteropServices.JavaScript.Function? CompileFunction(string snippet) { throw null; } + public static void FreeObject(object obj) { } + public static object GetGlobalObject(string? str = null) { throw null; } + public static string InvokeJS(string str) { throw null; } + public static int New(string hostClassName, params object[] parms) { throw null; } + public static int New(params object[] parms) { throw null; } + public static System.IntPtr SafeHandleGetHandle(System.Runtime.InteropServices.SafeHandle safeHandle, bool addRef) { throw null; } + } + public partial class SharedArrayBuffer : System.Runtime.InteropServices.JavaScript.CoreObject + { + public SharedArrayBuffer(int length) : base (default(int)) { } + public int ByteLength { get { throw null; } } + public System.Runtime.InteropServices.JavaScript.SharedArrayBuffer Slice(int begin, int end) { throw null; } + } + public enum TypedArrayTypeCode + { + Int8Array = 5, + Uint8Array = 6, + Int16Array = 7, + Uint16Array = 8, + Int32Array = 9, + Uint32Array = 10, + Float32Array = 13, + Float64Array = 14, + Uint8ClampedArray = 15, + } + public abstract partial class TypedArray : System.Runtime.InteropServices.JavaScript.CoreObject, System.Runtime.InteropServices.JavaScript.ITypedArray, System.Runtime.InteropServices.JavaScript.ITypedArray where U : struct + { + protected TypedArray() : base (default(int)) { } + protected TypedArray(int length) : base (default(int)) { } + protected TypedArray(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer) : base (default(int)) { } + protected TypedArray(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer, int byteOffset) : base (default(int)) { } + protected TypedArray(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer, int byteOffset, int length) : base (default(int)) { } + protected TypedArray(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer) : base (default(int)) { } + protected TypedArray(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer, int byteOffset) : base (default(int)) { } + protected TypedArray(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer, int byteOffset, int length) : base (default(int)) { } + public System.Runtime.InteropServices.JavaScript.ArrayBuffer Buffer { get { throw null; } } + public int ByteLength { get { throw null; } } + public int BytesPerElement { get { throw null; } } + public U? this[int i] { get { throw null; } set { } } + public string Name { get { throw null; } } + public int CopyFrom(System.ReadOnlySpan span) { throw null; } + public int CopyTo(System.Span span) { throw null; } + public void Fill(U value) { } + public void Fill(U value, int start) { } + public void Fill(U value, int start, int end) { } + public static T From(System.ReadOnlySpan span) { throw null; } + public System.Runtime.InteropServices.JavaScript.TypedArrayTypeCode GetTypedArrayType() { throw null; } + public void Set(System.Runtime.InteropServices.JavaScript.Array array) { } + public void Set(System.Runtime.InteropServices.JavaScript.Array array, int offset) { } + public void Set(System.Runtime.InteropServices.JavaScript.ITypedArray typedArray) { } + public void Set(System.Runtime.InteropServices.JavaScript.ITypedArray typedArray, int offset) { } + public T Slice() { throw null; } + public T Slice(int begin) { throw null; } + public T Slice(int begin, int end) { throw null; } + public T SubArray() { throw null; } + public T SubArray(int begin) { throw null; } + public T SubArray(int begin, int end) { throw null; } + public U[] ToArray() { throw null; } + } + [System.CLSCompliantAttribute(false)] + public sealed partial class Uint16Array : System.Runtime.InteropServices.JavaScript.TypedArray + { + public Uint16Array() { } + public Uint16Array(int length) { } + public Uint16Array(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer) { } + public Uint16Array(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer, int byteOffset) { } + public Uint16Array(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer, int byteOffset, int length) { } + public Uint16Array(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer) { } + public Uint16Array(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer, int byteOffset) { } + public Uint16Array(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer, int byteOffset, int length) { } + public static implicit operator System.Span (System.Runtime.InteropServices.JavaScript.Uint16Array typedarray) { throw null; } + public static implicit operator System.Runtime.InteropServices.JavaScript.Uint16Array (System.Span span) { throw null; } + } + [System.CLSCompliantAttribute(false)] + public sealed partial class Uint32Array : System.Runtime.InteropServices.JavaScript.TypedArray + { + public Uint32Array() { } + public Uint32Array(int length) { } + public Uint32Array(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer) { } + public Uint32Array(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer, int byteOffset) { } + public Uint32Array(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer, int byteOffset, int length) { } + public Uint32Array(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer) { } + public Uint32Array(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer, int byteOffset) { } + public Uint32Array(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer, int byteOffset, int length) { } + public static implicit operator System.Span (System.Runtime.InteropServices.JavaScript.Uint32Array typedarray) { throw null; } + public static implicit operator System.Runtime.InteropServices.JavaScript.Uint32Array (System.Span span) { throw null; } + } + public sealed partial class Uint8Array : System.Runtime.InteropServices.JavaScript.TypedArray + { + public Uint8Array() { } + public Uint8Array(int length) { } + public Uint8Array(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer) { } + public Uint8Array(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer, int byteOffset) { } + public Uint8Array(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer, int byteOffset, int length) { } + public Uint8Array(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer) { } + public Uint8Array(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer, int byteOffset) { } + public Uint8Array(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer, int byteOffset, int length) { } + public static implicit operator System.Span (System.Runtime.InteropServices.JavaScript.Uint8Array typedarray) { throw null; } + public static implicit operator System.Runtime.InteropServices.JavaScript.Uint8Array (System.Span span) { throw null; } + } + public sealed partial class Uint8ClampedArray : System.Runtime.InteropServices.JavaScript.TypedArray + { + public Uint8ClampedArray() { } + public Uint8ClampedArray(int length) { } + public Uint8ClampedArray(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer) { } + public Uint8ClampedArray(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer, int byteOffset) { } + public Uint8ClampedArray(System.Runtime.InteropServices.JavaScript.ArrayBuffer buffer, int byteOffset, int length) { } + public Uint8ClampedArray(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer) { } + public Uint8ClampedArray(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer, int byteOffset) { } + public Uint8ClampedArray(System.Runtime.InteropServices.JavaScript.SharedArrayBuffer buffer, int byteOffset, int length) { } + public static implicit operator System.Span (System.Runtime.InteropServices.JavaScript.Uint8ClampedArray typedarray) { throw null; } + public static implicit operator System.Runtime.InteropServices.JavaScript.Uint8ClampedArray (System.Span span) { throw null; } + } +} diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/ref/System.Runtime.InteropServices.JavaScript.csproj b/src/libraries/System.Runtime.InteropServices.JavaScript/ref/System.Runtime.InteropServices.JavaScript.csproj new file mode 100644 index 00000000000000..aded6c5d1e510c --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/ref/System.Runtime.InteropServices.JavaScript.csproj @@ -0,0 +1,12 @@ + + + enable + $(NetCoreAppCurrent) + + + + + + + + \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/Resources/Strings.resx b/src/libraries/System.Runtime.InteropServices.JavaScript/src/Resources/Strings.resx new file mode 100644 index 00000000000000..a7f92bb25150cd --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/Resources/Strings.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + System.Runtime.InteropServices.JavaScript is not supported on this platform. + + \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj index 9eb0dc6fa61ddf..5d43a5781c2dfa 100644 --- a/src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj +++ b/src/libraries/System.Runtime.InteropServices.JavaScript/src/System.Runtime.InteropServices.JavaScript.csproj @@ -3,40 +3,46 @@ System.Runtime.InteropServices.JavaScript true enable - $(NetCoreAppCurrent)-Browser + $(NetCoreAppCurrent);$(NetCoreAppCurrent)-Browser - - - - - - - - + + + SR.SystemRuntimeInteropServicesJavaScript_PlatformNotSupported + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + diff --git a/src/libraries/pkg/baseline/packageIndex.json b/src/libraries/pkg/baseline/packageIndex.json index 1446eaab32977a..95fb67f15b89c6 100644 --- a/src/libraries/pkg/baseline/packageIndex.json +++ b/src/libraries/pkg/baseline/packageIndex.json @@ -5122,6 +5122,11 @@ "4.1.1.0": "4.3.0" } }, + "System.Runtime.InteropServices.JavaScript": { + "InboxOn": { + "net5.0": "5.0.0.0" + } + }, "System.Runtime.InteropServices.RuntimeInformation": { "StableVersions": [ "4.0.0", From d5b61d844b420c414b80e689723679f6010f2ab9 Mon Sep 17 00:00:00 2001 From: Maxim Lipnin Date: Mon, 20 Jul 2020 22:11:37 +0300 Subject: [PATCH 035/458] [wasm] Enable System.CodeDom.Tests test suite (#39626) Part of https://github.com/dotnet/runtime/issues/38422. --- .../tests/System/CodeDom/Compiler/CompilerResultsTests.cs | 2 +- src/libraries/tests.proj | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libraries/System.CodeDom/tests/System/CodeDom/Compiler/CompilerResultsTests.cs b/src/libraries/System.CodeDom/tests/System/CodeDom/Compiler/CompilerResultsTests.cs index a88143c34b5540..71158faaa22c3c 100644 --- a/src/libraries/System.CodeDom/tests/System/CodeDom/Compiler/CompilerResultsTests.cs +++ b/src/libraries/System.CodeDom/tests/System/CodeDom/Compiler/CompilerResultsTests.cs @@ -31,7 +31,7 @@ public void Ctor_TempFileCollection(TempFileCollection tempFiles) [Fact] public void CompiledAssembly_GetWithPathToAssemblySet_ReturnsExpectedAssembly() { - var results = new CompilerResults(null) { PathToAssembly = typeof(CompilerResultsTests).Assembly.Location }; + var results = new CompilerResults(null) { PathToAssembly = (PlatformDetection.IsBrowser ? "/" : string.Empty) + typeof(CompilerResultsTests).Assembly.Location }; Assert.NotNull(results.CompiledAssembly); Assert.Equal(typeof(CompilerResultsTests).Assembly.FullName, results.CompiledAssembly.FullName); diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index b11eb01f25d850..0473fc620c0c9e 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -22,7 +22,6 @@ - From 6998f4c575324b6d1b3311d91212b078034306ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Mon, 20 Jul 2020 21:22:55 +0200 Subject: [PATCH 036/458] Unify resource strings used for Browser PNSE (#39637) We sometimes used `... is not supported on Browser.` and elsewhere `... is not supported on this platform.` Standardize on the latter one as it can potentially be reused for other targets. --- .../System.Diagnostics.Process/src/Resources/Strings.resx | 2 +- .../System.IO.FileSystem.Watcher/src/Resources/Strings.resx | 2 +- src/libraries/System.IO.Pipes/src/Resources/Strings.resx | 2 +- src/libraries/System.Net.Mail/src/Resources/Strings.resx | 2 +- src/libraries/System.Net.Mail/src/System.Net.Mail.csproj | 2 +- .../System.Net.NameResolution/src/Resources/Strings.resx | 2 +- .../src/System.Net.NameResolution.csproj | 2 +- .../System.Net.NetworkInformation/src/Resources/Strings.resx | 2 +- .../src/System.Net.NetworkInformation.csproj | 2 +- src/libraries/System.Net.Ping/src/Resources/Strings.resx | 2 +- src/libraries/System.Net.Ping/src/System.Net.Ping.csproj | 2 +- src/libraries/System.Net.Sockets/src/Resources/Strings.resx | 2 +- .../System.Net.Sockets/src/System.Net.Sockets.csproj | 2 +- src/libraries/System.Net.WebClient/src/Resources/Strings.resx | 2 +- .../System.Net.WebClient/src/System.Net.WebClient.csproj | 2 +- .../src/Resources/Strings.resx | 4 ++-- .../src/System.Security.Cryptography.Algorithms.csproj | 2 +- .../src/Resources/Strings.resx | 4 ++-- .../src/System.Security.Cryptography.Csp.csproj | 2 +- .../src/Resources/Strings.resx | 4 ++-- .../src/System.Security.Cryptography.Encoding.csproj | 2 +- .../src/Resources/Strings.resx | 4 ++-- .../src/System.Security.Cryptography.Pkcs.csproj | 2 +- .../src/Resources/Strings.resx | 4 ++-- .../src/System.Security.Cryptography.Primitives.csproj | 2 +- .../src/Resources/Strings.resx | 4 ++-- .../src/System.Security.Cryptography.X509Certificates.csproj | 2 +- .../src/Resources/Strings.resx | 4 ++-- .../src/System.Security.Cryptography.Xml.csproj | 2 +- 29 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/libraries/System.Diagnostics.Process/src/Resources/Strings.resx b/src/libraries/System.Diagnostics.Process/src/Resources/Strings.resx index 5d52fa2a50123b..6aa5781a15250b 100644 --- a/src/libraries/System.Diagnostics.Process/src/Resources/Strings.resx +++ b/src/libraries/System.Diagnostics.Process/src/Resources/Strings.resx @@ -246,7 +246,7 @@ The {0} property is not supported on this platform. - System.Diagnostics.Process is not supported on this platform + System.Diagnostics.Process is not supported on this platform. Failed to set or retrieve rusage information. See the error code for OS-specific error information. diff --git a/src/libraries/System.IO.FileSystem.Watcher/src/Resources/Strings.resx b/src/libraries/System.IO.FileSystem.Watcher/src/Resources/Strings.resx index 1a3a137fe01272..c16582a79cc7f3 100644 --- a/src/libraries/System.IO.FileSystem.Watcher/src/Resources/Strings.resx +++ b/src/libraries/System.IO.FileSystem.Watcher/src/Resources/Strings.resx @@ -192,6 +192,6 @@ The path '{0}' is too long, or a component of the specified path is too long. - System.IO.FileSystem.Watcher is not supported on Browser. + System.IO.FileSystem.Watcher is not supported on this platform. diff --git a/src/libraries/System.IO.Pipes/src/Resources/Strings.resx b/src/libraries/System.IO.Pipes/src/Resources/Strings.resx index e4777e219890c6..5b1a648e56a50a 100644 --- a/src/libraries/System.IO.Pipes/src/Resources/Strings.resx +++ b/src/libraries/System.IO.Pipes/src/Resources/Strings.resx @@ -292,6 +292,6 @@ 'pipeSecurity' must be null when 'options' contains 'PipeOptions.CurrentUserOnly'. - System.IO.Pipes is not supported on this platform + System.IO.Pipes is not supported on this platform. diff --git a/src/libraries/System.Net.Mail/src/Resources/Strings.resx b/src/libraries/System.Net.Mail/src/Resources/Strings.resx index dd4d31fb2a9cb0..b04e8c6d8d1e27 100644 --- a/src/libraries/System.Net.Mail/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Mail/src/Resources/Strings.resx @@ -334,7 +334,7 @@ IIS delivery is not supported. - + System.Net.Mail is not supported on this platform. diff --git a/src/libraries/System.Net.Mail/src/System.Net.Mail.csproj b/src/libraries/System.Net.Mail/src/System.Net.Mail.csproj index 27a9633849037c..766dc25eab7d2b 100644 --- a/src/libraries/System.Net.Mail/src/System.Net.Mail.csproj +++ b/src/libraries/System.Net.Mail/src/System.Net.Mail.csproj @@ -6,7 +6,7 @@ - SR.SystemNetMailNotSupported + SR.SystemNetMail_PlatformNotSupported diff --git a/src/libraries/System.Net.NameResolution/src/Resources/Strings.resx b/src/libraries/System.Net.NameResolution/src/Resources/Strings.resx index 578cb9c5e2fb7d..ab9add73ea9554 100644 --- a/src/libraries/System.Net.NameResolution/src/Resources/Strings.resx +++ b/src/libraries/System.Net.NameResolution/src/Resources/Strings.resx @@ -72,7 +72,7 @@ IPv4 address 0.0.0.0 and IPv6 address ::0 are unspecified addresses that cannot be used as a target address. - + System.Net.NameResolution is not supported on this platform. \ No newline at end of file diff --git a/src/libraries/System.Net.NameResolution/src/System.Net.NameResolution.csproj b/src/libraries/System.Net.NameResolution/src/System.Net.NameResolution.csproj index 9dd965698c5dff..73f80add914cc0 100644 --- a/src/libraries/System.Net.NameResolution/src/System.Net.NameResolution.csproj +++ b/src/libraries/System.Net.NameResolution/src/System.Net.NameResolution.csproj @@ -6,7 +6,7 @@ enable - SR.NameResolution_PlatformNotSupported + SR.SystemNetNameResolution_PlatformNotSupported --exclude-api-list ExcludeApiList.PNSE.Browser.txt diff --git a/src/libraries/System.Net.NetworkInformation/src/Resources/Strings.resx b/src/libraries/System.Net.NetworkInformation/src/Resources/Strings.resx index 3f86a8ff7d6289..e2064ff2bfebab 100644 --- a/src/libraries/System.Net.NetworkInformation/src/Resources/Strings.resx +++ b/src/libraries/System.Net.NetworkInformation/src/Resources/Strings.resx @@ -90,7 +90,7 @@ An error was encountered while querying information from the operating system. - + System.Net.NetworkInformation is not supported on this platform. diff --git a/src/libraries/System.Net.NetworkInformation/src/System.Net.NetworkInformation.csproj b/src/libraries/System.Net.NetworkInformation/src/System.Net.NetworkInformation.csproj index 6f973f7559deb9..5360c88d8995ce 100644 --- a/src/libraries/System.Net.NetworkInformation/src/System.Net.NetworkInformation.csproj +++ b/src/libraries/System.Net.NetworkInformation/src/System.Net.NetworkInformation.csproj @@ -7,7 +7,7 @@ enable - SR.net_NetworkInformation_PlatformNotSupported + SR.SystemNetNetworkInformation_PlatformNotSupported diff --git a/src/libraries/System.Net.Ping/src/Resources/Strings.resx b/src/libraries/System.Net.Ping/src/Resources/Strings.resx index 7b96fe56921ce6..1ad9023082ef59 100644 --- a/src/libraries/System.Net.Ping/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Ping/src/Resources/Strings.resx @@ -87,7 +87,7 @@ Ping functionality is not currently supported in UWP. - + System.Net.Ping is not supported on this platform. \ No newline at end of file diff --git a/src/libraries/System.Net.Ping/src/System.Net.Ping.csproj b/src/libraries/System.Net.Ping/src/System.Net.Ping.csproj index fd4c98b1521a07..b64a73e871a0fc 100644 --- a/src/libraries/System.Net.Ping/src/System.Net.Ping.csproj +++ b/src/libraries/System.Net.Ping/src/System.Net.Ping.csproj @@ -6,7 +6,7 @@ enable - SR.Ping_PlatformNotSupported + SR.SystemNetPing_PlatformNotSupported diff --git a/src/libraries/System.Net.Sockets/src/Resources/Strings.resx b/src/libraries/System.Net.Sockets/src/Resources/Strings.resx index c2b2e397211ba5..a0308908d6279e 100644 --- a/src/libraries/System.Net.Sockets/src/Resources/Strings.resx +++ b/src/libraries/System.Net.Sockets/src/Resources/Strings.resx @@ -262,7 +262,7 @@ Null is not a valid value for {0}. - + System.Net.Sockets is not supported on this platform. diff --git a/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj b/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj index 211dd8a0eafd5e..ac3e781f745bcc 100644 --- a/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj +++ b/src/libraries/System.Net.Sockets/src/System.Net.Sockets.csproj @@ -6,7 +6,7 @@ enable - SR.Sockets_PlatformNotSupported + SR.SystemNetSockets_PlatformNotSupported diff --git a/src/tests/tracing/eventpipe/reverse/reverse.csproj b/src/tests/tracing/eventpipe/reverse/reverse.csproj index 44835ac5980fad..cec9486b658b50 100644 --- a/src/tests/tracing/eventpipe/reverse/reverse.csproj +++ b/src/tests/tracing/eventpipe/reverse/reverse.csproj @@ -4,7 +4,7 @@ exe BuildAndRun true - 1 + 0 true true diff --git a/src/tests/tracing/eventpipe/reverseouter/reverseouter.csproj b/src/tests/tracing/eventpipe/reverseouter/reverseouter.csproj index 62665b29922abc..2c10c6ed465339 100644 --- a/src/tests/tracing/eventpipe/reverseouter/reverseouter.csproj +++ b/src/tests/tracing/eventpipe/reverseouter/reverseouter.csproj @@ -4,7 +4,7 @@ exe BuildAndRun true - 1 + 0 true true From dc003454e6f1b274c8229370be65bee78e4a27e7 Mon Sep 17 00:00:00 2001 From: John Salem Date: Mon, 20 Jul 2020 13:31:42 -0700 Subject: [PATCH 039/458] Add ProcessInfo command to Diagnostics Server (#38967) --- src/coreclr/src/vm/CMakeLists.txt | 2 + src/coreclr/src/vm/diagnosticserver.cpp | 54 +---- src/coreclr/src/vm/diagnosticserver.h | 8 - src/coreclr/src/vm/diagnosticsprotocol.h | 25 +-- src/coreclr/src/vm/eventpipeeventsource.h | 6 +- .../vm/processdiagnosticsprotocolhelper.cpp | 211 ++++++++++++++++++ .../src/vm/processdiagnosticsprotocolhelper.h | 59 +++++ .../tracing/eventpipe/common/IpcUtils.cs | 63 +++++- .../eventpipe/pauseonstart/pauseonstart.cs | 20 +- .../eventpipe/processinfo/processinfo.cs | 201 +++++++++++++++++ .../eventpipe/processinfo/processinfo.csproj | 15 ++ 11 files changed, 577 insertions(+), 87 deletions(-) create mode 100644 src/coreclr/src/vm/processdiagnosticsprotocolhelper.cpp create mode 100644 src/coreclr/src/vm/processdiagnosticsprotocolhelper.h create mode 100644 src/tests/tracing/eventpipe/processinfo/processinfo.cs create mode 100644 src/tests/tracing/eventpipe/processinfo/processinfo.csproj diff --git a/src/coreclr/src/vm/CMakeLists.txt b/src/coreclr/src/vm/CMakeLists.txt index 81d0e8c21b108d..fb36f5ca9b6ee1 100644 --- a/src/coreclr/src/vm/CMakeLists.txt +++ b/src/coreclr/src/vm/CMakeLists.txt @@ -379,6 +379,7 @@ set(VM_SOURCES_WKS objectlist.cpp olevariant.cpp pendingload.cpp + processdiagnosticsprotocolhelper.cpp profdetach.cpp profilermetadataemitvalidator.cpp profilingenumerators.cpp @@ -499,6 +500,7 @@ set(VM_HEADERS_WKS objectlist.h olevariant.h pendingload.h + processdiagnosticsprotocolhelper.h profdetach.h profilermetadataemitvalidator.h profilingenumerators.h diff --git a/src/coreclr/src/vm/diagnosticserver.cpp b/src/coreclr/src/vm/diagnosticserver.cpp index a843cf311a25cf..b04def7957b179 100644 --- a/src/coreclr/src/vm/diagnosticserver.cpp +++ b/src/coreclr/src/vm/diagnosticserver.cpp @@ -7,6 +7,7 @@ #include "eventpipeprotocolhelper.h" #include "dumpdiagnosticprotocolhelper.h" #include "profilerdiagnosticprotocolhelper.h" +#include "processdiagnosticsprotocolhelper.h" #include "diagnosticsprotocol.h" #ifdef TARGET_UNIX @@ -75,10 +76,6 @@ DWORD WINAPI DiagnosticServer::DiagnosticsServerThread(LPVOID) switch ((DiagnosticsIpc::DiagnosticServerCommandSet)message.GetHeader().CommandSet) { - case DiagnosticsIpc::DiagnosticServerCommandSet::Server: - DiagnosticServerProtocolHelper::HandleIpcMessage(message, pStream); - break; - case DiagnosticsIpc::DiagnosticServerCommandSet::EventPipe: EventPipeProtocolHelper::HandleIpcMessage(message, pStream); break; @@ -87,6 +84,10 @@ DWORD WINAPI DiagnosticServer::DiagnosticsServerThread(LPVOID) DumpDiagnosticProtocolHelper::HandleIpcMessage(message, pStream); break; + case DiagnosticsIpc::DiagnosticServerCommandSet::Process: + ProcessDiagnosticsProtocolHelper::HandleIpcMessage(message,pStream); + break; + #ifdef FEATURE_PROFAPI_ATTACH_DETACH case DiagnosticsIpc::DiagnosticServerCommandSet::Profiler: ProfilerDiagnosticProtocolHelper::HandleIpcMessage(message, pStream); @@ -291,49 +292,4 @@ void DiagnosticServer::ResumeRuntimeStartup() s_ResumeRuntimeStartupEvent->Set(); } -void DiagnosticServerProtocolHelper::HandleIpcMessage(DiagnosticsIpc::IpcMessage& message, IpcStream* pStream) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_ANY; - PRECONDITION(pStream != nullptr); - } - CONTRACTL_END; - - switch ((DiagnosticsIpc::DiagnosticServerCommandId)message.GetHeader().CommandId) - { - case DiagnosticsIpc::DiagnosticServerCommandId::ResumeRuntime: - DiagnosticServerProtocolHelper::ResumeRuntimeStartup(message, pStream); - break; - - default: - STRESS_LOG1(LF_DIAGNOSTICS_PORT, LL_WARNING, "Received unknown request type (%d)\n", message.GetHeader().CommandSet); - DiagnosticsIpc::IpcMessage::SendErrorMessage(pStream, CORDIAGIPC_E_UNKNOWN_COMMAND); - delete pStream; - break; - } -} - -void DiagnosticServerProtocolHelper::ResumeRuntimeStartup(DiagnosticsIpc::IpcMessage& message, IpcStream *pStream) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_PREEMPTIVE; - PRECONDITION(pStream != nullptr); - } - CONTRACTL_END; - - // no payload - DiagnosticServer::ResumeRuntimeStartup(); - HRESULT res = S_OK; - - DiagnosticsIpc::IpcMessage successResponse; - if (successResponse.Initialize(DiagnosticsIpc::GenericSuccessHeader, res)) - successResponse.Send(pStream); -} - #endif // FEATURE_PERFTRACING diff --git a/src/coreclr/src/vm/diagnosticserver.h b/src/coreclr/src/vm/diagnosticserver.h index b7ea71d84192f4..3e001d600ea567 100644 --- a/src/coreclr/src/vm/diagnosticserver.h +++ b/src/coreclr/src/vm/diagnosticserver.h @@ -36,14 +36,6 @@ class DiagnosticServer final static CLREventStatic *s_ResumeRuntimeStartupEvent; }; -class DiagnosticServerProtocolHelper -{ -public: - // IPC event handlers. - static void HandleIpcMessage(DiagnosticsIpc::IpcMessage& message, IpcStream *pStream); - static void ResumeRuntimeStartup(DiagnosticsIpc::IpcMessage& message, IpcStream *pStream); -}; - #endif // FEATURE_PERFTRACING #endif // __DIAGNOSTIC_SERVER_H__ diff --git a/src/coreclr/src/vm/diagnosticsprotocol.h b/src/coreclr/src/vm/diagnosticsprotocol.h index e3c471e80a212c..a31c698723a0f8 100644 --- a/src/coreclr/src/vm/diagnosticsprotocol.h +++ b/src/coreclr/src/vm/diagnosticsprotocol.h @@ -70,24 +70,15 @@ namespace DiagnosticsIpc Dump = 0x01, EventPipe = 0x02, Profiler = 0x03, + Process = 0x04, Server = 0xFF, }; - // Overlaps with DiagnosticServerResponseId - // DON'T create overlapping values - enum class DiagnosticServerCommandId : uint8_t - { - // 0x00 used in DiagnosticServerResponseId - ResumeRuntime = 0x01, - // 0xFF used DiagnosticServerResponseId - }; - - // Overlaps with DiagnosticServerCommandId - // DON'T create overlapping values enum class DiagnosticServerResponseId : uint8_t { OK = 0x00, + // future Error = 0xFF, }; @@ -206,12 +197,12 @@ namespace DiagnosticsIpc // // For more details on this pattern, look up "Substitution Failure Is Not An Error" or SFINAE - // template meta-programming to check for bool(Flatten)(void*) member function + // template meta-programming to check for bool(Flatten)(BYTE*&, uint16_t&) member function template struct HasFlatten { template struct Has; - template static std::true_type test(Has*); + template static std::true_type test(Has*); template static std::false_type test(...); static constexpr bool value = decltype(test(nullptr))::value; }; @@ -464,7 +455,7 @@ namespace DiagnosticsIpc // Handles the case where the payload structure exposes Flatten // and GetSize methods template ::value&& HasGetSize::value, int>::type = 0> + typename std::enable_if::value && HasGetSize::value, int>::type = 0> bool FlattenImpl(U& payload) { CONTRACTL @@ -483,6 +474,7 @@ namespace DiagnosticsIpc ASSERT(!temp_size.IsOverflow()); m_Size = temp_size.Value(); + uint16_t remainingBytes = temp_size.Value(); BYTE* temp_buffer = new (nothrow) BYTE[m_Size]; if (temp_buffer == nullptr) @@ -497,13 +489,14 @@ namespace DiagnosticsIpc memcpy(temp_buffer_cursor, &m_Header, sizeof(struct IpcHeader)); temp_buffer_cursor += sizeof(struct IpcHeader); + remainingBytes -= sizeof(struct IpcHeader); - payload.Flatten(temp_buffer_cursor); + const bool fSuccess = payload.Flatten(temp_buffer_cursor, remainingBytes); ASSERT(m_pData == nullptr); m_pData = temp_buffer; - return true; + return fSuccess; }; // handles the case where we were handed a struct with no Flatten or GetSize method diff --git a/src/coreclr/src/vm/eventpipeeventsource.h b/src/coreclr/src/vm/eventpipeeventsource.h index d271ce0f67f459..9100cbdef841f1 100644 --- a/src/coreclr/src/vm/eventpipeeventsource.h +++ b/src/coreclr/src/vm/eventpipeeventsource.h @@ -19,15 +19,15 @@ class EventPipeEventSource const static WCHAR* s_pProcessInfoEventName; EventPipeEvent *m_pProcessInfoEvent; - const static WCHAR* s_pOSInformation; - const static WCHAR* s_pArchInformation; - public: EventPipeEventSource(); ~EventPipeEventSource(); void Enable(EventPipeSession *pSession); void SendProcessInfo(LPCWSTR pCommandLine); + + const static WCHAR* s_pOSInformation; + const static WCHAR* s_pArchInformation; }; #endif // FEATURE_PERFTRACING diff --git a/src/coreclr/src/vm/processdiagnosticsprotocolhelper.cpp b/src/coreclr/src/vm/processdiagnosticsprotocolhelper.cpp new file mode 100644 index 00000000000000..e62f0d43b8cd6d --- /dev/null +++ b/src/coreclr/src/vm/processdiagnosticsprotocolhelper.cpp @@ -0,0 +1,211 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#include "common.h" +#include "fastserializer.h" +#include "processdiagnosticsprotocolhelper.h" +#include "eventpipeeventsource.h" +#include "diagnosticsprotocol.h" +#include "diagnosticserver.h" + +#ifdef FEATURE_PERFTRACING + +static inline uint32_t GetStringLength(const WCHAR *&value) +{ + return static_cast(wcslen(value) + 1); +} + +static bool TryWriteString(uint8_t * &bufferCursor, uint16_t &bufferLen, const WCHAR *value) +{ + uint32_t stringLen = GetStringLength(value); + S_UINT16 totalStringSizeInBytes(stringLen * sizeof(WCHAR) + sizeof(uint32_t)); + ASSERT(!totalStringSizeInBytes.IsOverflow()); + ASSERT(bufferLen >= totalStringSizeInBytes.Value()); + if (bufferLen < totalStringSizeInBytes.Value() || totalStringSizeInBytes.IsOverflow()) + return false; + + memcpy(bufferCursor, &stringLen, sizeof(stringLen)); + bufferCursor += sizeof(stringLen); + + memcpy(bufferCursor, value, stringLen * sizeof(WCHAR)); + bufferCursor += stringLen * sizeof(WCHAR); + + bufferLen -= totalStringSizeInBytes.Value(); + return true; +} + +uint16_t ProcessInfoPayload::GetSize() +{ + LIMITED_METHOD_CONTRACT; + + // see IPC spec @ https://github.com/dotnet/diagnostics/blob/master/documentation/design-docs/ipc-protocol.md + // for definition of serialization format + + // uint64_t ProcessId; -> 8 bytes + // GUID RuntimeCookie; -> 16 bytes + // LPCWSTR CommandLine; -> 4 bytes + strlen * sizeof(WCHAR) + // LPCWSTR OS; -> 4 bytes + strlen * sizeof(WCHAR) + // LPCWSTR Arch; -> 4 bytes + strlen * sizeof(WCHAR) + + S_UINT16 size = S_UINT16(0); + size += sizeof(ProcessId); + size += sizeof(RuntimeCookie); + + size += sizeof(uint32_t); + size += CommandLine != nullptr ? + S_UINT16(GetStringLength(CommandLine) * sizeof(WCHAR)) : + S_UINT16(0); + + size += sizeof(uint32_t); + size += OS != nullptr ? + S_UINT16(GetStringLength(OS) * sizeof(WCHAR)) : + S_UINT16(0); + + size += sizeof(uint32_t); + size += Arch != nullptr ? + S_UINT16(GetStringLength(Arch) * sizeof(WCHAR)) : + S_UINT16(0); + + ASSERT(!size.IsOverflow()); + return size.Value(); +} + +bool ProcessInfoPayload::Flatten(BYTE * &lpBuffer, uint16_t &cbSize) +{ + CONTRACTL + { + NOTHROW; + GC_TRIGGERS; + MODE_PREEMPTIVE; + PRECONDITION(cbSize == GetSize()); + PRECONDITION(lpBuffer != nullptr); + } + CONTRACTL_END; + + // see IPC spec @ https://github.com/dotnet/diagnostics/blob/master/documentation/design-docs/ipc-protocol.md + // for definition of serialization format + + bool fSuccess = true; + // uint64_t ProcessId; + memcpy(lpBuffer, &ProcessId, sizeof(ProcessId)); + lpBuffer += sizeof(ProcessId); + cbSize -= sizeof(ProcessId); + + // GUID RuntimeCookie; + memcpy(lpBuffer, &RuntimeCookie, sizeof(RuntimeCookie)); + lpBuffer += sizeof(RuntimeCookie); + cbSize -= sizeof(RuntimeCookie); + + // LPCWSTR CommandLine; + fSuccess &= TryWriteString(lpBuffer, cbSize, CommandLine); + + // LPCWSTR OS; + if (fSuccess) + fSuccess &= TryWriteString(lpBuffer, cbSize, OS); + + // LPCWSTR Arch; + if (fSuccess) + fSuccess &= TryWriteString(lpBuffer, cbSize, Arch); + + // Assert we've used the whole buffer we were given + ASSERT(cbSize == 0); + + return fSuccess; +} + +void ProcessDiagnosticsProtocolHelper::GetProcessInfo(DiagnosticsIpc::IpcMessage& message, IpcStream *pStream) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_PREEMPTIVE; + PRECONDITION(pStream != nullptr); + } + CONTRACTL_END; + + struct ProcessInfoPayload payload = {}; + + // Get cmdline + payload.CommandLine = GetManagedCommandLine(); + + // Checkout https://github.com/dotnet/coreclr/pull/24433 for more information about this fall back. + if (payload.CommandLine == nullptr) + { + // Use the result from GetCommandLineW() instead + payload.CommandLine = GetCommandLineW(); + } + + // get OS + Arch info + payload.OS = EventPipeEventSource::s_pOSInformation; + payload.Arch = EventPipeEventSource::s_pArchInformation; + + // Get the PID + payload.ProcessId = GetCurrentProcessId(); + + // Get the cookie + payload.RuntimeCookie = DiagnosticsIpc::GetAdvertiseCookie_V1(); + + DiagnosticsIpc::IpcMessage ProcessInfoResponse; + const bool fSuccess = ProcessInfoResponse.Initialize(DiagnosticsIpc::GenericSuccessHeader, payload) ? + ProcessInfoResponse.Send(pStream) : + DiagnosticsIpc::IpcMessage::SendErrorMessage(pStream, E_FAIL); + + if (!fSuccess) + STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_WARNING, "Failed to send DiagnosticsIPC response"); + + delete pStream; +} + +void ProcessDiagnosticsProtocolHelper::ResumeRuntimeStartup(DiagnosticsIpc::IpcMessage& message, IpcStream *pStream) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_PREEMPTIVE; + PRECONDITION(pStream != nullptr); + } + CONTRACTL_END; + + // no payload + DiagnosticServer::ResumeRuntimeStartup(); + HRESULT res = S_OK; + + DiagnosticsIpc::IpcMessage successResponse; + const bool fSuccess = successResponse.Initialize(DiagnosticsIpc::GenericSuccessHeader, res) ? + successResponse.Send(pStream) : + DiagnosticsIpc::IpcMessage::SendErrorMessage(pStream, E_FAIL); + if (!fSuccess) + STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_WARNING, "Failed to send DiagnosticsIPC response"); + + delete pStream; +} + +void ProcessDiagnosticsProtocolHelper::HandleIpcMessage(DiagnosticsIpc::IpcMessage& message, IpcStream* pStream) +{ + CONTRACTL + { + THROWS; + GC_TRIGGERS; + MODE_ANY; + PRECONDITION(pStream != nullptr); + } + CONTRACTL_END; + + switch ((ProcessCommandId)message.GetHeader().CommandId) + { + case ProcessCommandId::GetProcessInfo: + ProcessDiagnosticsProtocolHelper::GetProcessInfo(message, pStream); + break; + + default: + STRESS_LOG1(LF_DIAGNOSTICS_PORT, LL_WARNING, "Received unknown request type (%d)\n", message.GetHeader().CommandSet); + DiagnosticsIpc::IpcMessage::SendErrorMessage(pStream, CORDIAGIPC_E_UNKNOWN_COMMAND); + delete pStream; + break; + } +} + +#endif // FEATURE_PERFTRACING diff --git a/src/coreclr/src/vm/processdiagnosticsprotocolhelper.h b/src/coreclr/src/vm/processdiagnosticsprotocolhelper.h new file mode 100644 index 00000000000000..ac4e1e5d1d50e1 --- /dev/null +++ b/src/coreclr/src/vm/processdiagnosticsprotocolhelper.h @@ -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. +// See the LICENSE file in the project root for more information. + +#ifndef __PROCESS_PROTOCOL_HELPER_H__ +#define __PROCESS_PROTOCOL_HELPER_H__ + +#ifdef FEATURE_PERFTRACING + +#include "common.h" +#include "eventpipe.h" +#include "diagnosticsipc.h" +#include "diagnosticsprotocol.h" + +class IpcStream; + +// The event pipe command set is 0x02 +// see diagnosticsipc.h and diagnosticserver.h for more details +enum class ProcessCommandId : uint8_t +{ + GetProcessInfo = 0x00, + ResumeRuntime = 0x01, + // future +}; + +// command = 0x0400 +struct ProcessInfoPayload +{ + // The protocol buffer is defined as: + // X, Y, Z means encode bytes for X followed by bytes for Y followed by bytes for Z + // uint = 4 little endian bytes + // long = 8 little endian bytes + // GUID = 16 little endian bytes + // wchar = 2 little endian bytes, UTF16 encoding + // array = uint length, length # of Ts + // string = (array where the last char must = 0) or (length = 0) + + // ProcessInfo = long pid, string cmdline, string OS, string arch, GUID runtimeCookie + uint64_t ProcessId; + LPCWSTR CommandLine; + LPCWSTR OS; + LPCWSTR Arch; + GUID RuntimeCookie; + uint16_t GetSize(); + bool Flatten(BYTE * &lpBuffer, uint16_t& cbSize); +}; + +class ProcessDiagnosticsProtocolHelper +{ +public: + // IPC event handlers. + static void HandleIpcMessage(DiagnosticsIpc::IpcMessage& message, IpcStream *pStream); + static void GetProcessInfo(DiagnosticsIpc::IpcMessage& message, IpcStream *pStream); + static void ResumeRuntimeStartup(DiagnosticsIpc::IpcMessage& message, IpcStream *pStream); +}; + +#endif // FEATURE_PERFTRACING + +#endif // __PROCESS_PROTOCOL_HELPER_H__ diff --git a/src/tests/tracing/eventpipe/common/IpcUtils.cs b/src/tests/tracing/eventpipe/common/IpcUtils.cs index c9dbade684cb44..bf17e1e27e837b 100644 --- a/src/tests/tracing/eventpipe/common/IpcUtils.cs +++ b/src/tests/tracing/eventpipe/common/IpcUtils.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; +using System.IO.Pipes; using System.Net.Sockets; using System.Runtime.InteropServices; using System.Text; @@ -13,6 +14,7 @@ using System.Threading; using System.Linq; using System.Reflection; +using System.Security.Principal; // modified version of same code in dotnet/diagnostics for testing namespace Tracing.Tests.Common @@ -153,6 +155,12 @@ public static async Task RunSubprocess(Assembly currentAssembly, Dictionar return fSuccess; } + + public static void Assert(bool predicate, string message = "") + { + if (!predicate) + throw new Exception(message); + } } public class IpcHeader @@ -274,7 +282,7 @@ override public string ToString() { sb.Append("Payload=[ "); foreach (byte b in Payload) - sb.Append($"'{b:X4}' "); + sb.Append($"0x{b:X2} "); sb.Append(" ]"); } sb.Append("}"); @@ -316,4 +324,57 @@ private static IpcMessage Read(Stream stream) return IpcMessage.Parse(stream); } } + + public class ConnectionHelper + { + private static string IpcRootPath { get; } = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"\\.\pipe\" : Path.GetTempPath(); + public static Stream GetStandardTransport(int processId) + { + try + { + var process = Process.GetProcessById(processId); + } + catch (System.ArgumentException) + { + throw new Exception($"Process {processId} is not running."); + } + catch (System.InvalidOperationException) + { + throw new Exception($"Process {processId} seems to be elevated."); + } + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + string pipeName = $"dotnet-diagnostic-{processId}"; + var namedPipe = new NamedPipeClientStream( + ".", pipeName, PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.Impersonation); + namedPipe.Connect(3); + return namedPipe; + } + else + { + string ipcPort; + try + { + ipcPort = Directory.GetFiles(IpcRootPath, $"dotnet-diagnostic-{processId}-*-socket") // Try best match. + .OrderByDescending(f => new FileInfo(f).LastWriteTime) + .FirstOrDefault(); + if (ipcPort == null) + { + throw new Exception($"Process {processId} not running compatible .NET Core runtime."); + } + } + catch (InvalidOperationException) + { + throw new Exception($"Process {processId} not running compatible .NET Core runtime."); + } + string path = Path.Combine(IpcRootPath, ipcPort); + var remoteEP = new UnixDomainSocketEndPoint(path); + + var socket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified); + socket.Connect(remoteEP); + return new NetworkStream(socket, ownsSocket: true); + } + } + } } diff --git a/src/tests/tracing/eventpipe/pauseonstart/pauseonstart.cs b/src/tests/tracing/eventpipe/pauseonstart/pauseonstart.cs index 83782532d06ab4..4065cd586feef1 100644 --- a/src/tests/tracing/eventpipe/pauseonstart/pauseonstart.cs +++ b/src/tests/tracing/eventpipe/pauseonstart/pauseonstart.cs @@ -34,8 +34,8 @@ public static async Task TEST_RuntimeResumesExecutionWithCommand() Stream stream = await server.AcceptAsync(); IpcAdvertise advertise = IpcAdvertise.Parse(stream); Logger.logger.Log(advertise.ToString()); - // send ResumeRuntime command (0xFF=ServerCommandSet, 0x01=ResumeRuntime commandid) - var message = new IpcMessage(0xFF,0x01); + // send ResumeRuntime command (0x04=ProcessCommandSet, 0x01=ResumeRuntime commandid) + var message = new IpcMessage(0x04,0x01); Logger.logger.Log($"Sent: {message.ToString()}"); IpcMessage response = IpcClient.SendMessage(stream, message); Logger.logger.Log($"received: {response.ToString()}"); @@ -75,8 +75,8 @@ public static async Task TEST_TracesHaveRelevantEvents() Task readerTask = eventStream.CopyToAsync(memoryStream); Logger.logger.Log($"Send ResumeRuntime Diagnostics IPC Command"); - // send ResumeRuntime command (0xFF=ServerCommandSet, 0x01=ResumeRuntime commandid) - var message = new IpcMessage(0xFF,0x01); + // send ResumeRuntime command (0x04=ProcessCommandSet, 0x01=ResumeRuntime commandid) + var message = new IpcMessage(0x04,0x01); Logger.logger.Log($"Sent: {message.ToString()}"); IpcMessage response = IpcClient.SendMessage(stream, message); Logger.logger.Log($"received: {response.ToString()}"); @@ -145,8 +145,8 @@ public static async Task TEST_MultipleSessionsCanBeStartedWhilepaused() Logger.logger.Log($"Send ResumeRuntime Diagnostics IPC Command"); - // send ResumeRuntime command (0xFF=ServerCommandSet, 0x01=ResumeRuntime commandid) - var message = new IpcMessage(0xFF,0x01); + // send ResumeRuntime command (0x04=ProcessCommandSet, 0x01=ResumeRuntime commandid) + var message = new IpcMessage(0x04,0x01); Logger.logger.Log($"Sent: {message.ToString()}"); IpcMessage response = IpcClient.SendMessage(stream, message); Logger.logger.Log($"received: {response.ToString()}"); @@ -247,8 +247,8 @@ public static async Task TEST_CanStartAndStopSessionWhilepaused() Logger.logger.Log("Stopped EventPipeSession over standard connection"); Logger.logger.Log($"Send ResumeRuntime Diagnostics IPC Command"); - // send ResumeRuntime command (0xFF=ServerCommandSet, 0x01=ResumeRuntime commandid) - var message = new IpcMessage(0xFF,0x01); + // send ResumeRuntime command (0x04=ProcessCommandSet, 0x01=ResumeRuntime commandid) + var message = new IpcMessage(0x04,0x01); Logger.logger.Log($"Sent: {message.ToString()}"); IpcMessage response = IpcClient.SendMessage(stream, message); Logger.logger.Log($"received: {response.ToString()}"); @@ -292,8 +292,8 @@ public static async Task TEST_DisabledCommandsError() Logger.logger.Log(advertise.ToString()); Logger.logger.Log($"Send ResumeRuntime Diagnostics IPC Command"); - // send ResumeRuntime command (0xFF=ServerCommandSet, 0x01=ResumeRuntime commandid) - message = new IpcMessage(0xFF,0x01); + // send ResumeRuntime command (0x04=ProcessCommandSet, 0x01=ResumeRuntime commandid) + message = new IpcMessage(0x04,0x01); Logger.logger.Log($"Sent: {message.ToString()}"); response = IpcClient.SendMessage(stream, message); Logger.logger.Log($"received: {response.ToString()}"); diff --git a/src/tests/tracing/eventpipe/processinfo/processinfo.cs b/src/tests/tracing/eventpipe/processinfo/processinfo.cs new file mode 100644 index 00000000000000..f9f70605e1f5fe --- /dev/null +++ b/src/tests/tracing/eventpipe/processinfo/processinfo.cs @@ -0,0 +1,201 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Diagnostics.Tracing; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Diagnostics.Tools.RuntimeClient; +using Microsoft.Diagnostics.Tracing; +using Tracing.Tests.Common; + +namespace Tracing.Tests.ProcessInfoValidation +{ + public class ProcessInfoValidation + { + public static string NormalizeCommandLine(string cmdline) + { + // ASSUMPTION: double quotes (") and single quotes (') are used for paths with spaces + // ASSUMPTION: This test will only have two parts to the commandline + + // check for quotes in first part + var parts = new List(); + bool isQuoted = false; + int start = 0; + + for (int i = 0; i < cmdline.Length; i++) + { + if (isQuoted) + { + if (cmdline[i] == '"' || cmdline[i] == '\'') + { + parts.Add(cmdline.Substring(start, i - start)); + isQuoted = false; + start = i + 1; + } + } + else if (cmdline[i] == '"' || cmdline[i] == '\'') + { + isQuoted = true; + start = i + 1; + } + else if (cmdline[i] == ' ') + { + parts.Add(cmdline.Substring(start, i - start)); + start = i + 1; + } + else if (i == cmdline.Length - 1) + { + parts.Add(cmdline.Substring(start)); + } + } + + string normalizedCommandLine = parts + .Where(part => !string.IsNullOrWhiteSpace(part)) + .Select(part => (new FileInfo(part)).FullName) + .Aggregate((s1, s2) => string.Join(' ', s1, s2)); + + // Tests are run out of /tmp on Mac and linux, but on Mac /tmp is actually a symlink that points to /private/tmp. + // This isn't represented in the output from FileInfo.FullName unfortunately, so we'll fake that completion in that case. + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && normalizedCommandLine.StartsWith("/tmp/")) + normalizedCommandLine = "/private" + normalizedCommandLine; + + return normalizedCommandLine; + } + + public static int Main(string[] args) + { + + Process currentProcess = Process.GetCurrentProcess(); + int pid = currentProcess.Id; + Logger.logger.Log($"Test PID: {pid}"); + + Stream stream = ConnectionHelper.GetStandardTransport(pid); + + // 0x04 = ProcessCommandSet, 0x00 = ProcessInfo + var processInfoMessage = new IpcMessage(0x04, 0x00); + Logger.logger.Log($"Wrote: {processInfoMessage}"); + IpcMessage response = IpcClient.SendMessage(stream, processInfoMessage); + Logger.logger.Log($"Received: {response}"); + + Utils.Assert(response.Header.CommandSet == 0xFF, $"Response must have Server command set. Expected: 0xFF, Received: 0x{response.Header.CommandSet:X2}"); // server + Utils.Assert(response.Header.CommandId == 0x00, $"Response must have OK command id. Expected: 0x00, Received: 0x{response.Header.CommandId:X2}"); // OK + + // Parse payload + // uint64_t ProcessId; + // GUID RuntimeCookie; + // LPCWSTR CommandLine; + // LPCWSTR OS; + // LPCWSTR Arch; + + int totalSize = response.Payload.Length; + Logger.logger.Log($"Total size of Payload == {totalSize} b"); + + // VALIDATE PID + int start = 0; + int end = start + 8 /* sizeof(uint63_t) */; + UInt64 processId = BitConverter.ToUInt64(response.Payload[start..end]); + Utils.Assert((int)processId == pid, $"PID in process info must match. Expected: {pid}, Received: {processId}"); + Logger.logger.Log($"pid: {processId}"); + + // VALIDATE RUNTIME COOKIE + start = end; + end = start + 16 /* sizeof(GUID) */; + Guid runtimeCookie = new Guid(response.Payload[start..end]); + Logger.logger.Log($"runtimeCookie: {runtimeCookie}"); + + // VALIDATE COMMAND LINE + start = end; + end = start + 4 /* sizeof(uint32_t) */; + UInt32 commandLineLength = BitConverter.ToUInt32(response.Payload[start..end]); + Logger.logger.Log($"commandLineLength: {commandLineLength}"); + + start = end; + end = start + ((int)commandLineLength * sizeof(char)); + Utils.Assert(end <= totalSize, $"String end can't exceed payload size. Expected: <{totalSize}, Received: {end} (decoded length: {commandLineLength})"); + Logger.logger.Log($"commandLine bytes: [ {response.Payload[start..end].Select(b => b.ToString("X2") + " ").Aggregate(string.Concat)}]"); + string commandLine = System.Text.Encoding.Unicode.GetString(response.Payload[start..end]).TrimEnd('\0'); + Logger.logger.Log($"commandLine: \"{commandLine}\""); + + // The following logic is tailored to this specific test where the cmdline _should_ look like the following: + // /path/to/corerun /path/to/processinfo.dll + // or + // "C:\path\to\CoreRun.exe" C:\path\to\processinfo.dll + string currentProcessCommandLine = $"{currentProcess.MainModule.FileName} {System.Reflection.Assembly.GetExecutingAssembly().Location}"; + string receivedCommandLine = NormalizeCommandLine(commandLine); + + Utils.Assert(currentProcessCommandLine.Equals(receivedCommandLine, StringComparison.OrdinalIgnoreCase), $"CommandLine must match current process. Expected: {currentProcessCommandLine}, Received: {receivedCommandLine} (original: {commandLine})"); + + // VALIDATE OS + start = end; + end = start + 4 /* sizeof(uint32_t) */; + UInt32 OSLength = BitConverter.ToUInt32(response.Payload[start..end]); + Logger.logger.Log($"OSLength: {OSLength}"); + + start = end; + end = start + ((int)OSLength * sizeof(char)); + Utils.Assert(end <= totalSize, $"String end can't exceed payload size. Expected: <{totalSize}, Received: {end} (decoded length: {OSLength})"); + Logger.logger.Log($"OS bytes: [ {response.Payload[start..end].Select(b => b.ToString("X2") + " ").Aggregate(string.Concat)}]"); + string OS = System.Text.Encoding.Unicode.GetString(response.Payload[start..end]).TrimEnd('\0'); + Logger.logger.Log($"OS: \"{OS}\""); + + // see eventpipeeventsource.cpp for these values + string expectedOSValue = null; + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + expectedOSValue = "Windows"; + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + expectedOSValue = "macOS"; + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + expectedOSValue = "Linux"; + } + else + { + expectedOSValue = "Unknown"; + } + + Utils.Assert(expectedOSValue.Equals(OS), $"OS must match current Operating System. Expected: \"{expectedOSValue}\", Received: \"{OS}\""); + + // VALIDATE ARCH + start = end; + end = start + 4 /* sizeof(uint32_t) */; + UInt32 archLength = BitConverter.ToUInt32(response.Payload[start..end]); + Logger.logger.Log($"archLength: {archLength}"); + + start = end; + end = start + ((int)archLength * sizeof(char)); + Utils.Assert(end <= totalSize, $"String end can't exceed payload size. Expected: <{totalSize}, Received: {end} (decoded length: {archLength})"); + Logger.logger.Log($"arch bytes: [ {response.Payload[start..end].Select(b => b.ToString("X2") + " ").Aggregate(string.Concat)}]"); + string arch = System.Text.Encoding.Unicode.GetString(response.Payload[start..end]).TrimEnd('\0'); + Logger.logger.Log($"arch: \"{arch}\""); + + // see eventpipeeventsource.cpp for these values + string expectedArchValue = RuntimeInformation.ProcessArchitecture switch + { + Architecture.X86 => "x86", + Architecture.X64 => "x64", + Architecture.Arm => "arm32", + Architecture.Arm64 => "arm64", + _ => "Unknown" + }; + + Utils.Assert(expectedArchValue.Equals(arch), $"OS must match current Operating System. Expected: \"{expectedArchValue}\", Received: \"{arch}\""); + + Utils.Assert(end == totalSize, $"Full payload should have been read. Expected: {totalSize}, Received: {end}"); + + Logger.logger.Log($"\n{{\n\tprocessId: {processId},\n\truntimeCookie: {runtimeCookie},\n\tcommandLine: {commandLine},\n\tOS: {OS},\n\tArch: {arch}\n}}"); + + return 100; + } + } +} \ No newline at end of file diff --git a/src/tests/tracing/eventpipe/processinfo/processinfo.csproj b/src/tests/tracing/eventpipe/processinfo/processinfo.csproj new file mode 100644 index 00000000000000..6d5ae5ccf18d87 --- /dev/null +++ b/src/tests/tracing/eventpipe/processinfo/processinfo.csproj @@ -0,0 +1,15 @@ + + + .NETCoreApp + exe + BuildAndRun + true + 0 + true + true + + + + + + From d252f297d38c897ca889cf6e2f01d9766d758c87 Mon Sep 17 00:00:00 2001 From: Jeff Handley Date: Mon, 20 Jul 2020 13:34:18 -0700 Subject: [PATCH 040/458] Apply missing obsolete attributes in src; fix attribute ordering (#39607) * Apply missing obsolete attributes in src; fix attribute ordering * Only obsolete the constructors of PolicyStatement --- .../ref/System.Security.Permissions.cs | 16 ++++++++-------- .../ConfigurationPermissionAttribute.cs | 3 +++ .../Data/Common/DBDataPermissionAttribute.cs | 3 +++ .../OracleClient/OraclePermissionAttribute.cs | 3 +++ .../Diagnostics/EventLogPermissionAttribute.cs | 3 +++ .../PerformanceCounterPermissionAttribute.cs | 3 +++ .../Printing/PrintingPermissionAttribute.cs | 3 +++ .../src/System/Net/DnsPermissionAttribute.cs | 3 +++ .../System/Net/Mail/SmtpPermissionAttribute.cs | 3 +++ .../NetworkInformationPermissionAttribute.cs | 3 +++ .../PeerCollaborationPermissionAttribute.cs | 3 +++ .../Net/PeerToPeer/PnrpPermissionAttribute.cs | 3 +++ .../src/System/Net/SocketPermissionAttribute.cs | 3 +++ .../src/System/Net/WebPermissionAttribute.cs | 3 +++ .../src/System/Security/CodeAccessPermission.cs | 3 +++ .../src/System/Security/NamedPermissionSet.cs | 3 +++ .../src/System/Security/Policy/GacInstalled.cs | 3 +++ .../Policy/IIdentityPermissionFactory.cs | 3 +++ .../src/System/Security/Policy/PolicyLevel.cs | 15 +++++++++++++++ .../System/Security/Policy/PolicyStatement.cs | 6 ++++++ .../src/System/Security/Policy/Publisher.cs | 3 +++ .../src/System/Security/Policy/Site.cs | 3 +++ .../src/System/Security/Policy/Url.cs | 3 +++ .../src/System/Security/Policy/Zone.cs | 3 +++ .../ServiceControllerPermissionAttribute.cs | 3 +++ .../DistributedTransactionPermissionAttribute.cs | 3 +++ .../Web/AspNetHostingPermissionAttribute.cs | 3 +++ 27 files changed, 101 insertions(+), 8 deletions(-) diff --git a/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.cs b/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.cs index 81c59db3baa11b..0ef3beb0bad3ed 100644 --- a/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.cs +++ b/src/libraries/System.Security.Permissions/ref/System.Security.Permissions.cs @@ -31,10 +31,10 @@ public override void FromXml(System.Security.SecurityElement securityElement) { public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } - [System.AttributeUsageAttribute(System.AttributeTargets.All, AllowMultiple=true, Inherited=false)] #if NET50_OBSOLETIONS [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif + [System.AttributeUsageAttribute(System.AttributeTargets.All, AllowMultiple=true, Inherited=false)] public sealed partial class ConfigurationPermissionAttribute : System.Security.Permissions.CodeAccessSecurityAttribute { public ConfigurationPermissionAttribute(System.Security.Permissions.SecurityAction action) : base (default(System.Security.Permissions.SecurityAction)) { } @@ -402,10 +402,10 @@ public override void FromXml(System.Security.SecurityElement securityElement) { public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } - [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] #if NET50_OBSOLETIONS [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif + [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] public sealed partial class SocketPermissionAttribute : System.Security.Permissions.CodeAccessSecurityAttribute { public SocketPermissionAttribute(System.Security.Permissions.SecurityAction action) : base (default(System.Security.Permissions.SecurityAction)) { } @@ -444,10 +444,10 @@ public override void FromXml(System.Security.SecurityElement securityElement) { public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } - [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] #if NET50_OBSOLETIONS [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif + [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] public sealed partial class WebPermissionAttribute : System.Security.Permissions.CodeAccessSecurityAttribute { public WebPermissionAttribute(System.Security.Permissions.SecurityAction action) : base (default(System.Security.Permissions.SecurityAction)) { } @@ -885,10 +885,10 @@ public void SetPathList(System.Security.Permissions.EnvironmentPermissionAccess public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission other) { throw null; } } - [System.FlagsAttribute] #if NET50_OBSOLETIONS [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif + [System.FlagsAttribute] public enum EnvironmentPermissionAccess { NoAccess = 0, @@ -896,10 +896,10 @@ public enum EnvironmentPermissionAccess Write = 2, AllAccess = 3, } - [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] #if NET50_OBSOLETIONS [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif + [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] public sealed partial class EnvironmentPermissionAttribute : System.Security.Permissions.CodeAccessSecurityAttribute { public EnvironmentPermissionAttribute(System.Security.Permissions.SecurityAction action) : base (default(System.Security.Permissions.SecurityAction)) { } @@ -1199,10 +1199,10 @@ public KeyContainerPermissionAccessEntryEnumerator() { } public bool MoveNext() { throw null; } public void Reset() { } } - [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] #if NET50_OBSOLETIONS [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif + [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] public sealed partial class KeyContainerPermissionAttribute : System.Security.Permissions.CodeAccessSecurityAttribute { public KeyContainerPermissionAttribute(System.Security.Permissions.SecurityAction action) : base (default(System.Security.Permissions.SecurityAction)) { } @@ -1253,10 +1253,10 @@ public override void FromXml(System.Security.SecurityElement securityElement) { public override System.Security.SecurityElement ToXml() { throw null; } public override System.Security.IPermission Union(System.Security.IPermission target) { throw null; } } - [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] #if NET50_OBSOLETIONS [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif + [System.AttributeUsageAttribute(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Struct, AllowMultiple=true, Inherited=false)] public sealed partial class MediaPermissionAttribute : System.Security.Permissions.CodeAccessSecurityAttribute { public MediaPermissionAttribute(System.Security.Permissions.SecurityAction action) : base (default(System.Security.Permissions.SecurityAction)) { } @@ -1337,10 +1337,10 @@ public void FromXml(System.Security.SecurityElement elem) { } public System.Security.SecurityElement ToXml() { throw null; } public System.Security.IPermission Union(System.Security.IPermission other) { throw null; } } - [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true, Inherited=false)] #if NET50_OBSOLETIONS [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] #endif + [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true, Inherited=false)] public sealed partial class PrincipalPermissionAttribute : System.Security.Permissions.CodeAccessSecurityAttribute { #if NET50_OBSOLETIONS diff --git a/src/libraries/System.Security.Permissions/src/System/Configuration/ConfigurationPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Configuration/ConfigurationPermissionAttribute.cs index 0ca7d38ca2d008..9df7cd35683b29 100644 --- a/src/libraries/System.Security.Permissions/src/System/Configuration/ConfigurationPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Configuration/ConfigurationPermissionAttribute.cs @@ -6,6 +6,9 @@ namespace System.Configuration { +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)] public sealed class ConfigurationPermissionAttribute : CodeAccessSecurityAttribute { diff --git a/src/libraries/System.Security.Permissions/src/System/Data/Common/DBDataPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Data/Common/DBDataPermissionAttribute.cs index 097ba88c304bf4..57a0c5fbd2c84a 100644 --- a/src/libraries/System.Security.Permissions/src/System/Data/Common/DBDataPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Data/Common/DBDataPermissionAttribute.cs @@ -5,6 +5,9 @@ namespace System.Data.Common { +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor| AttributeTargets.Method, AllowMultiple =true, Inherited =false)] public abstract class DBDataPermissionAttribute : CodeAccessSecurityAttribute diff --git a/src/libraries/System.Security.Permissions/src/System/Data/OracleClient/OraclePermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Data/OracleClient/OraclePermissionAttribute.cs index fb871718b77df1..8b702005afc7e1 100644 --- a/src/libraries/System.Security.Permissions/src/System/Data/OracleClient/OraclePermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Data/OracleClient/OraclePermissionAttribute.cs @@ -5,6 +5,9 @@ namespace System.Data.OracleClient { +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = true, Inherited = false)] public sealed class OraclePermissionAttribute : CodeAccessSecurityAttribute diff --git a/src/libraries/System.Security.Permissions/src/System/Diagnostics/EventLogPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Diagnostics/EventLogPermissionAttribute.cs index f06e73cb9cd58e..fdfd74de52aa28 100644 --- a/src/libraries/System.Security.Permissions/src/System/Diagnostics/EventLogPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Diagnostics/EventLogPermissionAttribute.cs @@ -6,6 +6,9 @@ namespace System.Diagnostics { +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Event, AllowMultiple = true, Inherited = false)] public class EventLogPermissionAttribute : CodeAccessSecurityAttribute diff --git a/src/libraries/System.Security.Permissions/src/System/Diagnostics/PerformanceCounterPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Diagnostics/PerformanceCounterPermissionAttribute.cs index 20c92891cdc497..90768d8236992e 100644 --- a/src/libraries/System.Security.Permissions/src/System/Diagnostics/PerformanceCounterPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Diagnostics/PerformanceCounterPermissionAttribute.cs @@ -5,6 +5,9 @@ using System.Security.Permissions; namespace System.Diagnostics { +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Event, AllowMultiple = true, Inherited = false)] public class PerformanceCounterPermissionAttribute : CodeAccessSecurityAttribute diff --git a/src/libraries/System.Security.Permissions/src/System/Drawing/Printing/PrintingPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Drawing/Printing/PrintingPermissionAttribute.cs index 1a16545a647dad..307637f8542bd7 100644 --- a/src/libraries/System.Security.Permissions/src/System/Drawing/Printing/PrintingPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Drawing/Printing/PrintingPermissionAttribute.cs @@ -5,6 +5,9 @@ namespace System.Drawing.Printing { +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif [AttributeUsage(AttributeTargets.All, AllowMultiple = true)] public sealed class PrintingPermissionAttribute : CodeAccessSecurityAttribute { diff --git a/src/libraries/System.Security.Permissions/src/System/Net/DnsPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Net/DnsPermissionAttribute.cs index 89edcd32473724..024858147b93e3 100644 --- a/src/libraries/System.Security.Permissions/src/System/Net/DnsPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Net/DnsPermissionAttribute.cs @@ -6,6 +6,9 @@ namespace System.Net { +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)] public sealed class DnsPermissionAttribute : CodeAccessSecurityAttribute diff --git a/src/libraries/System.Security.Permissions/src/System/Net/Mail/SmtpPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Net/Mail/SmtpPermissionAttribute.cs index 9366ed61721081..607fb1bf78d1b6 100644 --- a/src/libraries/System.Security.Permissions/src/System/Net/Mail/SmtpPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Net/Mail/SmtpPermissionAttribute.cs @@ -6,6 +6,9 @@ namespace System.Net.Mail { +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)] public sealed class SmtpPermissionAttribute : CodeAccessSecurityAttribute diff --git a/src/libraries/System.Security.Permissions/src/System/Net/NetworkInformation/NetworkInformationPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Net/NetworkInformation/NetworkInformationPermissionAttribute.cs index b8ed459bbfc0a8..80321fe7f85af6 100644 --- a/src/libraries/System.Security.Permissions/src/System/Net/NetworkInformation/NetworkInformationPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Net/NetworkInformation/NetworkInformationPermissionAttribute.cs @@ -6,6 +6,9 @@ namespace System.Net.NetworkInformation { +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)] public sealed class NetworkInformationPermissionAttribute : CodeAccessSecurityAttribute { diff --git a/src/libraries/System.Security.Permissions/src/System/Net/PeerToPeer/Collaboration/PeerCollaborationPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Net/PeerToPeer/Collaboration/PeerCollaborationPermissionAttribute.cs index c1fd9c189917b3..5b4b924db05b22 100644 --- a/src/libraries/System.Security.Permissions/src/System/Net/PeerToPeer/Collaboration/PeerCollaborationPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Net/PeerToPeer/Collaboration/PeerCollaborationPermissionAttribute.cs @@ -6,6 +6,9 @@ namespace System.Net.PeerToPeer.Collaboration { +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = true, Inherited = false)] public sealed class PeerCollaborationPermissionAttribute : CodeAccessSecurityAttribute diff --git a/src/libraries/System.Security.Permissions/src/System/Net/PeerToPeer/PnrpPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Net/PeerToPeer/PnrpPermissionAttribute.cs index e85697d11fce49..499eeba5d96a62 100644 --- a/src/libraries/System.Security.Permissions/src/System/Net/PeerToPeer/PnrpPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Net/PeerToPeer/PnrpPermissionAttribute.cs @@ -6,6 +6,9 @@ namespace System.Net.PeerToPeer { +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = true, Inherited = false)] public sealed class PnrpPermissionAttribute : CodeAccessSecurityAttribute diff --git a/src/libraries/System.Security.Permissions/src/System/Net/SocketPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Net/SocketPermissionAttribute.cs index ed5cc2d8b32232..09a111fc98c771 100644 --- a/src/libraries/System.Security.Permissions/src/System/Net/SocketPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Net/SocketPermissionAttribute.cs @@ -6,6 +6,9 @@ namespace System.Net { +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)] public sealed class SocketPermissionAttribute : CodeAccessSecurityAttribute diff --git a/src/libraries/System.Security.Permissions/src/System/Net/WebPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Net/WebPermissionAttribute.cs index 0e584d79e4f094..45621281bb1762 100644 --- a/src/libraries/System.Security.Permissions/src/System/Net/WebPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Net/WebPermissionAttribute.cs @@ -6,6 +6,9 @@ namespace System.Net { +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly, AllowMultiple = true, Inherited = false)] public sealed class WebPermissionAttribute : CodeAccessSecurityAttribute diff --git a/src/libraries/System.Security.Permissions/src/System/Security/CodeAccessPermission.cs b/src/libraries/System.Security.Permissions/src/System/Security/CodeAccessPermission.cs index fe77fe0f78d359..148282d0c8091a 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/CodeAccessPermission.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/CodeAccessPermission.cs @@ -3,6 +3,9 @@ namespace System.Security { +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif public abstract partial class CodeAccessPermission : IPermission, ISecurityEncodable, IStackWalk { protected CodeAccessPermission() { } diff --git a/src/libraries/System.Security.Permissions/src/System/Security/NamedPermissionSet.cs b/src/libraries/System.Security.Permissions/src/System/Security/NamedPermissionSet.cs index 100f003274826e..372e95632f73f5 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/NamedPermissionSet.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/NamedPermissionSet.cs @@ -5,6 +5,9 @@ namespace System.Security { +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif public sealed partial class NamedPermissionSet : PermissionSet { public NamedPermissionSet(NamedPermissionSet permSet) : base(default(PermissionState)) { } diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Policy/GacInstalled.cs b/src/libraries/System.Security.Permissions/src/System/Security/Policy/GacInstalled.cs index 991f0a38c7b08e..a1520e9222f744 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Policy/GacInstalled.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Policy/GacInstalled.cs @@ -3,6 +3,9 @@ namespace System.Security.Policy { +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif public sealed partial class GacInstalled : EvidenceBase, IIdentityPermissionFactory { public GacInstalled() { } diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Policy/IIdentityPermissionFactory.cs b/src/libraries/System.Security.Permissions/src/System/Security/Policy/IIdentityPermissionFactory.cs index 6b9f9da8a0cfb4..92762151cbbfa5 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Policy/IIdentityPermissionFactory.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Policy/IIdentityPermissionFactory.cs @@ -3,6 +3,9 @@ namespace System.Security.Policy { +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif public partial interface IIdentityPermissionFactory { IPermission CreateIdentityPermission(Evidence evidence); diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Policy/PolicyLevel.cs b/src/libraries/System.Security.Permissions/src/System/Security/Policy/PolicyLevel.cs index 7a89e9b500f875..477fb70e4a749f 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Policy/PolicyLevel.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Policy/PolicyLevel.cs @@ -19,18 +19,33 @@ internal PolicyLevel() { } public void AddFullTrustAssembly(StrongName sn) { } [Obsolete("Because all GAC assemblies always get full trust, the full trust list is no longer meaningful. You should install any assemblies that are used in security policy in the GAC to ensure they are trusted.")] public void AddFullTrustAssembly(StrongNameMembershipCondition snMC) { } +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif public void AddNamedPermissionSet(NamedPermissionSet permSet) { } +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif public NamedPermissionSet ChangeNamedPermissionSet(string name, PermissionSet pSet) { return default(NamedPermissionSet); } [Obsolete("AppDomain policy levels are obsolete. See https://go.microsoft.com/fwlink/?LinkID=155570 for more information.")] public static PolicyLevel CreateAppDomainLevel() { return default(PolicyLevel); } public void FromXml(SecurityElement e) { } +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif public NamedPermissionSet GetNamedPermissionSet(string name) { return default(NamedPermissionSet); } public void Recover() { } [Obsolete("Because all GAC assemblies always get full trust, the full trust list is no longer meaningful. You should install any assemblies that are used in security policy in the GAC to ensure they are trusted.")] public void RemoveFullTrustAssembly(StrongName sn) { } [Obsolete("Because all GAC assemblies always get full trust, the full trust list is no longer meaningful. You should install any assemblies that are used in security policy in the GAC to ensure they are trusted.")] public void RemoveFullTrustAssembly(StrongNameMembershipCondition snMC) { } +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif public NamedPermissionSet RemoveNamedPermissionSet(NamedPermissionSet permSet) { return default(NamedPermissionSet); } +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif public NamedPermissionSet RemoveNamedPermissionSet(string name) { return default(NamedPermissionSet); } public void Reset() { } public PolicyStatement Resolve(Evidence evidence) { return default(PolicyStatement); } diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Policy/PolicyStatement.cs b/src/libraries/System.Security.Permissions/src/System/Security/Policy/PolicyStatement.cs index b73ae5d42c254c..788a094602d7f1 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Policy/PolicyStatement.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Policy/PolicyStatement.cs @@ -5,7 +5,13 @@ namespace System.Security.Policy { public sealed partial class PolicyStatement : ISecurityEncodable, ISecurityPolicyEncodable { +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif public PolicyStatement(PermissionSet permSet) { } +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif public PolicyStatement(PermissionSet permSet, PolicyStatementAttribute attributes) { } public PolicyStatementAttribute Attributes { get; set; } public string AttributeString { get { return null; } } diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Policy/Publisher.cs b/src/libraries/System.Security.Permissions/src/System/Security/Policy/Publisher.cs index 5a149a7acab90f..89fe1cab5c2b6d 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Policy/Publisher.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Policy/Publisher.cs @@ -5,6 +5,9 @@ namespace System.Security.Policy { +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif public sealed partial class Publisher : EvidenceBase, IIdentityPermissionFactory { public Publisher(X509Certificate cert) { } diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Policy/Site.cs b/src/libraries/System.Security.Permissions/src/System/Security/Policy/Site.cs index 8d88da1e9a6d56..c7975c9ec5aabe 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Policy/Site.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Policy/Site.cs @@ -3,6 +3,9 @@ namespace System.Security.Policy { +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif public sealed partial class Site : EvidenceBase, IIdentityPermissionFactory { public Site(string name) { } diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Policy/Url.cs b/src/libraries/System.Security.Permissions/src/System/Security/Policy/Url.cs index 0264b2c02849a7..e7ec73638ab14a 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Policy/Url.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Policy/Url.cs @@ -3,6 +3,9 @@ namespace System.Security.Policy { +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif public sealed partial class Url : EvidenceBase, IIdentityPermissionFactory { public Url(string name) { } diff --git a/src/libraries/System.Security.Permissions/src/System/Security/Policy/Zone.cs b/src/libraries/System.Security.Permissions/src/System/Security/Policy/Zone.cs index c63c8360eaa8db..1f7b0950f57add 100644 --- a/src/libraries/System.Security.Permissions/src/System/Security/Policy/Zone.cs +++ b/src/libraries/System.Security.Permissions/src/System/Security/Policy/Zone.cs @@ -3,6 +3,9 @@ namespace System.Security.Policy { +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif public sealed partial class Zone : EvidenceBase, IIdentityPermissionFactory { public Zone(SecurityZone zone) { } diff --git a/src/libraries/System.Security.Permissions/src/System/ServiceProcess/ServiceControllerPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/ServiceProcess/ServiceControllerPermissionAttribute.cs index 5c822963b26b6f..34f03504f9291a 100644 --- a/src/libraries/System.Security.Permissions/src/System/ServiceProcess/ServiceControllerPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/ServiceProcess/ServiceControllerPermissionAttribute.cs @@ -6,6 +6,9 @@ namespace System.ServiceProcess { +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Assembly | AttributeTargets.Event, AllowMultiple = true, Inherited = false )] public class ServiceControllerPermissionAttribute : CodeAccessSecurityAttribute { diff --git a/src/libraries/System.Security.Permissions/src/System/Transactions/DistributedTransactionPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Transactions/DistributedTransactionPermissionAttribute.cs index 1bc89cbd615410..9b2844136c2d8f 100644 --- a/src/libraries/System.Security.Permissions/src/System/Transactions/DistributedTransactionPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Transactions/DistributedTransactionPermissionAttribute.cs @@ -6,6 +6,9 @@ namespace System.Transactions { +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif [AttributeUsage(AttributeTargets.All, AllowMultiple = true)] public sealed class DistributedTransactionPermissionAttribute : CodeAccessSecurityAttribute { diff --git a/src/libraries/System.Security.Permissions/src/System/Web/AspNetHostingPermissionAttribute.cs b/src/libraries/System.Security.Permissions/src/System/Web/AspNetHostingPermissionAttribute.cs index ebf6eec3b367b5..9078711ecac83c 100644 --- a/src/libraries/System.Security.Permissions/src/System/Web/AspNetHostingPermissionAttribute.cs +++ b/src/libraries/System.Security.Permissions/src/System/Web/AspNetHostingPermissionAttribute.cs @@ -6,6 +6,9 @@ namespace System.Web { +#if NET50_OBSOLETIONS + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] +#endif [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false )] public sealed class AspNetHostingPermissionAttribute : CodeAccessSecurityAttribute { From 0a1f7ba9475c78e6a8894a076f57a05baa6c1697 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Mon, 20 Jul 2020 15:42:22 -0500 Subject: [PATCH 041/458] Allow Debugger attributes to be trimmed in Mono (#39479) * Allow Debugger attributes to be trimmed in Mono. Changed debugger-agent to allow for the Debugger Attributes to not exist. Removed the Debugger Attributes entries from the Descriptors.xml file. Fix https://github.com/mono/linker/issues/1355 * Use GENERATE_TRY_GET_CLASS_WITH_CACHE to initialize Debugger attribute pointers. --- src/mono/mono/metadata/class.c | 2 +- src/mono/mono/mini/debugger-agent.c | 30 ++++++++----------- .../src/ILLink/ILLink.Descriptors.xml | 5 ---- 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/src/mono/mono/metadata/class.c b/src/mono/mono/metadata/class.c index bfd02a8eb736c9..bc3b46b7f7609f 100644 --- a/src/mono/mono/metadata/class.c +++ b/src/mono/mono/metadata/class.c @@ -3448,7 +3448,7 @@ mono_class_from_name (MonoImage *image, const char* name_space, const char *name * * This function works exactly like mono_class_from_name but it will abort if the class is not found. * This function should be used by the runtime for critical types to which there's no way to recover but crash - * If they are missing. Thing of System.Object or System.String. + * if they are missing. For example, System.Object or System.String. */ MonoClass * mono_class_load_from_name (MonoImage *image, const char* name_space, const char *name) diff --git a/src/mono/mono/mini/debugger-agent.c b/src/mono/mono/mini/debugger-agent.c index f76e887e6db885..ace0affe8d73b6 100644 --- a/src/mono/mono/mini/debugger-agent.c +++ b/src/mono/mono/mini/debugger-agent.c @@ -3598,6 +3598,10 @@ dbg_path_get_basename (const char *filename) return g_strdup (&r[1]); } +GENERATE_TRY_GET_CLASS_WITH_CACHE(hidden_klass, "System.Diagnostics", "DebuggerHiddenAttribute") +GENERATE_TRY_GET_CLASS_WITH_CACHE(step_through_klass, "System.Diagnostics", "DebuggerStepThroughAttribute") +GENERATE_TRY_GET_CLASS_WITH_CACHE(non_user_klass, "System.Diagnostics", "DebuggerNonUserCodeAttribute") + static void init_jit_info_dbg_attrs (MonoJitInfo *ji) { @@ -3607,27 +3611,19 @@ init_jit_info_dbg_attrs (MonoJitInfo *ji) if (ji->dbg_attrs_inited) return; - MONO_STATIC_POINTER_INIT (MonoClass, hidden_klass) - hidden_klass = mono_class_load_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerHiddenAttribute"); - MONO_STATIC_POINTER_INIT_END (MonoClass, hidden_klass) - - - MONO_STATIC_POINTER_INIT (MonoClass, step_through_klass) - step_through_klass = mono_class_load_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerStepThroughAttribute"); - MONO_STATIC_POINTER_INIT_END (MonoClass, step_through_klass) - - MONO_STATIC_POINTER_INIT (MonoClass, non_user_klass) - non_user_klass = mono_class_load_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerNonUserCodeAttribute"); - MONO_STATIC_POINTER_INIT_END (MonoClass, non_user_klass) + // NOTE: The following Debugger attributes may not exist if they are trimmed away by the ILLinker + MonoClass *hidden_klass = mono_class_try_get_hidden_klass_class (); + MonoClass *step_through_klass = mono_class_try_get_step_through_klass_class (); + MonoClass *non_user_klass = mono_class_try_get_non_user_klass_class (); ainfo = mono_custom_attrs_from_method_checked (jinfo_get_method (ji), error); mono_error_cleanup (error); /* FIXME don't swallow the error? */ if (ainfo) { - if (mono_custom_attrs_has_attr (ainfo, hidden_klass)) + if (hidden_klass && mono_custom_attrs_has_attr (ainfo, hidden_klass)) ji->dbg_hidden = TRUE; - if (mono_custom_attrs_has_attr (ainfo, step_through_klass)) + if (step_through_klass && mono_custom_attrs_has_attr (ainfo, step_through_klass)) ji->dbg_step_through = TRUE; - if (mono_custom_attrs_has_attr (ainfo, non_user_klass)) + if (non_user_klass && mono_custom_attrs_has_attr (ainfo, non_user_klass)) ji->dbg_non_user_code = TRUE; mono_custom_attrs_free (ainfo); } @@ -3635,9 +3631,9 @@ init_jit_info_dbg_attrs (MonoJitInfo *ji) ainfo = mono_custom_attrs_from_class_checked (jinfo_get_method (ji)->klass, error); mono_error_cleanup (error); /* FIXME don't swallow the error? */ if (ainfo) { - if (mono_custom_attrs_has_attr (ainfo, step_through_klass)) + if (step_through_klass && mono_custom_attrs_has_attr (ainfo, step_through_klass)) ji->dbg_step_through = TRUE; - if (mono_custom_attrs_has_attr (ainfo, non_user_klass)) + if (non_user_klass && mono_custom_attrs_has_attr (ainfo, non_user_klass)) ji->dbg_non_user_code = TRUE; mono_custom_attrs_free (ainfo); } diff --git a/src/mono/netcore/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml b/src/mono/netcore/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml index 788f2c616784c9..244f9da5b3ac58 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml +++ b/src/mono/netcore/System.Private.CoreLib/src/ILLink/ILLink.Descriptors.xml @@ -142,11 +142,6 @@ - - - - - From 874399ab15e47c2b4b7c6533cc37d27d47cb5242 Mon Sep 17 00:00:00 2001 From: Aaron Robinson Date: Mon, 20 Jul 2020 14:24:50 -0700 Subject: [PATCH 042/458] Declare AllowReversePInvokeCallsAttribute as Obsolete. (#39636) --- .../AllowReversePInvokeCallsAttribute.cs | 4 ++-- .../tests/Resources/Interop/Interop.Mock01.cs | 1 - .../ref/System.Runtime.InteropServices.cs | 1 + ...ystem.Runtime.InteropServices.Tests.csproj | 1 - .../AllowReversePInvokeCallsAttributeTests.cs | 24 ------------------- 5 files changed, 3 insertions(+), 28 deletions(-) delete mode 100644 src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/AllowReversePInvokeCallsAttributeTests.cs diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/AllowReversePInvokeCallsAttribute.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/AllowReversePInvokeCallsAttribute.cs index 5b14e88c4beec7..99b3a57a3dbbdb 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/AllowReversePInvokeCallsAttribute.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/AllowReversePInvokeCallsAttribute.cs @@ -3,8 +3,8 @@ namespace System.Runtime.InteropServices { - // To be used on methods that sink reverse P/Invoke calls. - // This attribute was a Silverlight security measure, currently ignored. + // This attribute was a Silverlight security measure and is no longer respected. + [Obsolete(Obsoletions.CodeAccessSecurityMessage, DiagnosticId = Obsoletions.CodeAccessSecurityDiagId, UrlFormat = Obsoletions.SharedUrlFormat)] [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] public sealed class AllowReversePInvokeCallsAttribute : Attribute { diff --git a/src/libraries/System.Reflection.Metadata/tests/Resources/Interop/Interop.Mock01.cs b/src/libraries/System.Reflection.Metadata/tests/Resources/Interop/Interop.Mock01.cs index 612ed4111311fa..0ad8ac99a04ec4 100644 --- a/src/libraries/System.Reflection.Metadata/tests/Resources/Interop/Interop.Mock01.cs +++ b/src/libraries/System.Reflection.Metadata/tests/Resources/Interop/Interop.Mock01.cs @@ -98,7 +98,6 @@ InteropEnum IFooReadOnlyProp { [TypeLibImportClass(typeof(object))] public interface IBar { - [AllowReversePInvokeCalls()] object DoSomething(params string[] ary); [ComRegisterFunction()] object Register([MarshalAs(UnmanagedType.IDispatch), Optional, DefaultParameterValue(null)] ref object o); diff --git a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs index 62a71240547237..e4860f7e25ebc9 100644 --- a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs +++ b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs @@ -91,6 +91,7 @@ public IUnknownConstantAttribute() { } } namespace System.Runtime.InteropServices { + [System.ObsoleteAttribute("Code Access Security is not supported or honored by the runtime.", DiagnosticId = "SYSLIB0003", UrlFormat = "https://aka.ms/dotnet-warnings/{0}")] [System.AttributeUsageAttribute(System.AttributeTargets.Method, AllowMultiple=false, Inherited=false)] public sealed partial class AllowReversePInvokeCallsAttribute : System.Attribute { diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.Tests.csproj b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.Tests.csproj index 1e6ec37d556191..a4dab3d3151a35 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.Tests.csproj +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.Tests.csproj @@ -8,7 +8,6 @@ - diff --git a/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/AllowReversePInvokeCallsAttributeTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/AllowReversePInvokeCallsAttributeTests.cs deleted file mode 100644 index e2a9f2ecdca386..00000000000000 --- a/src/libraries/System.Runtime.InteropServices/tests/System/Runtime/InteropServices/AllowReversePInvokeCallsAttributeTests.cs +++ /dev/null @@ -1,24 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Linq; -using System.Reflection; -using Xunit; - -namespace System.Runtime.InteropServices.Tests -{ - public class AllowReversePInvokeCallsAttributeTests - { - [AllowReversePInvokeCalls] - private int Func(int a, int b) => a + b; - - [Fact] - public void Exists() - { - Type type = typeof(AllowReversePInvokeCallsAttributeTests); - MethodInfo method = type.GetTypeInfo().DeclaredMethods.Single(m => m.Name == "Func"); - AllowReversePInvokeCallsAttribute attribute = Assert.Single(method.GetCustomAttributes< AllowReversePInvokeCallsAttribute>(inherit: false)); - Assert.NotNull(attribute); - } - } -} From 36041c5c24e7cd9ed964283278013f70eb0c980b Mon Sep 17 00:00:00 2001 From: Koundinya Veluri Date: Mon, 20 Jul 2020 18:00:19 -0400 Subject: [PATCH 043/458] Fix tiering assertion failures from concurrent or reentering JIT of the same native code version (#39643) Fix tiering assertion failures from concurrent or reentering JIT of the same native code version Allowed disabling call counting multiple times. Fixes https://github.com/dotnet/runtime/issues/39604 --- src/coreclr/src/vm/callcounting.cpp | 11 ++++++++++- src/coreclr/src/vm/prestub.cpp | 14 ++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/coreclr/src/vm/callcounting.cpp b/src/coreclr/src/vm/callcounting.cpp index aadb400295cda8..45edd54b8d355a 100644 --- a/src/coreclr/src/vm/callcounting.cpp +++ b/src/coreclr/src/vm/callcounting.cpp @@ -474,7 +474,16 @@ void CallCountingManager::DisableCallCounting(NativeCodeVersion codeVersion) CodeVersionManager::LockHolder codeVersioningLockHolder; - _ASSERTE(m_callCountingInfoByCodeVersionHash.Lookup(codeVersion) == nullptr); + CallCountingInfo *callCountingInfo = m_callCountingInfoByCodeVersionHash.Lookup(codeVersion); + if (callCountingInfo != nullptr) + { + // Call counting may already have been disabled due to the possibility of concurrent or reentering JIT of the same + // native code version of a method. The call counting info is created with call counting enabled or disabled and it + // cannot be changed thereafter for consistency in dependents of the info. + _ASSERTE(callCountingInfo->GetStage() == CallCountingInfo::Stage::Disabled); + return; + } + NewHolder callCountingInfoHolder = CallCountingInfo::CreateWithCallCountingDisabled(codeVersion); m_callCountingInfoByCodeVersionHash.Add(callCountingInfoHolder); callCountingInfoHolder.SuppressRelease(); diff --git a/src/coreclr/src/vm/prestub.cpp b/src/coreclr/src/vm/prestub.cpp index c6a3a58f98d3e3..dd7ca44aaf9dc1 100644 --- a/src/coreclr/src/vm/prestub.cpp +++ b/src/coreclr/src/vm/prestub.cpp @@ -1063,11 +1063,21 @@ PCODE MethodDesc::JitCompileCodeLocked(PrepareCodeConfig* pConfig, JitListLockEn bool shouldCountCalls = false; if (pFlags->IsSet(CORJIT_FLAGS::CORJIT_FLAG_TIER0)) { - _ASSERTE(pConfig->GetCodeVersion().GetOptimizationTier() == NativeCodeVersion::OptimizationTier0); _ASSERTE(pConfig->GetMethodDesc()->IsEligibleForTieredCompilation()); if (pConfig->JitSwitchedToOptimized()) { +#ifdef _DEBUG + // Call counting may already have been disabled due to the possibility of concurrent or reentering JIT of the same + // native code version of a method. The current optimization tier should be consistent with the change being made + // (Tier 0 to Optimized), such that the tier is not changed in an unexpected way or at an unexpected time. Since + // changes to the optimization tier are unlocked, this assertion is just a speculative check on possible values. + NativeCodeVersion::OptimizationTier previousOptimizationTier = pConfig->GetCodeVersion().GetOptimizationTier(); + _ASSERTE( + previousOptimizationTier == NativeCodeVersion::OptimizationTier0 || + previousOptimizationTier == NativeCodeVersion::OptimizationTierOptimized); +#endif // _DEBUG + // Update the tier in the code version. The JIT may have decided to switch from tier 0 to optimized, in which case // call counting would have to be disabled for the method. NativeCodeVersion codeVersion = pConfig->GetCodeVersion(); @@ -1082,7 +1092,7 @@ PCODE MethodDesc::JitCompileCodeLocked(PrepareCodeConfig* pConfig, JitListLockEn shouldCountCalls = true; } } -#endif +#endif // FEATURE_TIERED_COMPILATION // Aside from rejit, performing a SetNativeCodeInterlocked at this point // generally ensures that there is only one winning version of the native From 25b610624eb73b9c6c6c299ecd4d513650492bbf Mon Sep 17 00:00:00 2001 From: Levi Broderick Date: Mon, 20 Jul 2020 15:02:34 -0700 Subject: [PATCH 044/458] Revert "Fix resx test name mangling logic" (#39644) * Revert "Fix resx test name mangling logic" This reverts commit 6af0d0e09a3b00a3a79033f7d26670b2563405fa. * Add comment warning not to change this code --- .../tests/TestData.cs | 51 +++--------------- .../tests/TestData.resources | Bin 8828 -> 8184 bytes 2 files changed, 8 insertions(+), 43 deletions(-) diff --git a/src/libraries/System.Resources.Extensions/tests/TestData.cs b/src/libraries/System.Resources.Extensions/tests/TestData.cs index e71619c276a673..afef1125985eb5 100644 --- a/src/libraries/System.Resources.Extensions/tests/TestData.cs +++ b/src/libraries/System.Resources.Extensions/tests/TestData.cs @@ -303,8 +303,15 @@ public override void BindToName(Type serializedType, out string assemblyName, ou // workaround for https://github.com/dotnet/runtime/issues/31289 assemblyQualifiedTypeName = assemblyQualifiedTypeName.Replace(s_coreAssemblyName, s_mscorlibAssemblyName); - if (TryDeconstructFullyQualifiedTypeName(assemblyQualifiedTypeName, out string newTypeName, out assemblyName)) + // The logic below is intentionally incorrect. Generic type names like System.Collections.Generic.List`1[[System.String, ...]] + // will be split on the first comma, causing unbalanced [[ and ]] in the resulting substrings. This is for compatibility + // with the existing incorrect logic in Full Framework. + + int pos = assemblyQualifiedTypeName.IndexOf(','); + if (pos > 0 && pos < assemblyQualifiedTypeName.Length - 1) { + assemblyName = assemblyQualifiedTypeName.Substring(pos + 1).TrimStart(); + string newTypeName = assemblyQualifiedTypeName.Substring(0, pos); if (!string.Equals(newTypeName, serializedType.FullName, StringComparison.InvariantCulture)) { typeName = newTypeName; @@ -319,48 +326,6 @@ public override Type BindToType(string assemblyName, string typeName) // We should never be using this binder during Deserialization throw new NotSupportedException($"{nameof(TypeNameManglingSerializationBinder)}.{nameof(BindToType)} should not be used during testing."); } - - private static bool TryDeconstructFullyQualifiedTypeName(string assemblyQualifiedTypeName, out string typeName, out string assemblyName) - { - // Skip over all generic arguments in the assembly-qualified type name. - - int genericDepth = 0; - int i; - for (i = 0; i < assemblyQualifiedTypeName.Length; i++) - { - switch (assemblyQualifiedTypeName[i]) - { - case '[': - checked { genericDepth++; } - break; - - case ']': - checked { genericDepth--; } - break; - - case ',' when genericDepth == 0: - goto AfterLoop; - - default: - continue; - } - } - - AfterLoop: - - if (i < assemblyQualifiedTypeName.Length - 1) - { - // Found a proper fully-qualified type name with assembly! - typeName = assemblyQualifiedTypeName.Substring(0, i); - assemblyName = assemblyQualifiedTypeName.Substring(i + 1).Trim(); - return true; - } - - // Couldn't find an assembly after the type name. - typeName = default; - assemblyName = default; - return false; - } } } } diff --git a/src/libraries/System.Resources.Extensions/tests/TestData.resources b/src/libraries/System.Resources.Extensions/tests/TestData.resources index 6b7552d4314159f50e0e8ea3d37fa6c28967c223..b2f4b4cd1928883e15073f7033e78217b6800728 100644 GIT binary patch delta 1021 zcmc&xO=uHQ5T5sv-DdxqY?s(1yUixvib!k^r57p1>ZwtC@lrLUx~*bNOMa9}rHD5# zwhnku@FX4rLN%axQ#=cL^arH~(u+k8LcxO0Y$Aw=mmXYrv-5r5%)FU-+Y?)3YgOH` z6ae!y%tI4qpaKC*Xm~}>_ZKyQL;zLd&qIl{v*aJs@QI$6sNp+3ZNH=teU_5up$rXp zt)Xi8&U<224sO6la#Q4D!br*u4UZVE{H$Tc7)*cC0b-n4g*o_O0A#uV%P~i882H@S zBflE>#n>yi4fM^V+G7Ib7VxCy%X=nHo9@U#3t(4`dOk&$m7q?x7WO#@lO*YNYI~8$ z0Hz6gU5KSv(mm19&rk<7PVVR-=uH`!bKx-^AayU&Pf!v9tUFu4f8()XO=1VYqkR6Q6hl um%TxETc;7S?5f_5Ec#n6_Irq-FhxvMB>)4%^=A0G) z`ZUZ#2$RqRAD&BG(JGk@31IusB76? gHK2Z;~03g4sSD=n9r)&aEh)HDwb=)jzg zLV8X>s8He#EYLGcPqby4FX=cT3w%Y#rX0xy20%h}wqORPOn`j9z(&I1O%tEU{X8`B zvpm4Bn&|0iag9{vOL)%k_&y8I=!HY;7Qj$Io~P(zb!gKaL_TNW8BtoBY%db%!)q#s z`z6*B>B7b~e}NnXqy(J*qreRm8`}l9e-&<%Kx%d~-l<<^M;#~_*8lw)| zMOpspV$j8#M#VB+S~iTFbs+8HBcqtg6Q+excq#(V#ZQLk>?KqWX_FmeRTs-(Tg5jX2E#xFOTq0g9zQ$vh^s-V9EL|J%T^R!v>mNraqQ+sVm0 NJ;2As{2%alKLC5j&?^7{ From 73247415306f537ef831f83b891d5559439ca182 Mon Sep 17 00:00:00 2001 From: Carlos Sanchez Lopez <1175054+carlossanlop@users.noreply.github.com> Date: Mon, 20 Jul 2020 15:04:40 -0700 Subject: [PATCH 045/458] AdvSimd support for System.Text.Unicode.Utf8Utility.TranscodeToUtf8 (#39041) * AdvSimd support for System.Text.Unicode.Utf8Utility.TranscodeToUtf8 * Readd using to prevent build failure. Add AdvSimd equivalent operation to TestZ. * Inverted condition * Address IsSupported order, improve use ExtractNarrowingSaturated usage * Rename source to result, second argument utf16Data * Improve CompareTest * Add shims causing failures in Linux * Use unsigned version of ExtractNarrowingSaturate, avoid using MinAcross and use MaxPairwise instead * Missing support check for Sse2.X64 * Add missing case for AdvSimd * Use MinPairwise for short --- .../Text/Unicode/Utf8Utility.Transcoding.cs | 64 +++++++++++++++---- .../Runtime/Intrinsics/Intrinsics.Shims.cs | 1 + 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.Transcoding.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.Transcoding.cs index ee9f789a40fab0..b0c1376611b9e7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.Transcoding.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.Transcoding.cs @@ -6,6 +6,7 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; using System.Runtime.Intrinsics.X86; #if SYSTEM_PRIVATE_CORELIB @@ -882,7 +883,7 @@ public static OperationStatus TranscodeToUtf8(char* pInputBuffer, int inputLengt // is not enabled. Unsafe.SkipInit(out Vector128 nonAsciiUtf16DataMask); - if (Sse41.X64.IsSupported) + if (Sse41.X64.IsSupported || (AdvSimd.Arm64.IsSupported && BitConverter.IsLittleEndian)) { nonAsciiUtf16DataMask = Vector128.Create(unchecked((short)0xFF80)); // mask of non-ASCII bits in a UTF-16 char } @@ -940,10 +941,8 @@ public static OperationStatus TranscodeToUtf8(char* pInputBuffer, int inputLengt uint inputCharsRemaining = (uint)(pFinalPosWhereCanReadDWordFromInputBuffer - pInputBuffer) + 2; uint minElementsRemaining = (uint)Math.Min(inputCharsRemaining, outputBytesRemaining); - if (Sse41.X64.IsSupported) + if (Sse41.X64.IsSupported || (AdvSimd.Arm64.IsSupported && BitConverter.IsLittleEndian)) { - Debug.Assert(BitConverter.IsLittleEndian, "SSE41 requires little-endian."); - // Try reading and writing 8 elements per iteration. uint maxIters = minElementsRemaining / 8; ulong possibleNonAsciiQWord; @@ -952,14 +951,30 @@ public static OperationStatus TranscodeToUtf8(char* pInputBuffer, int inputLengt for (i = 0; (uint)i < maxIters; i++) { utf16Data = Unsafe.ReadUnaligned>(pInputBuffer); - if (!Sse41.TestZ(utf16Data, nonAsciiUtf16DataMask)) + + if (AdvSimd.IsSupported) { - goto LoopTerminatedDueToNonAsciiDataInVectorLocal; - } + Vector128 isUtf16DataNonAscii = AdvSimd.CompareTest(utf16Data, nonAsciiUtf16DataMask); + bool hasNonAsciiDataInVector = AdvSimd.Arm64.MinPairwise(isUtf16DataNonAscii, isUtf16DataNonAscii).AsUInt64().ToScalar() != 0; - // narrow and write + if (hasNonAsciiDataInVector) + { + goto LoopTerminatedDueToNonAsciiDataInVectorLocal; + } - Sse2.StoreScalar((ulong*)pOutputBuffer /* unaligned */, Sse2.PackUnsignedSaturate(utf16Data, utf16Data).AsUInt64()); + Vector64 lower = AdvSimd.ExtractNarrowingSaturateUnsignedLower(utf16Data); + AdvSimd.Store(pOutputBuffer, lower); + } + else + { + if (!Sse41.TestZ(utf16Data, nonAsciiUtf16DataMask)) + { + goto LoopTerminatedDueToNonAsciiDataInVectorLocal; + } + + // narrow and write + Sse2.StoreScalar((ulong*)pOutputBuffer /* unaligned */, Sse2.PackUnsignedSaturate(utf16Data, utf16Data).AsUInt64()); + } pInputBuffer += 8; pOutputBuffer += 8; @@ -978,7 +993,16 @@ public static OperationStatus TranscodeToUtf8(char* pInputBuffer, int inputLengt } utf16Data = Vector128.CreateScalarUnsafe(possibleNonAsciiQWord).AsInt16(); - Unsafe.WriteUnaligned(pOutputBuffer, Sse2.ConvertToUInt32(Sse2.PackUnsignedSaturate(utf16Data, utf16Data).AsUInt32())); + + if (AdvSimd.IsSupported) + { + Vector64 lower = AdvSimd.ExtractNarrowingSaturateUnsignedLower(utf16Data); + AdvSimd.StoreSelectedScalar((uint*)pOutputBuffer, lower.AsUInt32(), 0); + } + else + { + Unsafe.WriteUnaligned(pOutputBuffer, Sse2.ConvertToUInt32(Sse2.PackUnsignedSaturate(utf16Data, utf16Data).AsUInt32())); + } pInputBuffer += 4; pOutputBuffer += 4; @@ -990,7 +1014,15 @@ public static OperationStatus TranscodeToUtf8(char* pInputBuffer, int inputLengt LoopTerminatedDueToNonAsciiDataInVectorLocal: outputBytesRemaining -= 8 * i; - possibleNonAsciiQWord = Sse2.X64.ConvertToUInt64(utf16Data.AsUInt64()); + + if (Sse2.X64.IsSupported) + { + possibleNonAsciiQWord = Sse2.X64.ConvertToUInt64(utf16Data.AsUInt64()); + } + else + { + possibleNonAsciiQWord = utf16Data.AsUInt64().ToScalar(); + } // Temporarily set 'possibleNonAsciiQWord' to be the low 64 bits of the vector, // then check whether it's all-ASCII. If so, narrow and write to the destination @@ -1000,7 +1032,15 @@ public static OperationStatus TranscodeToUtf8(char* pInputBuffer, int inputLengt if (Utf16Utility.AllCharsInUInt64AreAscii(possibleNonAsciiQWord)) // all chars in first QWORD are ASCII { - Unsafe.WriteUnaligned(pOutputBuffer, Sse2.ConvertToUInt32(Sse2.PackUnsignedSaturate(utf16Data, utf16Data).AsUInt32())); + if (AdvSimd.IsSupported) + { + Vector64 lower = AdvSimd.ExtractNarrowingSaturateUnsignedLower(utf16Data); + AdvSimd.StoreSelectedScalar((uint*)pOutputBuffer, lower.AsUInt32(), 0); + } + else + { + Unsafe.WriteUnaligned(pOutputBuffer, Sse2.ConvertToUInt32(Sse2.PackUnsignedSaturate(utf16Data, utf16Data).AsUInt32())); + } pInputBuffer += 4; pOutputBuffer += 4; outputBytesRemaining -= 4; diff --git a/src/libraries/System.Utf8String.Experimental/src/System/Runtime/Intrinsics/Intrinsics.Shims.cs b/src/libraries/System.Utf8String.Experimental/src/System/Runtime/Intrinsics/Intrinsics.Shims.cs index c4c68e966eba22..fa4602b33f429f 100644 --- a/src/libraries/System.Utf8String.Experimental/src/System/Runtime/Intrinsics/Intrinsics.Shims.cs +++ b/src/libraries/System.Utf8String.Experimental/src/System/Runtime/Intrinsics/Intrinsics.Shims.cs @@ -8,6 +8,7 @@ internal static class Vector64 public static Vector64 Create(ulong value) => throw new PlatformNotSupportedException(); public static Vector64 CreateScalar(uint value) => throw new PlatformNotSupportedException(); public static Vector64 AsByte(this Vector64 vector) where T : struct => throw new PlatformNotSupportedException(); + public static Vector64 AsUInt32(this Vector64 vector) where T : struct => throw new PlatformNotSupportedException(); } internal readonly struct Vector64 where T : struct From 9d88a948ba3c18a9bea2217ad51828913701c2eb Mon Sep 17 00:00:00 2001 From: Carlos Sanchez Lopez <1175054+carlossanlop@users.noreply.github.com> Date: Mon, 20 Jul 2020 15:26:22 -0700 Subject: [PATCH 046/458] AdvSimd support for System.Text.Unicode.Utf8Utility.GetPointerToFirstInvalidByte (#38653) * AdvSimd support for System.Text.Unicode.Utf8Utility.GetPointerToFirstInvalidByte * Move comment to the top, add shims. * Little endian checks * Use custom MoveMask method for AdvSimd * Address suggestions to improve the AdvSimdMoveMask method * Define initialMask outside MoveMask method * UInt64 in Arm64MoveMask * Add unit test case to verify intrinsics improvement * Avoid casting to smaller integer type * Typo and comment * Use ShiftRightArithmetic instead of CompareEqual + And. Remove test case causing other unit tests to fail. * Use AddPairwise version of GetNotAsciiBytes * Add missing shims causing Linux build to fail * Simplify GetNonAsciiBytes to only one AddPairwise call, shorter bitmask * Respect data type returned by masking method * Address suggestions - assert trailingzerocount and bring back uint mask * Trailing zeroes in AdvSimd need to be divided by 4, and total number should not be larger than 16 * Avoid declaring static field which causes PNSE in Utf8String.Experimental (S.P.Corelib code is used for being NetStandard) * Prefer using nuint for BitConverter.TrailingZeroCount --- .../Text/Unicode/Utf8Utility.Validation.cs | 64 ++++++++++++++----- 1 file changed, 47 insertions(+), 17 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.Validation.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.Validation.cs index 33e5181363920b..7730708030ebaf 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.Validation.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf8Utility.Validation.cs @@ -4,6 +4,8 @@ using System.Diagnostics; using System.Numerics; using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; using System.Runtime.Intrinsics.X86; #if SYSTEM_PRIVATE_CORELIB @@ -117,22 +119,35 @@ internal static unsafe partial class Utf8Utility // the alignment check consumes at most a single DWORD.) byte* pInputBufferFinalPosAtWhichCanSafelyLoop = pFinalPosWhereCanReadDWordFromInputBuffer - 3 * sizeof(uint); // can safely read 4 DWORDs here - uint mask; + nuint trailingZeroCount; + + Vector128 bitMask128 = BitConverter.IsLittleEndian ? + Vector128.Create((ushort)0x1001).AsByte() : + Vector128.Create((ushort)0x0110).AsByte(); do { - if (Sse2.IsSupported) + // pInputBuffer is 32-bit aligned but not necessary 128-bit aligned, so we're + // going to perform an unaligned load. We don't necessarily care about aligning + // this because we pessimistically assume we'll encounter non-ASCII data at some + // point in the not-too-distant future (otherwise we would've stayed entirely + // within the all-ASCII vectorized code at the entry to this method). + if (AdvSimd.Arm64.IsSupported && BitConverter.IsLittleEndian) { - // pInputBuffer is 32-bit aligned but not necessary 128-bit aligned, so we're - // going to perform an unaligned load. We don't necessarily care about aligning - // this because we pessimistically assume we'll encounter non-ASCII data at some - // point in the not-too-distant future (otherwise we would've stayed entirely - // within the all-ASCII vectorized code at the entry to this method). - - mask = (uint)Sse2.MoveMask(Sse2.LoadVector128((byte*)pInputBuffer)); + ulong mask = GetNonAsciiBytes(AdvSimd.LoadVector128(pInputBuffer), bitMask128); + if (mask != 0) + { + trailingZeroCount = (nuint)BitOperations.TrailingZeroCount(mask) >> 2; + goto LoopTerminatedEarlyDueToNonAsciiData; + } + } + else if (Sse2.IsSupported) + { + uint mask = (uint)Sse2.MoveMask(Sse2.LoadVector128(pInputBuffer)); if (mask != 0) { - goto Sse2LoopTerminatedEarlyDueToNonAsciiData; + trailingZeroCount = (nuint)BitOperations.TrailingZeroCount(mask); + goto LoopTerminatedEarlyDueToNonAsciiData; } } else @@ -153,19 +168,20 @@ internal static unsafe partial class Utf8Utility continue; // need to perform a bounds check because we might be running out of data - Sse2LoopTerminatedEarlyDueToNonAsciiData: + LoopTerminatedEarlyDueToNonAsciiData: + // x86 can only be little endian, while ARM can be big or little endian + // so if we reached this label we need to check both combinations are supported + Debug.Assert((AdvSimd.Arm64.IsSupported && BitConverter.IsLittleEndian) || Sse2.IsSupported); - Debug.Assert(BitConverter.IsLittleEndian); - Debug.Assert(Sse2.IsSupported); // The 'mask' value will have a 0 bit for each ASCII byte we saw and a 1 bit - // for each non-ASCII byte we saw. We can count the number of ASCII bytes, + // for each non-ASCII byte we saw. trailingZeroCount will count the number of ASCII bytes, // bump our input counter by that amount, and resume processing from the // "the first byte is no longer ASCII" portion of the main loop. + // We should not expect a total number of zeroes equal or larger than 16. + Debug.Assert(trailingZeroCount < 16); - Debug.Assert(mask != 0); - - pInputBuffer += BitOperations.TrailingZeroCount(mask); + pInputBuffer += trailingZeroCount; if (pInputBuffer > pFinalPosWhereCanReadDWordFromInputBuffer) { goto ProcessRemainingBytesSlow; @@ -719,5 +735,19 @@ internal static unsafe partial class Utf8Utility scalarCountAdjustment = tempScalarCountAdjustment; return pInputBuffer; } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static ulong GetNonAsciiBytes(Vector128 value, Vector128 bitMask128) + { + if (!AdvSimd.Arm64.IsSupported || !BitConverter.IsLittleEndian) + { + throw new PlatformNotSupportedException(); + } + + Vector128 mostSignificantBitIsSet = AdvSimd.ShiftRightArithmetic(value.AsSByte(), 7).AsByte(); + Vector128 extractedBits = AdvSimd.And(mostSignificantBitIsSet, bitMask128); + extractedBits = AdvSimd.Arm64.AddPairwise(extractedBits, extractedBits); + return extractedBits.AsUInt64().ToScalar(); + } } } From 562763b5498bf53b68517b68221a89ad80ef6d16 Mon Sep 17 00:00:00 2001 From: Carlos Sanchez Lopez <1175054+carlossanlop@users.noreply.github.com> Date: Mon, 20 Jul 2020 15:35:59 -0700 Subject: [PATCH 047/458] Fix build failure in net472 debug AdvSimd Utf16Utility (#39652) --- .../Text/Unicode/Utf16Utility.Validation.cs | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf16Utility.Validation.cs b/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf16Utility.Validation.cs index cd4e6627d84455..f2df0ccdf53c42 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf16Utility.Validation.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Text/Unicode/Utf16Utility.Validation.cs @@ -87,6 +87,11 @@ static Utf16Utility() Vector128 vectorA800 = Vector128.Create((ushort)0xA800); Vector128 vector8800 = Vector128.Create(unchecked((short)0x8800)); Vector128 vectorZero = Vector128.Zero; + + Vector128 bitMask128 = BitConverter.IsLittleEndian ? + Vector128.Create(0x80402010_08040201).AsByte() : + Vector128.Create(0x01020408_10204080).AsByte(); + do { Vector128 utf16Data; @@ -127,7 +132,7 @@ static Utf16Utility() uint debugMask; if (AdvSimd.Arm64.IsSupported) { - debugMask = GetNonAsciiBytes(charIsNonAscii.AsByte()); + debugMask = GetNonAsciiBytes(charIsNonAscii.AsByte(), bitMask128); } else { @@ -145,7 +150,7 @@ static Utf16Utility() if (AdvSimd.IsSupported) { charIsThreeByteUtf8Encoded = AdvSimd.Subtract(vectorZero, AdvSimd.ShiftRightLogical(utf16Data, 11)); - mask = GetNonAsciiBytes(AdvSimd.Or(charIsNonAscii, charIsThreeByteUtf8Encoded).AsByte()); + mask = GetNonAsciiBytes(AdvSimd.Or(charIsNonAscii, charIsThreeByteUtf8Encoded).AsByte(), bitMask128); } else { @@ -185,7 +190,7 @@ static Utf16Utility() if (AdvSimd.Arm64.IsSupported) { utf16Data = AdvSimd.Add(utf16Data, vectorA800); - mask = GetNonAsciiBytes(AdvSimd.CompareLessThan(utf16Data.AsInt16(), vector8800).AsByte()); + mask = GetNonAsciiBytes(AdvSimd.CompareLessThan(utf16Data.AsInt16(), vector8800).AsByte(), bitMask128); } else { @@ -219,7 +224,7 @@ static Utf16Utility() uint mask2; if (AdvSimd.Arm64.IsSupported) { - mask2 = GetNonAsciiBytes(AdvSimd.ShiftRightLogical(utf16Data, 3).AsByte()); + mask2 = GetNonAsciiBytes(AdvSimd.ShiftRightLogical(utf16Data, 3).AsByte(), bitMask128); } else { @@ -480,17 +485,13 @@ static Utf16Utility() return pInputBuffer; } - private static readonly Vector128 s_bitMask128 = BitConverter.IsLittleEndian ? - Vector128.Create(0x80402010_08040201).AsByte() : - Vector128.Create(0x01020408_10204080).AsByte(); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static uint GetNonAsciiBytes(Vector128 value) + private static uint GetNonAsciiBytes(Vector128 value, Vector128 bitMask128) { Debug.Assert(AdvSimd.Arm64.IsSupported); Vector128 mostSignificantBitIsSet = AdvSimd.ShiftRightArithmetic(value.AsSByte(), 7).AsByte(); - Vector128 extractedBits = AdvSimd.And(mostSignificantBitIsSet, s_bitMask128); + Vector128 extractedBits = AdvSimd.And(mostSignificantBitIsSet, bitMask128); // self-pairwise add until all flags have moved to the first two bytes of the vector extractedBits = AdvSimd.Arm64.AddPairwise(extractedBits, extractedBits); From c44ea8f15c4ea39d5870230ab83436841bcaef39 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 21 Jul 2020 01:51:08 +0200 Subject: [PATCH 048/458] [master] Update dependencies from mono/linker Microsoft/vstest dotnet/runtime-assets dotnet/llvm-project dotnet/icu (#39516) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update dependencies from https://github.com/mono/linker build 20200716.2 Microsoft.NET.ILLink.Tasks From Version 5.0.0-preview.3.20363.5 -> To Version 5.0.0-preview.3.20366.2 * Update dependencies from https://github.com/microsoft/vstest build 20200716-03 Microsoft.NET.Test.Sdk From Version 16.8.0-preview-20200708-01 -> To Version 16.8.0-preview-20200716-03 * Update dependencies from https://github.com/dotnet/runtime-assets build 20200714.1 System.ComponentModel.TypeConverter.TestData , System.Drawing.Common.TestData , System.IO.Compression.TestData , System.IO.Packaging.TestData , System.Net.TestData , System.Private.Runtime.UnicodeData , System.Security.Cryptography.X509Certificates.TestData , System.Windows.Extensions.TestData From Version 5.0.0-beta.20360.1 -> To Version 5.0.0-beta.20364.1 * Update dependencies from https://github.com/dotnet/llvm-project build 20200715.1 runtime.linux-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools , runtime.win-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools , runtime.win-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk , runtime.osx.10.12-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools , runtime.osx.10.12-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk , runtime.linux-x64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk , runtime.linux-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Tools , runtime.linux-arm64.Microsoft.NETCore.Runtime.Mono.LLVM.Sdk From Version 9.0.1-alpha.1.20356.1 -> To Version 9.0.1-alpha.1.20365.1 * Update dependencies from https://github.com/dotnet/icu build 20200716.2 Microsoft.NETCore.Runtime.ICU.Transport From Version 5.0.0-preview.8.20365.1 -> To Version 5.0.0-preview.8.20366.2 * Update dependencies from https://github.com/dotnet/icu build 20200717.1 Microsoft.NETCore.Runtime.ICU.Transport From Version 5.0.0-preview.8.20365.1 -> To Version 5.0.0-preview.8.20367.1 Co-authored-by: dotnet-maestro[bot] Co-authored-by: Alexander Köplinger --- eng/Version.Details.xml | 72 ++++++++++++++++++++--------------------- eng/Versions.props | 36 ++++++++++----------- 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 0d7aad96f5897b..2940b3c13c7665 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -86,73 +86,73 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-optimization d0bb63d2ec7060714e63ee4082fac48f2e57f3e2 - + https://github.com/microsoft/vstest - b9296fc900e2f2d717d507b4ee2a4306521796d4 + 069d8bd6357e2dbc260a35016ddbefe5dfec4102 - + https://github.com/dotnet/runtime-assets - b34a70799faa67f13c2e72852e4f3af463ff4d6c + 5a041ae14a25fe6e5db62666778a7adb59d5a056 - + https://github.com/dotnet/runtime-assets - b34a70799faa67f13c2e72852e4f3af463ff4d6c + 5a041ae14a25fe6e5db62666778a7adb59d5a056 - + https://github.com/dotnet/runtime-assets - b34a70799faa67f13c2e72852e4f3af463ff4d6c + 5a041ae14a25fe6e5db62666778a7adb59d5a056 - + https://github.com/dotnet/runtime-assets - b34a70799faa67f13c2e72852e4f3af463ff4d6c + 5a041ae14a25fe6e5db62666778a7adb59d5a056 - + https://github.com/dotnet/runtime-assets - b34a70799faa67f13c2e72852e4f3af463ff4d6c + 5a041ae14a25fe6e5db62666778a7adb59d5a056 - + https://github.com/dotnet/runtime-assets - b34a70799faa67f13c2e72852e4f3af463ff4d6c + 5a041ae14a25fe6e5db62666778a7adb59d5a056 - + https://github.com/dotnet/runtime-assets - b34a70799faa67f13c2e72852e4f3af463ff4d6c + 5a041ae14a25fe6e5db62666778a7adb59d5a056 - + https://github.com/dotnet/runtime-assets - b34a70799faa67f13c2e72852e4f3af463ff4d6c + 5a041ae14a25fe6e5db62666778a7adb59d5a056 - + https://github.com/dotnet/llvm-project - 266c9f5b5c1e94333e01ca77fa74d76563969842 + 4e6a09468cb4e4e1be38ac25fcf866ca8136638b - + https://github.com/dotnet/llvm-project - 266c9f5b5c1e94333e01ca77fa74d76563969842 + 4e6a09468cb4e4e1be38ac25fcf866ca8136638b - + https://github.com/dotnet/llvm-project - 266c9f5b5c1e94333e01ca77fa74d76563969842 + 4e6a09468cb4e4e1be38ac25fcf866ca8136638b - + https://github.com/dotnet/llvm-project - 266c9f5b5c1e94333e01ca77fa74d76563969842 + 4e6a09468cb4e4e1be38ac25fcf866ca8136638b - + https://github.com/dotnet/llvm-project - 266c9f5b5c1e94333e01ca77fa74d76563969842 + 4e6a09468cb4e4e1be38ac25fcf866ca8136638b - + https://github.com/dotnet/llvm-project - 266c9f5b5c1e94333e01ca77fa74d76563969842 + 4e6a09468cb4e4e1be38ac25fcf866ca8136638b - + https://github.com/dotnet/llvm-project - 266c9f5b5c1e94333e01ca77fa74d76563969842 + 4e6a09468cb4e4e1be38ac25fcf866ca8136638b - + https://github.com/dotnet/llvm-project - 266c9f5b5c1e94333e01ca77fa74d76563969842 + 4e6a09468cb4e4e1be38ac25fcf866ca8136638b https://github.com/dotnet/runtime @@ -182,9 +182,9 @@ https://github.com/dotnet/runtime 0375524a91a47ca4db3ee1be548f74bab7e26e76 - + https://github.com/mono/linker - e76321851c05c5016df3d1243885c02e875b9912 + f7c8a2a9e5aa47718169140db23c42f3439e6660 https://github.com/dotnet/xharness diff --git a/eng/Versions.props b/eng/Versions.props index 94c0d597cd5715..c06cc9058abc1d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -72,14 +72,14 @@ 5.0.0-preview.4.20202.18 5.0.0-alpha.1.19563.3 - 5.0.0-beta.20360.1 - 5.0.0-beta.20360.1 - 5.0.0-beta.20360.1 - 5.0.0-beta.20360.1 - 5.0.0-beta.20360.1 - 5.0.0-beta.20360.1 - 5.0.0-beta.20360.1 - 5.0.0-beta.20360.1 + 5.0.0-beta.20364.1 + 5.0.0-beta.20364.1 + 5.0.0-beta.20364.1 + 5.0.0-beta.20364.1 + 5.0.0-beta.20364.1 + 5.0.0-beta.20364.1 + 5.0.0-beta.20364.1 + 5.0.0-beta.20364.1 2.2.0-prerelease.19564.1 @@ -104,7 +104,7 @@ 4.8.0 - 16.8.0-preview-20200708-01 + 16.8.0-preview-20200716-03 1.0.0-prerelease.20352.3 1.0.0-prerelease.20352.3 2.4.1 @@ -116,18 +116,18 @@ 3.0.0-preview-20200715.1 - 5.0.0-preview.3.20363.5 + 5.0.0-preview.3.20366.2 5.0.0-preview.8.20370.1 - 9.0.1-alpha.1.20356.1 - 9.0.1-alpha.1.20356.1 - 9.0.1-alpha.1.20356.1 - 9.0.1-alpha.1.20356.1 - 9.0.1-alpha.1.20356.1 - 9.0.1-alpha.1.20356.1 - 9.0.1-alpha.1.20356.1 - 9.0.1-alpha.1.20356.1 + 9.0.1-alpha.1.20365.1 + 9.0.1-alpha.1.20365.1 + 9.0.1-alpha.1.20365.1 + 9.0.1-alpha.1.20365.1 + 9.0.1-alpha.1.20365.1 + 9.0.1-alpha.1.20365.1 + 9.0.1-alpha.1.20365.1 + 9.0.1-alpha.1.20365.1 From 6bb606099c6d442aec08fe9825ce5a0acc16f484 Mon Sep 17 00:00:00 2001 From: Ryan Lucia Date: Mon, 20 Jul 2020 20:41:30 -0400 Subject: [PATCH 049/458] Add CoffeeFlux to area-VM-meta-mono (#39659) This ensures I see notifications about new issues --- docs/area-owners.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/area-owners.md b/docs/area-owners.md index e696729861dff8..6626a5576cdc63 100644 --- a/docs/area-owners.md +++ b/docs/area-owners.md @@ -118,4 +118,4 @@ If you need to tag folks on an issue or PR, you will generally want to tag the o | area-TypeSystem-coreclr | @mangod9 | @davidwrighton @MichalStrehovsky @janvorli @mangod9 | | | area-UWP | @tommcdon | @jashook | UWP-specific issues including Microsoft.NETCore.UniversalWindowsPlatform and Microsoft.Net.UWPCoreRuntimeSdk | | area-VM-coreclr | @mangod9 | @mangod9 | | -| area-VM-meta-mono | @SamMonoRT | @lambdageek | | +| area-VM-meta-mono | @SamMonoRT | @lambdageek @CoffeeFlux | | From c39980607d66be9630c63266759f0a819f230889 Mon Sep 17 00:00:00 2001 From: Sergey Andreenko Date: Mon, 20 Jul 2020 18:35:31 -0700 Subject: [PATCH 050/458] Fix tailCall check for CallI. (#39621) --- src/coreclr/src/jit/importer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp index e3efd08dbe309e..e1443b849ad347 100644 --- a/src/coreclr/src/jit/importer.cpp +++ b/src/coreclr/src/jit/importer.cpp @@ -8577,7 +8577,7 @@ var_types Compiler::impImportCall(OPCODE opcode, if (canTailCall && !impTailCallRetTypeCompatible(info.compRetType, info.compMethodInfo->args.retTypeClass, callRetTyp, - callInfo->sig.retTypeClass)) + sig->retTypeClass)) { canTailCall = false; szCanTailCallFailReason = "Return types are not tail call compatible"; From 0c79b70c4d15dfb32b64ca6ab54d7a4eecda4d97 Mon Sep 17 00:00:00 2001 From: Vladimir Sadov Date: Mon, 20 Jul 2020 19:29:13 -0700 Subject: [PATCH 051/458] Fixing a memory ordering issue in AsymmetricLock and enabling MemoryBarrierProcessWide test on ARM64 (#39668) --- .../System.Threading/tests/InterlockedTests.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Threading/tests/InterlockedTests.cs b/src/libraries/System.Threading/tests/InterlockedTests.cs index ed7e3efa956cba..941a78378c0060 100644 --- a/src/libraries/System.Threading/tests/InterlockedTests.cs +++ b/src/libraries/System.Threading/tests/InterlockedTests.cs @@ -301,7 +301,7 @@ public void InterlockedOr_UInt64() Assert.Equal(0x17755771u, value); } - [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotArm64Process), nameof(PlatformDetection.IsThreadingSupported))] // [ActiveIssue("https://github.com/dotnet/runtime/issues/11177")] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] public void MemoryBarrierProcessWide() { // Stress MemoryBarrierProcessWide correctness using a simple AsymmetricLock @@ -406,6 +406,15 @@ private LockCookie EnterSlow() while (oldEntry.Taken) sw.SpinOnce(); + // We have seen that the other thread released the lock by setting Taken to false. + // However, on platforms with weak memory ordering (ex: ARM32, ARM64) observing that does not guarantee that the writes executed by that + // thread prior to releasing the lock are all committed to the shared memory. + // We could fix that by doing the release via Volatile.Write, but we do not want to add expense to every release on the fast path. + // Instead we will do another MemoryBarrierProcessWide here. + + // NOTE: not needed on x86/x64 + Interlocked.MemoryBarrierProcessWide(); + _current.Taken = true; return _current; } From 0df6dac02c71ca400e81c62d6cd18366dec519c4 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Mon, 20 Jul 2020 19:32:22 -0700 Subject: [PATCH 052/458] Start using UnmanagedCallersOnly in CoreLib (#39082) - Fix CoreCLR assert on x86 - Use workaround for Mono --- src/coreclr/src/vm/tieredcompilation.cpp | 6 ++++++ .../Common/src/Interop/Interop.Calendar.cs | 15 ++++++++------- .../Windows/Kernel32/Interop.Globalization.cs | 12 +++--------- .../System/Globalization/CalendarData.Icu.cs | 17 ++++++++++------- .../System/Globalization/CalendarData.Nls.cs | 5 +++-- .../Globalization/CalendarData.Windows.cs | 4 ++-- .../src/System/Globalization/CultureData.Nls.cs | 14 +++++++------- 7 files changed, 39 insertions(+), 34 deletions(-) diff --git a/src/coreclr/src/vm/tieredcompilation.cpp b/src/coreclr/src/vm/tieredcompilation.cpp index 311154f1ad7212..01c663c8ba682d 100644 --- a/src/coreclr/src/vm/tieredcompilation.cpp +++ b/src/coreclr/src/vm/tieredcompilation.cpp @@ -772,9 +772,15 @@ BOOL TieredCompilationManager::CompileCodeVersion(NativeCodeVersion nativeCodeVe PrepareCodeConfigBuffer configBuffer(nativeCodeVersion); PrepareCodeConfig *config = configBuffer.GetConfig(); +#if defined(TARGET_X86) + // Deferring X86 support until a need is observed or + // time permits investigation into all the potential issues. + // https://github.com/dotnet/runtime/issues/33582 +#else // This is a recompiling request which means the caller was // in COOP mode since the code already ran. _ASSERTE(!pMethod->HasUnmanagedCallersOnlyAttribute()); +#endif config->SetCallerGCMode(CallerGCMode::Coop); pCode = pMethod->PrepareCode(config); LOG((LF_TIEREDCOMPILATION, LL_INFO10000, "TieredCompilationManager::CompileCodeVersion Method=0x%pM (%s::%s), code version id=0x%x, code ptr=0x%p\n", diff --git a/src/libraries/Common/src/Interop/Interop.Calendar.cs b/src/libraries/Common/src/Interop/Interop.Calendar.cs index 9be426d367a6e4..fda13b9ba607b0 100644 --- a/src/libraries/Common/src/Interop/Interop.Calendar.cs +++ b/src/libraries/Common/src/Interop/Interop.Calendar.cs @@ -9,24 +9,25 @@ internal static partial class Interop { internal static partial class Globalization { - internal unsafe delegate void EnumCalendarInfoCallback( - char* calendarString, - IntPtr context); - [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetCalendars")] internal static extern int GetCalendars(string localeName, CalendarId[] calendars, int calendarsCapacity); [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetCalendarInfo")] internal static extern unsafe ResultCode GetCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType calendarDataType, char* result, int resultCapacity); -#if TARGET_BROWSER - // Temp workaround for pinvoke callbacks for Mono-Wasm-Interpreter +#if MONO + // Temp workaround for pinvoke callbacks for Mono // https://github.com/dotnet/runtime/issues/39100 + + internal unsafe delegate void EnumCalendarInfoCallback( + char* calendarString, + IntPtr context); + [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_EnumCalendarInfo")] internal static extern bool EnumCalendarInfo(IntPtr callback, string localeName, CalendarId calendarId, CalendarDataType calendarDataType, IntPtr context); #else [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_EnumCalendarInfo")] - internal static extern bool EnumCalendarInfo(EnumCalendarInfoCallback callback, string localeName, CalendarId calendarId, CalendarDataType calendarDataType, IntPtr context); + internal static extern unsafe bool EnumCalendarInfo(delegate* callback, string localeName, CalendarId calendarId, CalendarDataType calendarDataType, IntPtr context); #endif [DllImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetLatestJapaneseEra")] diff --git a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.Globalization.cs b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.Globalization.cs index 78ba717b2306e8..d207e321ea4001 100644 --- a/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.Globalization.cs +++ b/src/libraries/Common/src/Interop/Windows/Kernel32/Interop.Globalization.cs @@ -121,14 +121,10 @@ internal static extern bool IsNLSDefinedString( internal static extern int GetLocaleInfoEx(string lpLocaleName, uint LCType, void* lpLCData, int cchData); [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] - internal static extern bool EnumSystemLocalesEx(EnumLocalesProcEx lpLocaleEnumProcEx, uint dwFlags, void* lParam, IntPtr reserved); - - internal delegate BOOL EnumLocalesProcEx(char* lpLocaleString, uint dwFlags, void* lParam); + internal static extern bool EnumSystemLocalesEx(delegate* lpLocaleEnumProcEx, uint dwFlags, void* lParam, IntPtr reserved); [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] - internal static extern bool EnumTimeFormatsEx(EnumTimeFormatsProcEx lpTimeFmtEnumProcEx, string lpLocaleName, uint dwFlags, void* lParam); - - internal delegate BOOL EnumTimeFormatsProcEx(char* lpTimeFormatString, void* lParam); + internal static extern bool EnumTimeFormatsEx(delegate* lpTimeFmtEnumProcEx, string lpLocaleName, uint dwFlags, void* lParam); [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] internal static extern int GetCalendarInfoEx(string? lpLocaleName, uint Calendar, IntPtr lpReserved, uint CalType, IntPtr lpCalData, int cchData, out int lpValue); @@ -143,9 +139,7 @@ internal static extern bool IsNLSDefinedString( internal static extern int GetGeoInfo(int location, int geoType, char* lpGeoData, int cchData, int LangId); [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] - internal static extern bool EnumCalendarInfoExEx(EnumCalendarInfoProcExEx pCalInfoEnumProcExEx, string lpLocaleName, uint Calendar, string? lpReserved, uint CalType, void* lParam); - - internal delegate BOOL EnumCalendarInfoProcExEx(char* lpCalendarInfoString, uint Calendar, IntPtr lpReserved, void* lParam); + internal static extern bool EnumCalendarInfoExEx(delegate* pCalInfoEnumProcExEx, string lpLocaleName, uint Calendar, string? lpReserved, uint CalType, void* lParam); [StructLayout(LayoutKind.Sequential)] internal struct NlsVersionInfoEx diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs index 26567368d392d1..df3a17e6a18aa3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Runtime.InteropServices; using System.Text; using Internal.Runtime.CompilerServices; @@ -422,15 +423,10 @@ internal static bool EnumCalendarInfo(string localeName, CalendarId calendarId, return result; } -#if !TARGET_BROWSER +#if MONO private static unsafe bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, ref IcuEnumCalendarsData callbackContext) { - return Interop.Globalization.EnumCalendarInfo(EnumCalendarInfoCallback, localeName, calendarId, dataType, (IntPtr)Unsafe.AsPointer(ref callbackContext)); - } -#else - private static unsafe bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, ref IcuEnumCalendarsData callbackContext) - { - // Temp workaround for pinvoke callbacks for Mono-Wasm-Interpreter + // Temp workaround for pinvoke callbacks for Mono // https://github.com/dotnet/runtime/issues/39100 var calendarInfoCallback = new Interop.Globalization.EnumCalendarInfoCallback(EnumCalendarInfoCallback); return Interop.Globalization.EnumCalendarInfo( @@ -439,6 +435,13 @@ private static unsafe bool EnumCalendarInfo(string localeName, CalendarId calend } [Mono.MonoPInvokeCallback(typeof(Interop.Globalization.EnumCalendarInfoCallback))] +#else + private static unsafe bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, ref IcuEnumCalendarsData callbackContext) + { + return Interop.Globalization.EnumCalendarInfo(&EnumCalendarInfoCallback, localeName, calendarId, dataType, (IntPtr)Unsafe.AsPointer(ref callbackContext)); + } + + [UnmanagedCallersOnly] #endif private static unsafe void EnumCalendarInfoCallback(char* calendarStringPtr, IntPtr context) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Nls.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Nls.cs index b95aca903dcafc..ea0bcbb8026955 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Nls.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Nls.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.Collections.Generic; +using System.Runtime.InteropServices; using Internal.Runtime.CompilerServices; namespace System.Globalization @@ -69,7 +70,7 @@ private struct EnumData } // EnumCalendarInfoExEx callback itself. - // [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + [UnmanagedCallersOnly] private static unsafe Interop.BOOL EnumCalendarInfoCallback(char* lpCalendarInfoString, uint calendar, IntPtr pReserved, void* lParam) { ref EnumData context = ref Unsafe.As(ref *(byte*)lParam); @@ -101,7 +102,7 @@ public struct NlsEnumCalendarsData public List calendars; // list of calendars found so far } - // [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + [UnmanagedCallersOnly] private static unsafe Interop.BOOL EnumCalendarsCallback(char* lpCalendarInfoString, uint calendar, IntPtr reserved, void* lParam) { ref NlsEnumCalendarsData context = ref Unsafe.As(ref *(byte*)lParam); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Windows.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Windows.cs index 0147bed7e2d46d..8f89619276ffa5 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Windows.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Windows.cs @@ -266,7 +266,7 @@ private static unsafe bool CallEnumCalendarInfo(string localeName, CalendarId ca } // Now call the enumeration API. Work is done by our callback function - Interop.Kernel32.EnumCalendarInfoExEx(EnumCalendarInfoCallback, localeName, (uint)calendar, null, calType, Unsafe.AsPointer(ref context)); + Interop.Kernel32.EnumCalendarInfoExEx(&EnumCalendarInfoCallback, localeName, (uint)calendar, null, calType, Unsafe.AsPointer(ref context)); // Now we have a list of data, fail if we didn't find anything. Debug.Assert(context.strings != null); @@ -418,7 +418,7 @@ private static int NlsGetCalendars(string localeName, bool useUserOverride, Cale unsafe { - Interop.Kernel32.EnumCalendarInfoExEx(EnumCalendarsCallback, localeName, ENUM_ALL_CALENDARS, null, CAL_ICALINTVALUE, Unsafe.AsPointer(ref data)); + Interop.Kernel32.EnumCalendarInfoExEx(&EnumCalendarsCallback, localeName, ENUM_ALL_CALENDARS, null, CAL_ICALINTVALUE, Unsafe.AsPointer(ref data)); } // Copy to the output array diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs index 41734e6f0d50f6..9738d5a289464d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CultureData.Nls.cs @@ -117,7 +117,7 @@ private int NlsGetFirstDayOfWeek() unsafe { - Interop.Kernel32.EnumSystemLocalesEx(EnumSystemLocalesProc, Interop.Kernel32.LOCALE_SPECIFICDATA | Interop.Kernel32.LOCALE_SUPPLEMENTAL, Unsafe.AsPointer(ref context), IntPtr.Zero); + Interop.Kernel32.EnumSystemLocalesEx(&EnumSystemLocalesProc, Interop.Kernel32.LOCALE_SPECIFICDATA | Interop.Kernel32.LOCALE_SUPPLEMENTAL, Unsafe.AsPointer(ref context), IntPtr.Zero); } if (context.cultureName != null) @@ -338,7 +338,7 @@ private struct EnumLocaleData } // EnumSystemLocaleEx callback. - // [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + [UnmanagedCallersOnly] private static unsafe Interop.BOOL EnumSystemLocalesProc(char* lpLocaleString, uint flags, void* contextHandle) { ref EnumLocaleData context = ref Unsafe.As(ref *(byte*)contextHandle); @@ -361,7 +361,7 @@ private static unsafe Interop.BOOL EnumSystemLocalesProc(char* lpLocaleString, u } // EnumSystemLocaleEx callback. - // [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + [UnmanagedCallersOnly] private static unsafe Interop.BOOL EnumAllSystemLocalesProc(char* lpLocaleString, uint flags, void* contextHandle) { ref EnumData context = ref Unsafe.As(ref *(byte*)contextHandle); @@ -383,7 +383,7 @@ private struct EnumData } // EnumTimeFormatsEx callback itself. - // [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + [UnmanagedCallersOnly] private static unsafe Interop.BOOL EnumTimeCallback(char* lpTimeFormatString, void* lParam) { ref EnumData context = ref Unsafe.As(ref *(byte*)lParam); @@ -404,7 +404,7 @@ private static unsafe Interop.BOOL EnumTimeCallback(char* lpTimeFormatString, vo data.strings = new List(); // Now call the enumeration API. Work is done by our callback function - Interop.Kernel32.EnumTimeFormatsEx(EnumTimeCallback, localeName, dwFlags, Unsafe.AsPointer(ref data)); + Interop.Kernel32.EnumTimeFormatsEx(&EnumTimeCallback, localeName, dwFlags, Unsafe.AsPointer(ref data)); if (data.strings.Count > 0) { @@ -490,7 +490,7 @@ private static CultureInfo[] NlsEnumCultures(CultureTypes types) unsafe { - Interop.Kernel32.EnumSystemLocalesEx(EnumAllSystemLocalesProc, flags, Unsafe.AsPointer(ref context), IntPtr.Zero); + Interop.Kernel32.EnumSystemLocalesEx(&EnumAllSystemLocalesProc, flags, Unsafe.AsPointer(ref context), IntPtr.Zero); } CultureInfo[] cultures = new CultureInfo[context.strings.Count]; @@ -518,7 +518,7 @@ internal bool NlsIsReplacementCulture unsafe { - Interop.Kernel32.EnumSystemLocalesEx(EnumAllSystemLocalesProc, Interop.Kernel32.LOCALE_REPLACEMENT, Unsafe.AsPointer(ref context), IntPtr.Zero); + Interop.Kernel32.EnumSystemLocalesEx(&EnumAllSystemLocalesProc, Interop.Kernel32.LOCALE_REPLACEMENT, Unsafe.AsPointer(ref context), IntPtr.Zero); } for (int i = 0; i < context.strings.Count; i++) From 82d7d5fc58dcfbf5fd226c34a7c521565a3fb58c Mon Sep 17 00:00:00 2001 From: John Salem Date: Mon, 20 Jul 2020 20:58:56 -0700 Subject: [PATCH 053/458] fix missing command case (#39686) --- src/coreclr/src/vm/processdiagnosticsprotocolhelper.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/coreclr/src/vm/processdiagnosticsprotocolhelper.cpp b/src/coreclr/src/vm/processdiagnosticsprotocolhelper.cpp index e62f0d43b8cd6d..6aad9af96de0fe 100644 --- a/src/coreclr/src/vm/processdiagnosticsprotocolhelper.cpp +++ b/src/coreclr/src/vm/processdiagnosticsprotocolhelper.cpp @@ -199,6 +199,9 @@ void ProcessDiagnosticsProtocolHelper::HandleIpcMessage(DiagnosticsIpc::IpcMessa case ProcessCommandId::GetProcessInfo: ProcessDiagnosticsProtocolHelper::GetProcessInfo(message, pStream); break; + case ProcessCommandId::ResumeRuntime: + ProcessDiagnosticsProtocolHelper::ResumeRuntimeStartup(message, pStream); + break; default: STRESS_LOG1(LF_DIAGNOSTICS_PORT, LL_WARNING, "Received unknown request type (%d)\n", message.GetHeader().CommandSet); From 650f28f2c841c44b0a247e18a9f983c8619286dc Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Mon, 20 Jul 2020 21:13:29 -0700 Subject: [PATCH 054/458] Add JsonNumberHandling(Attribute) & support for (de)serializing numbers from/to string (#39363) * Add JsonNumberHandling & support for (de)serializing numbers from/to string * Add JsonNumberHandlingAttribute * Address review feedback + fixups * Address review feedback ii --- .../System.Text.Json/ref/System.Text.Json.cs | 15 + .../src/Resources/Strings.resx | 6 + .../src/System.Text.Json.csproj | 2 + .../src/System/Text/Json/JsonConstants.cs | 4 + .../Text/Json/Reader/JsonReaderHelper.cs | 77 + .../Text/Json/Reader/Utf8JsonReader.TryGet.cs | 93 +- .../Attributes/JsonNumberHandlingAttribute.cs | 30 + .../Converters/Collection/ArrayConverter.cs | 2 +- .../Collection/DictionaryDefaultConverter.cs | 20 +- .../DictionaryOfTKeyTValueConverter.cs | 8 +- .../Collection/IDictionaryConverter.cs | 2 +- .../IDictionaryOfTKeyTValueConverter.cs | 2 +- .../Collection/IEnumerableDefaultConverter.cs | 12 +- .../Converters/Collection/IListConverter.cs | 45 +- ...ReadOnlyDictionaryOfTKeyTValueConverter.cs | 2 +- ...mmutableDictionaryOfTKeyTValueConverter.cs | 2 +- .../Converters/Collection/ListOfTConverter.cs | 2 +- .../Object/KeyValuePairConverter.cs | 1 + .../Object/ObjectDefaultConverter.cs | 2 + ...ctWithParameterizedConstructorConverter.cs | 3 + .../Converters/Value/ByteConverter.cs | 27 + .../Converters/Value/DecimalConverter.cs | 28 + .../Converters/Value/DoubleConverter.cs | 38 + .../Converters/Value/Int16Converter.cs | 31 +- .../Converters/Value/Int32Converter.cs | 29 + .../Converters/Value/Int64Converter.cs | 28 + .../Converters/Value/NullableConverter.cs | 30 + .../Converters/Value/SByteConverter.cs | 28 + .../Converters/Value/SingleConverter.cs | 39 + .../Converters/Value/StringConverter.cs | 2 - .../Converters/Value/UInt16Converter.cs | 29 + .../Converters/Value/UInt32Converter.cs | 29 + .../Converters/Value/UInt64Converter.cs | 28 + .../Json/Serialization/JsonClassInfo.Cache.cs | 16 +- .../Text/Json/Serialization/JsonClassInfo.cs | 17 +- .../Text/Json/Serialization/JsonConverter.cs | 12 +- .../Json/Serialization/JsonConverterOfT.cs | 41 +- .../Json/Serialization/JsonNumberHandling.cs | 32 + .../Json/Serialization/JsonParameterInfo.cs | 3 + .../Json/Serialization/JsonPropertyInfo.cs | 68 +- .../Json/Serialization/JsonPropertyInfoOfT.cs | 12 +- .../JsonSerializer.Read.HandlePropertyName.cs | 1 + .../JsonSerializer.Read.Helpers.cs | 7 + .../JsonSerializerOptions.Converters.cs | 2 +- .../Serialization/JsonSerializerOptions.cs | 23 + .../Text/Json/Serialization/ReadStack.cs | 15 +- .../Text/Json/Serialization/ReadStackFrame.cs | 5 + .../Text/Json/Serialization/WriteStack.cs | 11 +- .../Json/Serialization/WriteStackFrame.cs | 3 + .../Text/Json/ThrowHelper.Serialization.cs | 22 + .../Utf8JsonWriter.WriteValues.Decimal.cs | 8 + .../Utf8JsonWriter.WriteValues.Double.cs | 28 + .../Utf8JsonWriter.WriteValues.Float.cs | 28 + ...Utf8JsonWriter.WriteValues.SignedNumber.cs | 8 + .../Utf8JsonWriter.WriteValues.String.cs | 14 + ...f8JsonWriter.WriteValues.UnsignedNumber.cs | 8 + .../tests/JsonNumberTestData.cs | 29 +- .../Serialization/NumberHandlingTests.cs | 1414 +++++++++++++++++ .../tests/Serialization/Object.ReadTests.cs | 4 +- .../tests/Serialization/OptionsTests.cs | 5 + .../tests/Serialization/Stream.Collections.cs | 38 +- .../TestClasses.NonGenericCollections.cs | 10 + .../Serialization/TestClasses/TestClasses.cs | 66 + .../tests/System.Text.Json.Tests.csproj | 3 +- 64 files changed, 2502 insertions(+), 147 deletions(-) create mode 100644 src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Attributes/JsonNumberHandlingAttribute.cs create mode 100644 src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonNumberHandling.cs create mode 100644 src/libraries/System.Text.Json/tests/Serialization/NumberHandlingTests.cs diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.cs b/src/libraries/System.Text.Json/ref/System.Text.Json.cs index 0ab83e8b526561..0de194ebde5bca 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -244,6 +244,7 @@ public JsonSerializerOptions(System.Text.Json.JsonSerializerDefaults defaults) { public bool IgnoreReadOnlyFields { get { throw null; } set { } } public bool IncludeFields { get { throw null; } set { } } public int MaxDepth { get { throw null; } set { } } + public System.Text.Json.Serialization.JsonNumberHandling NumberHandling { get { throw null; } set { } } public bool PropertyNameCaseInsensitive { get { throw null; } set { } } public System.Text.Json.JsonNamingPolicy? PropertyNamingPolicy { get { throw null; } set { } } public System.Text.Json.JsonCommentHandling ReadCommentHandling { get { throw null; } set { } } @@ -496,6 +497,14 @@ public enum JsonIgnoreCondition WhenWritingDefault = 2, WhenWritingNull = 3, } + [System.FlagsAttribute] + public enum JsonNumberHandling + { + Strict = 0, + AllowReadingFromString = 1, + WriteAsString = 2, + AllowNamedFloatingPointLiterals = 4, + } public abstract partial class JsonAttribute : System.Attribute { protected JsonAttribute() { } @@ -533,6 +542,12 @@ protected internal JsonConverter() { } public abstract T Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options); public abstract void Write(System.Text.Json.Utf8JsonWriter writer, T value, System.Text.Json.JsonSerializerOptions options); } + [System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Struct | System.AttributeTargets.Property | System.AttributeTargets.Field, AllowMultiple = false)] + public sealed partial class JsonNumberHandlingAttribute : System.Text.Json.Serialization.JsonAttribute + { + public JsonNumberHandlingAttribute(System.Text.Json.Serialization.JsonNumberHandling handling) { } + public System.Text.Json.Serialization.JsonNumberHandling Handling { get { throw null; } } + } [System.AttributeUsageAttribute(System.AttributeTargets.Constructor, AllowMultiple = false)] public sealed partial class JsonConstructorAttribute : System.Text.Json.Serialization.JsonAttribute { diff --git a/src/libraries/System.Text.Json/src/Resources/Strings.resx b/src/libraries/System.Text.Json/src/Resources/Strings.resx index 41cf9de418c483..d5db3cfc6fb1b0 100644 --- a/src/libraries/System.Text.Json/src/Resources/Strings.resx +++ b/src/libraries/System.Text.Json/src/Resources/Strings.resx @@ -536,4 +536,10 @@ The ignore condition 'JsonIgnoreCondition.WhenWritingNull' is not valid on value-type member '{0}' on type '{1}'. Consider using 'JsonIgnoreCondition.WhenWritingDefault'. + + 'JsonNumberHandlingAttribute' cannot be placed on a property, field, or type that is handled by a custom converter. See usage(s) of converter '{0}' on type '{1}'. + + + When 'JsonNumberHandlingAttribute' is placed on a property or field, the property or field must be a number or a collection. See member '{0}' on type '{1}'. + \ No newline at end of file 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 e381a1b381d464..e787defd06be02 100644 --- a/src/libraries/System.Text.Json/src/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/src/System.Text.Json.csproj @@ -60,6 +60,7 @@ + @@ -135,6 +136,7 @@ + diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/JsonConstants.cs b/src/libraries/System.Text.Json/src/System/Text/Json/JsonConstants.cs index 2bfc41c6bd912c..2e1bb4e16cfe17 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/JsonConstants.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/JsonConstants.cs @@ -37,6 +37,10 @@ internal static class JsonConstants public static ReadOnlySpan FalseValue => new byte[] { (byte)'f', (byte)'a', (byte)'l', (byte)'s', (byte)'e' }; public static ReadOnlySpan NullValue => new byte[] { (byte)'n', (byte)'u', (byte)'l', (byte)'l' }; + public static ReadOnlySpan NaNValue => new byte[] { (byte)'N', (byte)'a', (byte)'N' }; + public static ReadOnlySpan PositiveInfinityValue => new byte[] { (byte)'I', (byte)'n', (byte)'f', (byte)'i', (byte)'n', (byte)'i', (byte)'t', (byte)'y' }; + public static ReadOnlySpan NegativeInfinityValue => new byte[] { (byte)'-', (byte)'I', (byte)'n', (byte)'f', (byte)'i', (byte)'n', (byte)'i', (byte)'t', (byte)'y' }; + // Used to search for the end of a number public static ReadOnlySpan Delimiters => new byte[] { ListSeparator, CloseBrace, CloseBracket, Space, LineFeed, CarriageReturn, Tab, Slash }; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.cs index fcd7f0d3fb8da7..dbea5c0fea0c10 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/JsonReaderHelper.cs @@ -321,5 +321,82 @@ public static bool TryGetEscapedGuid(ReadOnlySpan source, out Guid value) value = default; return false; } + + public static char GetFloatingPointStandardParseFormat(ReadOnlySpan span) + { + // Assume that 'e/E' is closer to the end. + int startIndex = span.Length - 1; + for (int i = startIndex; i >= 0; i--) + { + byte token = span[i]; + if (token == 'E' || token == 'e') + { + return JsonConstants.ScientificNotationFormat; + } + } + return default; + } + + public static bool TryGetFloatingPointConstant(ReadOnlySpan span, out float value) + { + if (span.Length == 3) + { + if (span.SequenceEqual(JsonConstants.NaNValue)) + { + value = float.NaN; + return true; + } + } + else if (span.Length == 8) + { + if (span.SequenceEqual(JsonConstants.PositiveInfinityValue)) + { + value = float.PositiveInfinity; + return true; + } + } + else if (span.Length == 9) + { + if (span.SequenceEqual(JsonConstants.NegativeInfinityValue)) + { + value = float.NegativeInfinity; + return true; + } + } + + value = 0; + return false; + } + + public static bool TryGetFloatingPointConstant(ReadOnlySpan span, out double value) + { + if (span.Length == 3) + { + if (span.SequenceEqual(JsonConstants.NaNValue)) + { + value = double.NaN; + return true; + } + } + else if (span.Length == 8) + { + if (span.SequenceEqual(JsonConstants.PositiveInfinityValue)) + { + value = double.PositiveInfinity; + return true; + } + } + else if (span.Length == 9) + { + if (span.SequenceEqual(JsonConstants.NegativeInfinityValue)) + { + value = double.NegativeInfinity; + return true; + } + } + + value = 0; + return false; + } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.TryGet.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.TryGet.cs index dbc52d94b79d57..d08cbcbc28dd06 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.TryGet.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.TryGet.cs @@ -416,11 +416,38 @@ public float GetSingle() internal float GetSingleWithQuotes() { ReadOnlySpan span = GetUnescapedSpan(); - if (!TryGetSingleCore(out float value, span)) + + if (JsonReaderHelper.TryGetFloatingPointConstant(span, out float value)) { - throw ThrowHelper.GetFormatException(NumericType.Single); + return value; } - return value; + + char numberFormat = JsonReaderHelper.GetFloatingPointStandardParseFormat(span); + if (Utf8Parser.TryParse(span, out value, out int bytesConsumed, numberFormat) + && span.Length == bytesConsumed) + { + // NETCOREAPP implementation of the TryParse method above permits case-insenstive variants of the + // float constants "NaN", "Infinity", "-Infinity". This differs from the NETFRAMEWORK implementation. + // The following logic reconciles the two implementations to enforce consistent behavior. + if (!float.IsNaN(value) && !float.IsPositiveInfinity(value) && !float.IsNegativeInfinity(value)) + { + return value; + } + } + + throw ThrowHelper.GetFormatException(NumericType.Single); + } + + internal float GetSingleFloatingPointConstant() + { + ReadOnlySpan span = GetUnescapedSpan(); + + if (JsonReaderHelper.TryGetFloatingPointConstant(span, out float value)) + { + return value; + } + + throw ThrowHelper.GetFormatException(NumericType.Single); } /// @@ -449,11 +476,38 @@ public double GetDouble() internal double GetDoubleWithQuotes() { ReadOnlySpan span = GetUnescapedSpan(); - if (!TryGetDoubleCore(out double value, span)) + + if (JsonReaderHelper.TryGetFloatingPointConstant(span, out double value)) { - throw ThrowHelper.GetFormatException(NumericType.Double); + return value; } - return value; + + char numberFormat = JsonReaderHelper.GetFloatingPointStandardParseFormat(span); + if (Utf8Parser.TryParse(span, out value, out int bytesConsumed, numberFormat) + && span.Length == bytesConsumed) + { + // NETCOREAPP implmentation of the TryParse method above permits case-insenstive variants of the + // float constants "NaN", "Infinity", "-Infinity". This differs from the NETFRAMEWORK implementation. + // The following logic reconciles the two implementations to enforce consistent behavior. + if (!double.IsNaN(value) && !double.IsPositiveInfinity(value) && !double.IsNegativeInfinity(value)) + { + return value; + } + } + + throw ThrowHelper.GetFormatException(NumericType.Double); + } + + internal double GetDoubleFloatingPointConstant() + { + ReadOnlySpan span = GetUnescapedSpan(); + + if (JsonReaderHelper.TryGetFloatingPointConstant(span, out double value)) + { + return value; + } + + throw ThrowHelper.GetFormatException(NumericType.Double); } /// @@ -482,11 +536,15 @@ public decimal GetDecimal() internal decimal GetDecimalWithQuotes() { ReadOnlySpan span = GetUnescapedSpan(); - if (!TryGetDecimalCore(out decimal value, span)) + + char numberFormat = JsonReaderHelper.GetFloatingPointStandardParseFormat(span); + if (Utf8Parser.TryParse(span, out decimal value, out int bytesConsumed, numberFormat) + && span.Length == bytesConsumed) { - throw ThrowHelper.GetFormatException(NumericType.Decimal); + return value; } - return value; + + throw ThrowHelper.GetFormatException(NumericType.Decimal); } /// @@ -919,13 +977,8 @@ public bool TryGetSingle(out float value) throw ThrowHelper.GetInvalidOperationException_ExpectedNumber(TokenType); } - ReadOnlySpan span = HasValueSequence ? ValueSequence.ToArray() : ValueSpan; - return TryGetSingleCore(out value, span); - } + ReadOnlySpan span = HasValueSequence ? ValueSequence.ToArray() : ValueSpan;; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal bool TryGetSingleCore(out float value, ReadOnlySpan span) - { if (Utf8Parser.TryParse(span, out float tmp, out int bytesConsumed, _numberFormat) && span.Length == bytesConsumed) { @@ -955,12 +1008,7 @@ public bool TryGetDouble(out double value) } ReadOnlySpan span = HasValueSequence ? ValueSequence.ToArray() : ValueSpan; - return TryGetDoubleCore(out value, span); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal bool TryGetDoubleCore(out double value, ReadOnlySpan span) - { if (Utf8Parser.TryParse(span, out double tmp, out int bytesConsumed, _numberFormat) && span.Length == bytesConsumed) { @@ -990,12 +1038,7 @@ public bool TryGetDecimal(out decimal value) } ReadOnlySpan span = HasValueSequence ? ValueSequence.ToArray() : ValueSpan; - return TryGetDecimalCore(out value, span); - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal bool TryGetDecimalCore(out decimal value, ReadOnlySpan span) - { if (Utf8Parser.TryParse(span, out decimal tmp, out int bytesConsumed, _numberFormat) && span.Length == bytesConsumed) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Attributes/JsonNumberHandlingAttribute.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Attributes/JsonNumberHandlingAttribute.cs new file mode 100644 index 00000000000000..581d4aacd766e4 --- /dev/null +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Attributes/JsonNumberHandlingAttribute.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Text.Json.Serialization +{ + /// + /// When placed on a type, property, or field, indicates what + /// settings should be used when serializing or deserialing numbers. + /// + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] + public sealed class JsonNumberHandlingAttribute : JsonAttribute + { + /// + /// Indicates what settings should be used when serializing or deserialing numbers. + /// + public JsonNumberHandling Handling { get; } + + /// + /// Initializes a new instance of . + /// + public JsonNumberHandlingAttribute(JsonNumberHandling handling) + { + if (!JsonSerializer.IsValidNumberHandlingValue(handling)) + { + throw new ArgumentOutOfRangeException(nameof(handling)); + } + Handling = handling; + } + } +} diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ArrayConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ArrayConverter.cs index 4337037817f050..9147243ef95be1 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ArrayConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ArrayConverter.cs @@ -38,7 +38,7 @@ protected override bool OnWriteResume(Utf8JsonWriter writer, TCollection value, int index = state.Current.EnumeratorIndex; JsonConverter elementConverter = GetElementConverter(ref state); - if (elementConverter.CanUseDirectReadOrWrite) + if (elementConverter.CanUseDirectReadOrWrite && state.Current.NumberHandling == null) { // Fast path that avoids validation and extra indirection. for (; index < array.Length; index++) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs index c992d01eefb1ea..2093cd66cda5e8 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryDefaultConverter.cs @@ -29,7 +29,9 @@ protected virtual void ConvertCollection(ref ReadStack state, JsonSerializerOpti /// protected virtual void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state) { } - internal override Type ElementType => typeof(TValue); + private static Type s_valueType = typeof(TValue); + + internal override Type ElementType => s_valueType; protected Type KeyType = typeof(TKey); // For string keys we don't use a key converter @@ -39,9 +41,9 @@ protected virtual void CreateCollection(ref Utf8JsonReader reader, ref ReadStack protected JsonConverter? _keyConverter; protected JsonConverter? _valueConverter; - protected static JsonConverter GetValueConverter(JsonClassInfo classInfo) + protected static JsonConverter GetValueConverter(JsonClassInfo elementClassInfo) { - JsonConverter converter = (JsonConverter)classInfo.ElementClassInfo!.PropertyInfoForClassInfo.ConverterBase; + JsonConverter converter = (JsonConverter)elementClassInfo.PropertyInfoForClassInfo.ConverterBase; Debug.Assert(converter != null); // It should not be possible to have a null converter at this point. return converter; @@ -57,6 +59,8 @@ internal sealed override bool OnTryRead( ref ReadStack state, [MaybeNullWhen(false)] out TCollection value) { + JsonClassInfo elementClassInfo = state.Current.JsonClassInfo.ElementClassInfo!; + if (state.UseFastPath) { // Fast path that avoids maintaining state variables and dealing with preserved references. @@ -68,8 +72,8 @@ internal sealed override bool OnTryRead( CreateCollection(ref reader, ref state); - JsonConverter valueConverter = _valueConverter ??= GetValueConverter(state.Current.JsonClassInfo); - if (valueConverter.CanUseDirectReadOrWrite) + JsonConverter valueConverter = _valueConverter ??= GetValueConverter(elementClassInfo); + if (valueConverter.CanUseDirectReadOrWrite && state.Current.NumberHandling == null) { // Process all elements. while (true) @@ -89,7 +93,7 @@ internal sealed override bool OnTryRead( // Read the value and add. reader.ReadWithVerify(); - TValue element = valueConverter.Read(ref reader, typeof(TValue), options); + TValue element = valueConverter.Read(ref reader, s_valueType, options); Add(key, element!, options, ref state); } } @@ -114,7 +118,7 @@ internal sealed override bool OnTryRead( reader.ReadWithVerify(); // Get the value from the converter and add it. - valueConverter.TryRead(ref reader, typeof(TValue), options, ref state, out TValue element); + valueConverter.TryRead(ref reader, s_valueType, options, ref state, out TValue element); Add(key, element!, options, ref state); } } @@ -160,7 +164,7 @@ internal sealed override bool OnTryRead( } // Process all elements. - JsonConverter elementConverter = _valueConverter ??= GetValueConverter(state.Current.JsonClassInfo); + JsonConverter elementConverter = _valueConverter ??= GetValueConverter(elementClassInfo); while (true) { if (state.Current.PropertyState == StackFramePropertyState.None) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryOfTKeyTValueConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryOfTKeyTValueConverter.cs index 10818b7d31eeee..c89e1f9be07ee8 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryOfTKeyTValueConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/DictionaryOfTKeyTValueConverter.cs @@ -49,16 +49,18 @@ protected internal override bool OnWriteResume( enumerator = (Dictionary.Enumerator)state.Current.CollectionEnumerator; } + JsonClassInfo elementClassInfo = state.Current.JsonClassInfo.ElementClassInfo!; + JsonConverter keyConverter = _keyConverter ??= GetKeyConverter(KeyType, options); - JsonConverter valueConverter = _valueConverter ??= GetValueConverter(state.Current.JsonClassInfo); - if (!state.SupportContinuation && valueConverter.CanUseDirectReadOrWrite) + JsonConverter valueConverter = _valueConverter ??= GetValueConverter(elementClassInfo); + + if (!state.SupportContinuation && valueConverter.CanUseDirectReadOrWrite && state.Current.NumberHandling == null) { // Fast path that avoids validation and extra indirection. do { TKey key = enumerator.Current.Key; keyConverter.WriteWithQuotes(writer, key, options, ref state); - valueConverter.Write(writer, enumerator.Current.Value, options); } while (enumerator.MoveNext()); } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryConverter.cs index d1055df9ec5817..5bfef5de0b1eb7 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryConverter.cs @@ -71,7 +71,7 @@ protected internal override bool OnWriteResume(Utf8JsonWriter writer, TCollectio enumerator = (IDictionaryEnumerator)state.Current.CollectionEnumerator; } - JsonConverter valueConverter = _valueConverter ??= GetValueConverter(state.Current.JsonClassInfo); + JsonConverter valueConverter = _valueConverter ??= GetValueConverter(state.Current.JsonClassInfo.ElementClassInfo!); do { if (ShouldFlush(writer, ref state)) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryOfTKeyTValueConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryOfTKeyTValueConverter.cs index 4fb795ce71a8f4..44c2069f6fd2e4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryOfTKeyTValueConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IDictionaryOfTKeyTValueConverter.cs @@ -71,7 +71,7 @@ protected internal override bool OnWriteResume( } JsonConverter keyConverter = _keyConverter ??= GetKeyConverter(KeyType, options); - JsonConverter valueConverter = _valueConverter ??= GetValueConverter(state.Current.JsonClassInfo); + JsonConverter valueConverter = _valueConverter ??= GetValueConverter(state.Current.JsonClassInfo.ElementClassInfo!); do { if (ShouldFlush(writer, ref state)) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableDefaultConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableDefaultConverter.cs index e59b4c8f95bee1..3f05795d08bda8 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableDefaultConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IEnumerableDefaultConverter.cs @@ -16,9 +16,9 @@ internal abstract class IEnumerableDefaultConverter protected abstract void CreateCollection(ref Utf8JsonReader reader, ref ReadStack state, JsonSerializerOptions options); protected virtual void ConvertCollection(ref ReadStack state, JsonSerializerOptions options) { } - protected static JsonConverter GetElementConverter(ref ReadStack state) + protected static JsonConverter GetElementConverter(JsonClassInfo elementClassInfo) { - JsonConverter converter = (JsonConverter)state.Current.JsonClassInfo.ElementClassInfo!.PropertyInfoForClassInfo.ConverterBase; + JsonConverter converter = (JsonConverter)elementClassInfo.PropertyInfoForClassInfo.ConverterBase; Debug.Assert(converter != null); // It should not be possible to have a null converter at this point. return converter; @@ -39,6 +39,8 @@ internal override bool OnTryRead( ref ReadStack state, [MaybeNullWhen(false)] out TCollection value) { + JsonClassInfo elementClassInfo = state.Current.JsonClassInfo.ElementClassInfo!; + if (state.UseFastPath) { // Fast path that avoids maintaining state variables and dealing with preserved references. @@ -50,8 +52,8 @@ internal override bool OnTryRead( CreateCollection(ref reader, ref state, options); - JsonConverter elementConverter = GetElementConverter(ref state); - if (elementConverter.CanUseDirectReadOrWrite) + JsonConverter elementConverter = GetElementConverter(elementClassInfo); + if (elementConverter.CanUseDirectReadOrWrite && state.Current.NumberHandling == null) { // Fast path that avoids validation and extra indirection. while (true) @@ -137,7 +139,7 @@ internal override bool OnTryRead( if (state.Current.ObjectState < StackFrameObjectState.ReadElements) { - JsonConverter elementConverter = GetElementConverter(ref state); + JsonConverter elementConverter = GetElementConverter(elementClassInfo); // Process all elements. while (true) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IListConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IListConverter.cs index 3f6516cdfbb2d0..606ddfa7ca3d78 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IListConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IListConverter.cs @@ -49,36 +49,39 @@ protected override void CreateCollection(ref Utf8JsonReader reader, ref ReadStac protected override bool OnWriteResume(Utf8JsonWriter writer, TCollection value, JsonSerializerOptions options, ref WriteStack state) { - IEnumerator enumerator; - if (state.Current.CollectionEnumerator == null) + IList list = value; + + // Using an index is 2x faster than using an enumerator. + int index = state.Current.EnumeratorIndex; + JsonConverter elementConverter = GetElementConverter(ref state); + + if (elementConverter.CanUseDirectReadOrWrite && state.Current.NumberHandling == null) { - enumerator = value.GetEnumerator(); - if (!enumerator.MoveNext()) + // Fast path that avoids validation and extra indirection. + for (; index < list.Count; index++) { - return true; + elementConverter.Write(writer, list[index], options); } } else { - enumerator = state.Current.CollectionEnumerator; - } - - JsonConverter converter = GetElementConverter(ref state); - do - { - if (ShouldFlush(writer, ref state)) + for (; index < list.Count; index++) { - state.Current.CollectionEnumerator = enumerator; - return false; - } + object? element = list[index]; + if (!elementConverter.TryWrite(writer, element, options, ref state)) + { + state.Current.EnumeratorIndex = index; + return false; + } - object? element = enumerator.Current; - if (!converter.TryWrite(writer, element, options, ref state)) - { - state.Current.CollectionEnumerator = enumerator; - return false; + if (ShouldFlush(writer, ref state)) + { + state.Current.EnumeratorIndex = ++index; + return false; + } } - } while (enumerator.MoveNext()); + } + return true; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IReadOnlyDictionaryOfTKeyTValueConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IReadOnlyDictionaryOfTKeyTValueConverter.cs index 125f37534c1cc8..28c3c245b1c23b 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IReadOnlyDictionaryOfTKeyTValueConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IReadOnlyDictionaryOfTKeyTValueConverter.cs @@ -42,7 +42,7 @@ protected internal override bool OnWriteResume(Utf8JsonWriter writer, TCollectio } JsonConverter keyConverter = _keyConverter ??= GetKeyConverter(KeyType, options); - JsonConverter valueConverter = _valueConverter ??= GetValueConverter(state.Current.JsonClassInfo); + JsonConverter valueConverter = _valueConverter ??= GetValueConverter(state.Current.JsonClassInfo.ElementClassInfo!); do { if (ShouldFlush(writer, ref state)) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ImmutableDictionaryOfTKeyTValueConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ImmutableDictionaryOfTKeyTValueConverter.cs index 9f5e5d0506474c..ac9544d0528591 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ImmutableDictionaryOfTKeyTValueConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ImmutableDictionaryOfTKeyTValueConverter.cs @@ -53,7 +53,7 @@ protected internal override bool OnWriteResume(Utf8JsonWriter writer, TCollectio } JsonConverter keyConverter = _keyConverter ??= GetKeyConverter(KeyType, options); - JsonConverter valueConverter = _valueConverter ??= GetValueConverter(state.Current.JsonClassInfo); + JsonConverter valueConverter = _valueConverter ??= GetValueConverter(state.Current.JsonClassInfo.ElementClassInfo!); do { if (ShouldFlush(writer, ref state)) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ListOfTConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ListOfTConverter.cs index 5004bc1ded4c6e..52362693749eb7 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ListOfTConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/ListOfTConverter.cs @@ -33,7 +33,7 @@ protected override bool OnWriteResume(Utf8JsonWriter writer, TCollection value, int index = state.Current.EnumeratorIndex; JsonConverter elementConverter = GetElementConverter(ref state); - if (elementConverter.CanUseDirectReadOrWrite) + if (elementConverter.CanUseDirectReadOrWrite && state.Current.NumberHandling == null) { // Fast path that avoids validation and extra indirection. for (; index < list.Count; index++) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/KeyValuePairConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/KeyValuePairConverter.cs index bee101fbfc1812..9f2de6a1897eaa 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/KeyValuePairConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/KeyValuePairConverter.cs @@ -86,6 +86,7 @@ protected override bool TryLookupConstructorParameter( Debug.Assert(jsonParameterInfo != null); argState.ParameterIndex++; argState.JsonParameterInfo = jsonParameterInfo; + state.Current.NumberHandling = jsonParameterInfo.NumberHandling; return true; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectDefaultConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectDefaultConverter.cs index 008e9ad3eb54c8..237bb8367b0627 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectDefaultConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectDefaultConverter.cs @@ -256,6 +256,7 @@ internal sealed override bool OnTryWrite( // Remember the current property for JsonPath support if an exception is thrown. state.Current.DeclaredJsonPropertyInfo = jsonPropertyInfo; + state.Current.NumberHandling = jsonPropertyInfo.NumberHandling; if (jsonPropertyInfo.ShouldSerialize) { @@ -312,6 +313,7 @@ internal sealed override bool OnTryWrite( { JsonPropertyInfo jsonPropertyInfo = propertyCacheArray![state.Current.EnumeratorIndex]; state.Current.DeclaredJsonPropertyInfo = jsonPropertyInfo; + state.Current.NumberHandling = jsonPropertyInfo.NumberHandling; if (jsonPropertyInfo.ShouldSerialize) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.cs index 120b687bdabc0d..f001c86198ed53 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Object/ObjectWithParameterizedConstructorConverter.cs @@ -467,6 +467,9 @@ protected virtual bool TryLookupConstructorParameter( state.Current.JsonPropertyName = utf8PropertyName; state.Current.CtorArgumentState.JsonParameterInfo = jsonParameterInfo; + + state.Current.NumberHandling = jsonParameterInfo?.NumberHandling; + return jsonParameterInfo != null; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/ByteConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/ByteConverter.cs index 774341c8e39ae6..f02b3ac8d70d50 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/ByteConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/ByteConverter.cs @@ -5,6 +5,11 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class ByteConverter : JsonConverter { + public ByteConverter() + { + IsInternalConverterForNumberType = true; + } + public override byte Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetByte(); @@ -24,5 +29,27 @@ internal override void WriteWithQuotes(Utf8JsonWriter writer, byte value, JsonSe { writer.WritePropertyName(value); } + + internal override byte ReadNumberWithCustomHandling(ref Utf8JsonReader reader, JsonNumberHandling handling) + { + if (reader.TokenType == JsonTokenType.String && (JsonNumberHandling.AllowReadingFromString & handling) != 0) + { + return reader.GetByteWithQuotes(); + } + + return reader.GetByte(); + } + + internal override void WriteNumberWithCustomHandling(Utf8JsonWriter writer, byte value, JsonNumberHandling handling) + { + if ((JsonNumberHandling.WriteAsString & handling) != 0) + { + writer.WriteNumberValueAsString(value); + } + else + { + writer.WriteNumberValue(value); + } + } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/DecimalConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/DecimalConverter.cs index c78316a88f95fd..559079eec617a5 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/DecimalConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/DecimalConverter.cs @@ -5,6 +5,11 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class DecimalConverter : JsonConverter { + public DecimalConverter() + { + IsInternalConverterForNumberType = true; + } + public override decimal Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetDecimal(); @@ -24,5 +29,28 @@ internal override void WriteWithQuotes(Utf8JsonWriter writer, decimal value, Jso { writer.WritePropertyName(value); } + + internal override decimal ReadNumberWithCustomHandling(ref Utf8JsonReader reader, JsonNumberHandling handling) + { + if (reader.TokenType == JsonTokenType.String && + (JsonNumberHandling.AllowReadingFromString & handling) != 0) + { + return reader.GetDecimalWithQuotes(); + } + + return reader.GetDecimal(); + } + + internal override void WriteNumberWithCustomHandling(Utf8JsonWriter writer, decimal value, JsonNumberHandling handling) + { + if ((JsonNumberHandling.WriteAsString & handling) != 0) + { + writer.WriteNumberValueAsString(value); + } + else + { + writer.WriteNumberValue(value); + } + } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/DoubleConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/DoubleConverter.cs index 641ad8e9991e8f..7b929b10e33974 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/DoubleConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/DoubleConverter.cs @@ -5,6 +5,11 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class DoubleConverter : JsonConverter { + public DoubleConverter() + { + IsInternalConverterForNumberType = true; + } + public override double Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetDouble(); @@ -24,5 +29,38 @@ internal override void WriteWithQuotes(Utf8JsonWriter writer, double value, Json { writer.WritePropertyName(value); } + + internal override double ReadNumberWithCustomHandling(ref Utf8JsonReader reader, JsonNumberHandling handling) + { + if (reader.TokenType == JsonTokenType.String) + { + if ((JsonNumberHandling.AllowReadingFromString & handling) != 0) + { + return reader.GetDoubleWithQuotes(); + } + else if ((JsonNumberHandling.AllowNamedFloatingPointLiterals & handling) != 0) + { + return reader.GetDoubleFloatingPointConstant(); + } + } + + return reader.GetDouble(); + } + + internal override void WriteNumberWithCustomHandling(Utf8JsonWriter writer, double value, JsonNumberHandling handling) + { + if ((JsonNumberHandling.WriteAsString & handling) != 0) + { + writer.WriteNumberValueAsString(value); + } + else if ((JsonNumberHandling.AllowNamedFloatingPointLiterals & handling) != 0) + { + writer.WriteFloatingPointConstant(value); + } + else + { + writer.WriteNumberValue(value); + } + } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/Int16Converter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/Int16Converter.cs index c01ee00032cc55..f62da456a3a484 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/Int16Converter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/Int16Converter.cs @@ -1,12 +1,15 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Diagnostics.CodeAnalysis; - namespace System.Text.Json.Serialization.Converters { internal sealed class Int16Converter : JsonConverter { + public Int16Converter() + { + IsInternalConverterForNumberType = true; + } + public override short Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetInt16(); @@ -27,5 +30,29 @@ internal override void WriteWithQuotes(Utf8JsonWriter writer, short value, JsonS { writer.WritePropertyName(value); } + + internal override short ReadNumberWithCustomHandling(ref Utf8JsonReader reader, JsonNumberHandling handling) + { + if (reader.TokenType == JsonTokenType.String && + (JsonNumberHandling.AllowReadingFromString & handling) != 0) + { + return reader.GetInt16WithQuotes(); + } + + return reader.GetInt16(); + } + + internal override void WriteNumberWithCustomHandling(Utf8JsonWriter writer, short value, JsonNumberHandling handling) + { + if ((JsonNumberHandling.WriteAsString & handling) != 0) + { + writer.WriteNumberValueAsString(value); + } + else + { + // For performance, lift up the writer implementation. + writer.WriteNumberValue((long)value); + } + } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/Int32Converter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/Int32Converter.cs index 5fc881a6b2e4d1..85d7fb3c6aa90c 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/Int32Converter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/Int32Converter.cs @@ -5,6 +5,11 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class Int32Converter : JsonConverter { + public Int32Converter() + { + IsInternalConverterForNumberType = true; + } + public override int Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetInt32(); @@ -25,5 +30,29 @@ internal override void WriteWithQuotes(Utf8JsonWriter writer, int value, JsonSer { writer.WritePropertyName(value); } + + internal override int ReadNumberWithCustomHandling(ref Utf8JsonReader reader, JsonNumberHandling handling) + { + if (reader.TokenType == JsonTokenType.String && + (JsonNumberHandling.AllowReadingFromString & handling) != 0) + { + return reader.GetInt32WithQuotes(); + } + + return reader.GetInt32(); + } + + internal override void WriteNumberWithCustomHandling(Utf8JsonWriter writer, int value, JsonNumberHandling handling) + { + if ((JsonNumberHandling.WriteAsString & handling) != 0) + { + writer.WriteNumberValueAsString(value); + } + else + { + // For performance, lift up the writer implementation. + writer.WriteNumberValue((long)value); + } + } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/Int64Converter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/Int64Converter.cs index 4aec3ff4e48564..48725dccbeecca 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/Int64Converter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/Int64Converter.cs @@ -5,6 +5,11 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class Int64Converter : JsonConverter { + public Int64Converter() + { + IsInternalConverterForNumberType = true; + } + public override long Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetInt64(); @@ -24,5 +29,28 @@ internal override void WriteWithQuotes(Utf8JsonWriter writer, long value, JsonSe { writer.WritePropertyName(value); } + + internal override long ReadNumberWithCustomHandling(ref Utf8JsonReader reader, JsonNumberHandling handling) + { + if (reader.TokenType == JsonTokenType.String && + (JsonNumberHandling.AllowReadingFromString & handling) != 0) + { + return reader.GetInt64WithQuotes(); + } + + return reader.GetInt64(); + } + + internal override void WriteNumberWithCustomHandling(Utf8JsonWriter writer, long value, JsonNumberHandling handling) + { + if ((JsonNumberHandling.WriteAsString & handling) != 0) + { + writer.WriteNumberValueAsString(value); + } + else + { + writer.WriteNumberValue(value); + } + } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/NullableConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/NullableConverter.cs index e2c0ddcc43e01e..44e4270a26165b 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/NullableConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/NullableConverter.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics; + namespace System.Text.Json.Serialization.Converters { internal class NullableConverter : JsonConverter where T : struct @@ -12,6 +14,7 @@ internal class NullableConverter : JsonConverter where T : struct public NullableConverter(JsonConverter converter) { _converter = converter; + IsInternalConverterForNumberType = converter.IsInternalConverterForNumberType; } public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) @@ -40,5 +43,32 @@ public override void Write(Utf8JsonWriter writer, T? value, JsonSerializerOption _converter.Write(writer, value.Value, options); } } + + internal override T? ReadNumberWithCustomHandling(ref Utf8JsonReader reader, JsonNumberHandling numberHandling) + { + // We do not check _converter.HandleNull, as the underlying struct cannot be null. + // A custom converter for some type T? can handle null. + if (reader.TokenType == JsonTokenType.Null) + { + return null; + } + + T value = _converter.ReadNumberWithCustomHandling(ref reader, numberHandling); + return value; + } + + internal override void WriteNumberWithCustomHandling(Utf8JsonWriter writer, T? value, JsonNumberHandling handling) + { + if (!value.HasValue) + { + // We do not check _converter.HandleNull, as the underlying struct cannot be null. + // A custom converter for some type T? can handle null. + writer.WriteNullValue(); + } + else + { + _converter.WriteNumberWithCustomHandling(writer, value.Value, handling); + } + } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/SByteConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/SByteConverter.cs index 49ba6699b45301..0896bf97527ef5 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/SByteConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/SByteConverter.cs @@ -5,6 +5,11 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class SByteConverter : JsonConverter { + public SByteConverter() + { + IsInternalConverterForNumberType = true; + } + public override sbyte Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetSByte(); @@ -24,5 +29,28 @@ internal override void WriteWithQuotes(Utf8JsonWriter writer, sbyte value, JsonS { writer.WritePropertyName(value); } + + internal override sbyte ReadNumberWithCustomHandling(ref Utf8JsonReader reader, JsonNumberHandling handling) + { + if (reader.TokenType == JsonTokenType.String && + (JsonNumberHandling.AllowReadingFromString & handling) != 0) + { + return reader.GetSByteWithQuotes(); + } + + return reader.GetSByte(); + } + + internal override void WriteNumberWithCustomHandling(Utf8JsonWriter writer, sbyte value, JsonNumberHandling handling) + { + if ((JsonNumberHandling.WriteAsString & handling) != 0) + { + writer.WriteNumberValueAsString(value); + } + else + { + writer.WriteNumberValue(value); + } + } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/SingleConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/SingleConverter.cs index e2f7d76761e003..9b7e6fad328c63 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/SingleConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/SingleConverter.cs @@ -5,6 +5,12 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class SingleConverter : JsonConverter { + + public SingleConverter() + { + IsInternalConverterForNumberType = true; + } + public override float Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetSingle(); @@ -24,5 +30,38 @@ internal override void WriteWithQuotes(Utf8JsonWriter writer, float value, JsonS { writer.WritePropertyName(value); } + + internal override float ReadNumberWithCustomHandling(ref Utf8JsonReader reader, JsonNumberHandling handling) + { + if (reader.TokenType == JsonTokenType.String) + { + if ((JsonNumberHandling.AllowReadingFromString & handling) != 0) + { + return reader.GetSingleWithQuotes(); + } + else if ((JsonNumberHandling.AllowNamedFloatingPointLiterals & handling) != 0) + { + return reader.GetSingleFloatingPointConstant(); + } + } + + return reader.GetSingle(); + } + + internal override void WriteNumberWithCustomHandling(Utf8JsonWriter writer, float value, JsonNumberHandling handling) + { + if ((JsonNumberHandling.WriteAsString & handling) != 0) + { + writer.WriteNumberValueAsString(value); + } + else if ((JsonNumberHandling.AllowNamedFloatingPointLiterals & handling) != 0) + { + writer.WriteFloatingPointConstant(value); + } + else + { + writer.WriteNumberValue(value); + } + } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/StringConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/StringConverter.cs index f03d9ac1cba129..08972856b698c6 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/StringConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/StringConverter.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. -using System.Diagnostics.CodeAnalysis; - namespace System.Text.Json.Serialization.Converters { internal sealed class StringConverter : JsonConverter diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UInt16Converter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UInt16Converter.cs index db2af0a5f2e3ba..249d2a059ffa1d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UInt16Converter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UInt16Converter.cs @@ -5,6 +5,11 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class UInt16Converter : JsonConverter { + public UInt16Converter() + { + IsInternalConverterForNumberType = true; + } + public override ushort Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetUInt16(); @@ -25,5 +30,29 @@ internal override void WriteWithQuotes(Utf8JsonWriter writer, ushort value, Json { writer.WritePropertyName(value); } + + internal override ushort ReadNumberWithCustomHandling(ref Utf8JsonReader reader, JsonNumberHandling handling) + { + if (reader.TokenType == JsonTokenType.String && + (JsonNumberHandling.AllowReadingFromString & handling) != 0) + { + return reader.GetUInt16WithQuotes(); + } + + return reader.GetUInt16(); + } + + internal override void WriteNumberWithCustomHandling(Utf8JsonWriter writer, ushort value, JsonNumberHandling handling) + { + if ((JsonNumberHandling.WriteAsString & handling) != 0) + { + writer.WriteNumberValueAsString(value); + } + else + { + // For performance, lift up the writer implementation. + writer.WriteNumberValue((long)value); + } + } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UInt32Converter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UInt32Converter.cs index 131e6feb1b0544..2c6ea5e07d6b46 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UInt32Converter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UInt32Converter.cs @@ -5,6 +5,11 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class UInt32Converter : JsonConverter { + public UInt32Converter() + { + IsInternalConverterForNumberType = true; + } + public override uint Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetUInt32(); @@ -25,5 +30,29 @@ internal override void WriteWithQuotes(Utf8JsonWriter writer, uint value, JsonSe { writer.WritePropertyName(value); } + + internal override uint ReadNumberWithCustomHandling(ref Utf8JsonReader reader, JsonNumberHandling handling) + { + if (reader.TokenType == JsonTokenType.String && + (JsonNumberHandling.AllowReadingFromString & handling) != 0) + { + return reader.GetUInt32WithQuotes(); + } + + return reader.GetUInt32(); + } + + internal override void WriteNumberWithCustomHandling(Utf8JsonWriter writer, uint value, JsonNumberHandling handling) + { + if ((JsonNumberHandling.WriteAsString & handling) != 0) + { + writer.WriteNumberValueAsString(value); + } + else + { + // For performance, lift up the writer implementation. + writer.WriteNumberValue((ulong)value); + } + } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UInt64Converter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UInt64Converter.cs index 95f9025c39812d..3d94f296de13fe 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UInt64Converter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/UInt64Converter.cs @@ -5,6 +5,11 @@ namespace System.Text.Json.Serialization.Converters { internal sealed class UInt64Converter : JsonConverter { + public UInt64Converter() + { + IsInternalConverterForNumberType = true; + } + public override ulong Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.GetUInt64(); @@ -24,5 +29,28 @@ internal override void WriteWithQuotes(Utf8JsonWriter writer, ulong value, JsonS { writer.WritePropertyName(value); } + + internal override ulong ReadNumberWithCustomHandling(ref Utf8JsonReader reader, JsonNumberHandling handling) + { + if (reader.TokenType == JsonTokenType.String && + (JsonNumberHandling.AllowReadingFromString & handling) != 0) + { + return reader.GetUInt64WithQuotes(); + } + + return reader.GetUInt64(); + } + + internal override void WriteNumberWithCustomHandling(Utf8JsonWriter writer, ulong value, JsonNumberHandling handling) + { + if ((JsonNumberHandling.WriteAsString & handling) != 0) + { + writer.WriteNumberValueAsString(value); + } + else + { + writer.WriteNumberValue(value); + } + } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.Cache.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.Cache.cs index 785abae8a60793..7b01b16fb47725 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.Cache.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.Cache.cs @@ -52,10 +52,14 @@ internal sealed partial class JsonClassInfo // Use an array (instead of List) for highest performance. private volatile PropertyRef[]? _propertyRefsSorted; - public static JsonPropertyInfo AddProperty(MemberInfo memberInfo, Type memberType, Type parentClassType, JsonSerializerOptions options) + public static JsonPropertyInfo AddProperty( + MemberInfo memberInfo, + Type memberType, + Type parentClassType, + JsonNumberHandling? parentTypeNumberHandling, + JsonSerializerOptions options) { JsonIgnoreCondition? ignoreCondition = JsonPropertyInfo.GetAttribute(memberInfo)?.Condition; - if (ignoreCondition == JsonIgnoreCondition.Always) { return JsonPropertyInfo.CreateIgnoredPropertyPlaceholder(memberInfo, options); @@ -75,6 +79,7 @@ public static JsonPropertyInfo AddProperty(MemberInfo memberInfo, Type memberTyp parentClassType, converter, options, + parentTypeNumberHandling, ignoreCondition); } @@ -85,6 +90,7 @@ internal static JsonPropertyInfo CreateProperty( Type parentClassType, JsonConverter converter, JsonSerializerOptions options, + JsonNumberHandling? parentTypeNumberHandling = null, JsonIgnoreCondition? ignoreCondition = null) { // Create the JsonPropertyInfo instance. @@ -98,6 +104,7 @@ internal static JsonPropertyInfo CreateProperty( memberInfo, converter, ignoreCondition, + parentTypeNumberHandling, options); return jsonPropertyInfo; @@ -113,13 +120,16 @@ internal static JsonPropertyInfo CreatePropertyInfoForClassInfo( JsonConverter converter, JsonSerializerOptions options) { + JsonNumberHandling? numberHandling = GetNumberHandlingForType(declaredPropertyType); + JsonPropertyInfo jsonPropertyInfo = CreateProperty( declaredPropertyType: declaredPropertyType, runtimePropertyType: runtimePropertyType, memberInfo: null, // Not a real property so this is null. parentClassType: JsonClassInfo.ObjectType, // a dummy value (not used) converter: converter, - options); + options, + parentTypeNumberHandling: numberHandling); Debug.Assert(jsonPropertyInfo.IsForClassInfo); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs index bdd5f7442671a5..6f523b19b8294c 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonClassInfo.cs @@ -92,6 +92,8 @@ public JsonClassInfo(Type type, JsonSerializerOptions options) Options); ClassType = converter.ClassType; + JsonNumberHandling? typeNumberHandling = GetNumberHandlingForType(Type); + PropertyInfoForClassInfo = CreatePropertyInfoForClassInfo(Type, runtimeType, converter, Options); switch (ClassType) @@ -127,7 +129,7 @@ public JsonClassInfo(Type type, JsonSerializerOptions options) if (propertyInfo.GetMethod?.IsPublic == true || propertyInfo.SetMethod?.IsPublic == true) { - CacheMember(currentType, propertyInfo.PropertyType, propertyInfo, cache, ref ignoredMembers); + CacheMember(currentType, propertyInfo.PropertyType, propertyInfo, typeNumberHandling, cache, ref ignoredMembers); } else { @@ -153,7 +155,7 @@ public JsonClassInfo(Type type, JsonSerializerOptions options) { if (hasJsonInclude || Options.IncludeFields) { - CacheMember(currentType, fieldInfo.FieldType, fieldInfo, cache, ref ignoredMembers); + CacheMember(currentType, fieldInfo.FieldType, fieldInfo, typeNumberHandling, cache, ref ignoredMembers); } } else @@ -228,10 +230,11 @@ private void CacheMember( Type declaringType, Type memberType, MemberInfo memberInfo, + JsonNumberHandling? typeNumberHandling, Dictionary cache, ref Dictionary? ignoredMembers) { - JsonPropertyInfo jsonPropertyInfo = AddProperty(memberInfo, memberType, declaringType, Options); + JsonPropertyInfo jsonPropertyInfo = AddProperty(memberInfo, memberType, declaringType, typeNumberHandling, Options); Debug.Assert(jsonPropertyInfo.NameAsString != null); string memberName = memberInfo.Name; @@ -573,5 +576,13 @@ private static bool IsByRefLike(Type type) return false; #endif } + + private static JsonNumberHandling? GetNumberHandlingForType(Type type) + { + var numberHandlingAttribute = + (JsonNumberHandlingAttribute?)JsonSerializerOptions.GetAttributeThatCanHaveMultiple(type, typeof(JsonNumberHandlingAttribute)); + + return numberHandlingAttribute?.Handling; + } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverter.cs index b775aec8c85ce7..f8a000ecfeeacc 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonConverter.cs @@ -44,6 +44,16 @@ internal JsonConverter() { } /// internal bool IsValueType { get; set; } + /// + /// Whether the converter is built-in. + /// + internal bool IsInternalConverter { get; set; } + + /// + /// Whether the converter is built-in and handles a number type. + /// + internal bool IsInternalConverterForNumberType; + /// /// Loosely-typed ReadCore() that forwards to strongly-typed ReadCore(). /// @@ -76,7 +86,7 @@ internal bool ShouldFlush(Utf8JsonWriter writer, ref WriteStack state) internal abstract void WriteWithQuotesAsObject(Utf8JsonWriter writer, object value, JsonSerializerOptions options, ref WriteStack state); // Whether a type (ClassType.Object) is deserialized using a parameterized constructor. - internal virtual bool ConstructorIsParameterized => false; + internal virtual bool ConstructorIsParameterized { get; } internal ConstructorInfo? ConstructorInfo { get; set; } 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 52dba1df4bb4dc..dfd81ffd871b27 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 @@ -3,7 +3,6 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; namespace System.Text.Json.Serialization { @@ -69,11 +68,6 @@ internal override sealed JsonParameterInfo CreateJsonParameterInfo() /// internal bool CanBeNull { get; } - /// - /// Is the converter built-in. - /// - internal bool IsInternalConverter { get; set; } - // This non-generic API is sealed as it just forwards to the generic version. internal sealed override bool TryWriteAsObject(Utf8JsonWriter writer, object? value, JsonSerializerOptions options, ref WriteStack state) { @@ -131,7 +125,14 @@ internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSeriali // For performance, only perform validation on internal converters on debug builds. if (IsInternalConverter) { - value = Read(ref reader, typeToConvert, options); + if (IsInternalConverterForNumberType && state.Current.NumberHandling != null) + { + value = ReadNumberWithCustomHandling(ref reader, state.Current.NumberHandling.Value); + } + else + { + value = Read(ref reader, typeToConvert, options); + } } else #endif @@ -140,7 +141,15 @@ internal bool TryRead(ref Utf8JsonReader reader, Type typeToConvert, JsonSeriali int originalPropertyDepth = reader.CurrentDepth; long originalPropertyBytesConsumed = reader.BytesConsumed; - value = Read(ref reader, typeToConvert, options); + if (IsInternalConverterForNumberType && state.Current.NumberHandling != null) + { + value = ReadNumberWithCustomHandling(ref reader, state.Current.NumberHandling.Value); + } + else + { + value = Read(ref reader, typeToConvert, options); + } + VerifyRead( originalPropertyTokenType, originalPropertyDepth, @@ -309,7 +318,15 @@ internal bool TryWrite(Utf8JsonWriter writer, in T value, JsonSerializerOptions int originalPropertyDepth = writer.CurrentDepth; - Write(writer, value, options); + if (IsInternalConverterForNumberType && state.Current.NumberHandling != null) + { + WriteNumberWithCustomHandling(writer, value, state.Current.NumberHandling.Value); + } + else + { + Write(writer, value, options); + } + VerifyWrite(originalPropertyDepth, writer); return true; } @@ -452,5 +469,11 @@ internal virtual void WriteWithQuotes(Utf8JsonWriter writer, [DisallowNull] T va internal sealed override void WriteWithQuotesAsObject(Utf8JsonWriter writer, object value, JsonSerializerOptions options, ref WriteStack state) => WriteWithQuotes(writer, (T)value, options, ref state); + + internal virtual T ReadNumberWithCustomHandling(ref Utf8JsonReader reader, JsonNumberHandling handling) + => throw new InvalidOperationException(); + + internal virtual void WriteNumberWithCustomHandling(Utf8JsonWriter writer, T value, JsonNumberHandling handling) + => throw new InvalidOperationException(); } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonNumberHandling.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonNumberHandling.cs new file mode 100644 index 00000000000000..09be0bfc94c81e --- /dev/null +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonNumberHandling.cs @@ -0,0 +1,32 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Text.Json.Serialization +{ + /// + /// Determines how handles numbers when serializing and deserializing. + /// + [Flags] + public enum JsonNumberHandling + { + /// + /// Numbers will only be read from tokens and will only be written as JSON numbers (without quotes). + /// + Strict = 0x0, + /// + /// Numbers can be read from tokens. + /// Does not prevent numbers from being read from token. + /// + AllowReadingFromString = 0x1, + /// + /// Numbers will be written as JSON strings (with quotes), not as JSON numbers. + /// + WriteAsString = 0x2, + /// + /// The "NaN", "Infinity", and "-Infinity" tokens can be read as floating-point constants, + /// and the , , and + /// values will be written as their corresponding JSON string representations. + /// + AllowNamedFloatingPointLiterals = 0x4 + } +} diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonParameterInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonParameterInfo.cs index 0ccdbeeafda1ef..4687107f7f82be 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonParameterInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonParameterInfo.cs @@ -27,6 +27,8 @@ internal abstract class JsonParameterInfo // The name of the parameter as UTF-8 bytes. public byte[] NameAsUtf8Bytes { get; private set; } = null!; + public JsonNumberHandling? NumberHandling { get; private set; } + // The zero-based position of the parameter in the formal parameter list. public int Position { get; private set; } @@ -63,6 +65,7 @@ public virtual void Initialize( ShouldDeserialize = true; ConverterBase = matchingProperty.ConverterBase; IgnoreDefaultValuesOnRead = matchingProperty.IgnoreDefaultValuesOnRead; + NumberHandling = matchingProperty.NumberHandling; } // Create a parameter that is ignored at run-time. It uses the same type (typeof(sbyte)) to help diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfo.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfo.cs index 38adc919f9ed04..10b92e26fac964 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfo.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfo.cs @@ -50,6 +50,14 @@ public static JsonPropertyInfo CreateIgnoredPropertyPlaceholder(MemberInfo membe public Type DeclaredPropertyType { get; private set; } = null!; + public virtual void GetPolicies(JsonIgnoreCondition? ignoreCondition, JsonNumberHandling? parentTypeNumberHandling, bool defaultValueIsNull) + { + DetermineSerializationCapabilities(ignoreCondition); + DeterminePropertyName(); + DetermineIgnoreCondition(ignoreCondition, defaultValueIsNull); + DetermineNumberHandling(parentTypeNumberHandling); + } + private void DeterminePropertyName() { if (MemberInfo == null) @@ -174,6 +182,56 @@ private void DetermineIgnoreCondition(JsonIgnoreCondition? ignoreCondition, bool #pragma warning restore CS0618 // IgnoreNullValues is obsolete } + private void DetermineNumberHandling(JsonNumberHandling? parentTypeNumberHandling) + { + if (IsForClassInfo) + { + if (parentTypeNumberHandling != null && !ConverterBase.IsInternalConverter) + { + ThrowHelper.ThrowInvalidOperationException_NumberHandlingOnPropertyInvalid(this); + } + + // Priority 1: Get handling from the type (parent type in this case is the type itself). + NumberHandling = parentTypeNumberHandling; + + // Priority 2: Get handling from JsonSerializerOptions instance. + if (!NumberHandling.HasValue && Options.NumberHandling != JsonNumberHandling.Strict) + { + NumberHandling = Options.NumberHandling; + } + } + else + { + JsonNumberHandling? handling = null; + + // Priority 1: Get handling from attribute on property or field. + if (MemberInfo != null) + { + JsonNumberHandlingAttribute? attribute = GetAttribute(MemberInfo); + + if (attribute != null && + !ConverterBase.IsInternalConverterForNumberType && + ((ClassType.Enumerable | ClassType.Dictionary) & ClassType) == 0) + { + ThrowHelper.ThrowInvalidOperationException_NumberHandlingOnPropertyInvalid(this); + } + + handling = attribute?.Handling; + } + + // Priority 2: Get handling from attribute on parent class type. + handling ??= parentTypeNumberHandling; + + // Priority 3: Get handling from JsonSerializerOptions instance. + if (!handling.HasValue && Options.NumberHandling != JsonNumberHandling.Strict) + { + handling = Options.NumberHandling; + } + + NumberHandling = handling; + } + } + public static TAttribute? GetAttribute(MemberInfo memberInfo) where TAttribute : Attribute { return (TAttribute?)memberInfo.GetCustomAttribute(typeof(TAttribute), inherit: false); @@ -182,13 +240,6 @@ private void DetermineIgnoreCondition(JsonIgnoreCondition? ignoreCondition, bool public abstract bool GetMemberAndWriteJson(object obj, ref WriteStack state, Utf8JsonWriter writer); public abstract bool GetMemberAndWriteJsonExtensionData(object obj, ref WriteStack state, Utf8JsonWriter writer); - public virtual void GetPolicies(JsonIgnoreCondition? ignoreCondition, bool defaultValueIsNull) - { - DetermineSerializationCapabilities(ignoreCondition); - DeterminePropertyName(); - DetermineIgnoreCondition(ignoreCondition, defaultValueIsNull); - } - public abstract object? GetValueAsObject(object obj); public bool HasGetter { get; set; } @@ -202,6 +253,7 @@ public virtual void Initialize( MemberInfo? memberInfo, JsonConverter converter, JsonIgnoreCondition? ignoreCondition, + JsonNumberHandling? parentTypeNumberHandling, JsonSerializerOptions options) { Debug.Assert(converter != null); @@ -344,5 +396,7 @@ public JsonClassInfo RuntimeClassInfo public bool ShouldSerialize { get; private set; } public bool ShouldDeserialize { get; private set; } public bool IsIgnored { get; private set; } + + public JsonNumberHandling? NumberHandling { get; private set; } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoOfT.cs index 83c5ee116372de..85962cdb0bf515 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonPropertyInfoOfT.cs @@ -28,6 +28,7 @@ public override void Initialize( MemberInfo? memberInfo, JsonConverter converter, JsonIgnoreCondition? ignoreCondition, + JsonNumberHandling? parentTypeNumberHandling, JsonSerializerOptions options) { base.Initialize( @@ -38,6 +39,7 @@ public override void Initialize( memberInfo, converter, ignoreCondition, + parentTypeNumberHandling, options); switch (memberInfo) @@ -89,7 +91,7 @@ public override void Initialize( } } - GetPolicies(ignoreCondition, defaultValueIsNull: Converter.CanBeNull); + GetPolicies(ignoreCondition, parentTypeNumberHandling, defaultValueIsNull: Converter.CanBeNull); } public override JsonConverter ConverterBase @@ -209,13 +211,13 @@ public override bool ReadJsonAndSetMember(object obj, ref ReadStack state, ref U success = true; } - else if (Converter.CanUseDirectReadOrWrite) + else if (Converter.CanUseDirectReadOrWrite && state.Current.NumberHandling == null) { if (!isNullToken || !IgnoreDefaultValuesOnRead || !Converter.CanBeNull) { // Optimize for internal converters by avoiding the extra call to TryRead. - T fastvalue = Converter.Read(ref reader, RuntimePropertyType!, Options); - Set!(obj, fastvalue!); + T fastValue = Converter.Read(ref reader, RuntimePropertyType!, Options); + Set!(obj, fastValue!); } success = true; @@ -253,7 +255,7 @@ public override bool ReadJsonAsObject(ref ReadStack state, ref Utf8JsonReader re else { // Optimize for internal converters by avoiding the extra call to TryRead. - if (Converter.CanUseDirectReadOrWrite) + if (Converter.CanUseDirectReadOrWrite && state.Current.NumberHandling == null) { value = Converter.Read(ref reader, RuntimePropertyType!, Options); success = true; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandlePropertyName.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandlePropertyName.cs index 04bb332121f9fa..17a0669b2a4ab2 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandlePropertyName.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.HandlePropertyName.cs @@ -55,6 +55,7 @@ internal static JsonPropertyInfo LookupProperty( } state.Current.JsonPropertyInfo = jsonPropertyInfo; + state.Current.NumberHandling = jsonPropertyInfo.NumberHandling; return jsonPropertyInfo; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Helpers.cs index 4e7946872454c4..8b01c199e6e470 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Helpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Helpers.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; using System.Text.Json.Serialization; namespace System.Text.Json @@ -35,5 +36,11 @@ private static TValue ReadCore(JsonConverter jsonConverter, ref Utf8Json Debug.Assert(value == null || value is TValue); return (TValue)value!; } + + internal static bool IsValidNumberHandlingValue(JsonNumberHandling handling) + { + int handlingValue = (int)handling; + return handlingValue >= 0 && handlingValue <= 7; + } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs index 0796280c369dcd..860b49315a404d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Converters.cs @@ -325,7 +325,7 @@ private JsonConverter GetConverterFromAttribute(JsonConverterAttribute converter return GetAttributeThatCanHaveMultiple(attributeType, classType, memberInfo, attributes); } - private static Attribute? GetAttributeThatCanHaveMultiple(Type classType, Type attributeType) + internal static Attribute? GetAttributeThatCanHaveMultiple(Type classType, Type attributeType) { object[] attributes = classType.GetCustomAttributes(attributeType, inherit: false); return GetAttributeThatCanHaveMultiple(attributeType, classType, null, attributes); diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs index e26eb9e0176aab..4217f61a61fc84 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.cs @@ -33,6 +33,7 @@ public sealed partial class JsonSerializerOptions private ReferenceHandler? _referenceHandler; private JavaScriptEncoder? _encoder; private JsonIgnoreCondition _defaultIgnoreCondition; + private JsonNumberHandling _numberHandling; private int _defaultBufferSize = BufferSizeDefault; private int _maxDepth; @@ -74,6 +75,7 @@ public JsonSerializerOptions(JsonSerializerOptions options) _referenceHandler = options._referenceHandler; _encoder = options._encoder; _defaultIgnoreCondition = options._defaultIgnoreCondition; + _numberHandling = options._numberHandling; _defaultBufferSize = options._defaultBufferSize; _maxDepth = options._maxDepth; @@ -262,6 +264,27 @@ public JsonIgnoreCondition DefaultIgnoreCondition } } + /// + /// Specifies how number types should be handled when serializing or deserializing. + /// + /// + /// Thrown if this property is set after serialization or deserialization has occurred. + /// + public JsonNumberHandling NumberHandling + { + get => _numberHandling; + set + { + VerifyMutable(); + + if (!JsonSerializer.IsValidNumberHandlingValue(value)) + { + throw new ArgumentOutOfRangeException(nameof(value)); + } + _numberHandling = value; + } + } + /// /// Determines whether read-only properties are ignored during serialization. /// A property is read-only if it contains a public getter but not a public setter. diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStack.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStack.cs index c3b1ba7c38a74e..ac03e3b6adba67 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStack.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStack.cs @@ -87,6 +87,8 @@ public void Initialize(Type type, JsonSerializerOptions options, bool supportCon // The initial JsonPropertyInfo will be used to obtain the converter. Current.JsonPropertyInfo = jsonClassInfo.PropertyInfoForClassInfo; + Current.NumberHandling = Current.JsonPropertyInfo.NumberHandling; + bool preserveReferences = options.ReferenceHandler != null; if (preserveReferences) { @@ -109,6 +111,8 @@ public void Push() else { JsonClassInfo jsonClassInfo; + JsonNumberHandling? numberHandling = Current.NumberHandling; + if (Current.JsonClassInfo.ClassType == ClassType.Object) { if (Current.JsonPropertyInfo != null) @@ -120,13 +124,14 @@ public void Push() jsonClassInfo = Current.CtorArgumentState!.JsonParameterInfo!.RuntimeClassInfo; } } - else if ((Current.JsonClassInfo.ClassType & (ClassType.Value | ClassType.NewValue)) != 0) + else if (((ClassType.Value | ClassType.NewValue) & Current.JsonClassInfo.ClassType) != 0) { // Although ClassType.Value doesn't push, a custom custom converter may re-enter serialization. jsonClassInfo = Current.JsonPropertyInfo!.RuntimeClassInfo; } else { + Debug.Assert(((ClassType.Enumerable | ClassType.Dictionary) & Current.JsonClassInfo.ClassType) != 0); jsonClassInfo = Current.JsonClassInfo.ElementClassInfo!; } @@ -135,6 +140,8 @@ public void Push() Current.JsonClassInfo = jsonClassInfo; Current.JsonPropertyInfo = jsonClassInfo.PropertyInfoForClassInfo; + // Allow number handling on property to win over handling on type. + Current.NumberHandling = numberHandling ?? Current.JsonPropertyInfo.NumberHandling; } } else if (_continuationCount == 1) @@ -159,7 +166,7 @@ public void Push() } } - SetConstrutorArgumentState(); + SetConstructorArgumentState(); } public void Pop(bool success) @@ -210,7 +217,7 @@ public void Pop(bool success) Current = _previous[--_count -1]; } - SetConstrutorArgumentState(); + SetConstructorArgumentState(); } // Return a JSONPath using simple dot-notation when possible. When special characters are present, bracket-notation is used: @@ -328,7 +335,7 @@ static void AppendPropertyName(StringBuilder sb, string? propertyName) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void SetConstrutorArgumentState() + private void SetConstructorArgumentState() { if (Current.JsonClassInfo.ParameterCount > 0) { diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStackFrame.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStackFrame.cs index 3331e02990fe0d..5a35fa5a256b7a 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStackFrame.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReadStackFrame.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; +using System.Text.Json.Serialization; namespace System.Text.Json { @@ -43,6 +44,9 @@ internal struct ReadStackFrame public int CtorArgumentStateIndex; public ArgumentState? CtorArgumentState; + // Whether to use custom number handling. + public JsonNumberHandling? NumberHandling; + public void EndConstructorParameter() { CtorArgumentState!.JsonParameterInfo = null; @@ -59,6 +63,7 @@ public void EndProperty() ValidateEndTokenOnArray = false; // No need to clear these since they are overwritten each time: + // NumberHandling // UseExtensionProperty } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStack.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStack.cs index ec90b0c75e0218..e3378711eb1eb1 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStack.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStack.cs @@ -68,12 +68,10 @@ private void AddCurrent() public JsonConverter Initialize(Type type, JsonSerializerOptions options, bool supportContinuation) { JsonClassInfo jsonClassInfo = options.GetOrAddClassForRootType(type); - Current.JsonClassInfo = jsonClassInfo; - if ((jsonClassInfo.ClassType & (ClassType.Enumerable | ClassType.Dictionary)) == 0) - { - Current.DeclaredJsonPropertyInfo = jsonClassInfo.PropertyInfoForClassInfo; - } + Current.JsonClassInfo = jsonClassInfo; + Current.DeclaredJsonPropertyInfo = jsonClassInfo.PropertyInfoForClassInfo; + Current.NumberHandling = Current.DeclaredJsonPropertyInfo.NumberHandling; if (options.ReferenceHandler != null) { @@ -97,12 +95,15 @@ public void Push() else { JsonClassInfo jsonClassInfo = Current.GetPolymorphicJsonPropertyInfo().RuntimeClassInfo; + JsonNumberHandling? numberHandling = Current.NumberHandling; AddCurrent(); Current.Reset(); Current.JsonClassInfo = jsonClassInfo; Current.DeclaredJsonPropertyInfo = jsonClassInfo.PropertyInfoForClassInfo; + // Allow number handling on property to win over handling on type. + Current.NumberHandling = numberHandling ?? Current.DeclaredJsonPropertyInfo.NumberHandling; } } else if (_continuationCount == 1) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStackFrame.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStackFrame.cs index 9689568809b24d..d5a671dd4794f3 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStackFrame.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/WriteStackFrame.cs @@ -68,6 +68,9 @@ internal struct WriteStackFrame /// public JsonPropertyInfo? PolymorphicJsonPropertyInfo; + // Whether to use custom number handling. + public JsonNumberHandling? NumberHandling; + public void EndDictionaryElement() { PropertyState = StackFramePropertyState.None; diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs b/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs index ce4f554a37dc71..b9bd641a9cc22d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs @@ -225,6 +225,28 @@ public static void ThrowInvalidOperationException_IgnoreConditionOnValueTypeInva throw new InvalidOperationException(SR.Format(SR.IgnoreConditionOnValueTypeInvalid, memberInfo.Name, memberInfo.DeclaringType)); } + [DoesNotReturn] + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ThrowInvalidOperationException_NumberHandlingOnPropertyInvalid(JsonPropertyInfo jsonPropertyInfo) + { + MemberInfo? memberInfo = jsonPropertyInfo.MemberInfo; + + if (!jsonPropertyInfo.ConverterBase.IsInternalConverter) + { + throw new InvalidOperationException(SR.Format( + SR.NumberHandlingConverterMustBeBuiltIn, + jsonPropertyInfo.ConverterBase.GetType(), + jsonPropertyInfo.IsForClassInfo ? jsonPropertyInfo.DeclaredPropertyType : memberInfo!.DeclaringType)); + } + + // This exception is only thrown for object properties. + Debug.Assert(!jsonPropertyInfo.IsForClassInfo && memberInfo != null); + throw new InvalidOperationException(SR.Format( + SR.NumberHandlingOnPropertyTypeMustBeNumberOrCollection, + memberInfo.Name, + memberInfo.DeclaringType)); + } + [DoesNotReturn] [MethodImpl(MethodImplOptions.NoInlining)] public static void ThrowNotSupportedException_ObjectWithParameterizedCtorRefMetadataNotHonored( diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs index ca5b059be50bbd..a30af2e6546ad1 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Decimal.cs @@ -93,5 +93,13 @@ private void WriteNumberValueIndented(decimal value) Debug.Assert(result); BytesPending += bytesWritten; } + + internal void WriteNumberValueAsString(decimal value) + { + Span utf8Number = stackalloc byte[JsonConstants.MaximumFormatDecimalLength]; + bool result = Utf8Formatter.TryFormat(value, utf8Number, out int bytesWritten); + Debug.Assert(result); + WriteNumberValueAsStringUnescaped(utf8Number.Slice(0, bytesWritten)); + } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs index cf8732bc44ec8a..f8a46a31468ca9 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Double.cs @@ -143,5 +143,33 @@ private static bool TryFormatDouble(double value, Span destination, out in } #endif } + + internal void WriteNumberValueAsString(double value) + { + Span utf8Number = stackalloc byte[JsonConstants.MaximumFormatDoubleLength]; + bool result = TryFormatDouble(value, utf8Number, out int bytesWritten); + Debug.Assert(result); + WriteNumberValueAsStringUnescaped(utf8Number.Slice(0, bytesWritten)); + } + + internal void WriteFloatingPointConstant(double value) + { + if (double.IsNaN(value)) + { + WriteNumberValueAsStringUnescaped(JsonConstants.NaNValue); + } + else if (double.IsPositiveInfinity(value)) + { + WriteNumberValueAsStringUnescaped(JsonConstants.PositiveInfinityValue); + } + else if (double.IsNegativeInfinity(value)) + { + WriteNumberValueAsStringUnescaped(JsonConstants.NegativeInfinityValue); + } + else + { + WriteNumberValue(value); + } + } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs index f120a09373c479..2f046d872f6972 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.Float.cs @@ -143,5 +143,33 @@ private static bool TryFormatSingle(float value, Span destination, out int } #endif } + + internal void WriteNumberValueAsString(float value) + { + Span utf8Number = stackalloc byte[JsonConstants.MaximumFormatSingleLength]; + bool result = TryFormatSingle(value, utf8Number, out int bytesWritten); + Debug.Assert(result); + WriteNumberValueAsStringUnescaped(utf8Number.Slice(0, bytesWritten)); + } + + internal void WriteFloatingPointConstant(float value) + { + if (float.IsNaN(value)) + { + WriteNumberValueAsStringUnescaped(JsonConstants.NaNValue); + } + else if (float.IsPositiveInfinity(value)) + { + WriteNumberValueAsStringUnescaped(JsonConstants.PositiveInfinityValue); + } + else if (float.IsNegativeInfinity(value)) + { + WriteNumberValueAsStringUnescaped(JsonConstants.NegativeInfinityValue); + } + else + { + WriteNumberValue(value); + } + } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs index 957573ddb7a7f4..2d6120a6a87680 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.SignedNumber.cs @@ -106,5 +106,13 @@ private void WriteNumberValueIndented(long value) Debug.Assert(result); BytesPending += bytesWritten; } + + internal void WriteNumberValueAsString(long value) + { + Span utf8Number = stackalloc byte[JsonConstants.MaximumFormatInt64Length]; + bool result = Utf8Formatter.TryFormat(value, utf8Number, out int bytesWritten); + Debug.Assert(result); + WriteNumberValueAsStringUnescaped(utf8Number.Slice(0, bytesWritten)); + } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs index c86a8af22f1628..15cb0b8d1af5ec 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.String.cs @@ -349,5 +349,19 @@ private void WriteStringEscapeValue(ReadOnlySpan utf8Value, int firstEscap ArrayPool.Shared.Return(valueArray); } } + + /// + /// Writes a number as a JSON string. The string value is not escaped. + /// + /// + internal void WriteNumberValueAsStringUnescaped(ReadOnlySpan utf8Value) + { + // The value has been validated prior to calling this method. + + WriteStringByOptions(utf8Value); + + SetFlagToAddListSeparatorBeforeNextItem(); + _tokenType = JsonTokenType.String; + } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs index 2c15441d432593..d3cf96947db468 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Writer/Utf8JsonWriter.WriteValues.UnsignedNumber.cs @@ -108,5 +108,13 @@ private void WriteNumberValueIndented(ulong value) Debug.Assert(result); BytesPending += bytesWritten; } + + internal void WriteNumberValueAsString(ulong value) + { + Span utf8Number = stackalloc byte[JsonConstants.MaximumFormatUInt64Length]; + bool result = Utf8Formatter.TryFormat(value, utf8Number, out int bytesWritten); + Debug.Assert(result); + WriteNumberValueAsStringUnescaped(utf8Number.Slice(0, bytesWritten)); + } } } diff --git a/src/libraries/System.Text.Json/tests/JsonNumberTestData.cs b/src/libraries/System.Text.Json/tests/JsonNumberTestData.cs index d07064a3e487be..384488485c9806 100644 --- a/src/libraries/System.Text.Json/tests/JsonNumberTestData.cs +++ b/src/libraries/System.Text.Json/tests/JsonNumberTestData.cs @@ -3,8 +3,7 @@ using System.Collections.Generic; using System.Globalization; -using System.IO; -using Newtonsoft.Json; +using System.Linq; namespace System.Text.Json.Tests { @@ -21,6 +20,19 @@ internal class JsonNumberTestData public static List Floats { get; set; } public static List Doubles { get; set; } public static List Decimals { get; set; } + + public static List NullableBytes { get; set; } + public static List NullableSBytes { get; set; } + public static List NullableShorts { get; set; } + public static List NullableInts { get; set; } + public static List NullableLongs { get; set; } + public static List NullableUShorts { get; set; } + public static List NullableUInts { get; set; } + public static List NullableULongs { get; set; } + public static List NullableFloats { get; set; } + public static List NullableDoubles { get; set; } + public static List NullableDecimals { get; set; } + public static byte[] JsonData { get; set; } static JsonNumberTestData() @@ -295,6 +307,19 @@ static JsonNumberTestData() builder.Append("\"intEnd\": 0}"); #endregion + // Make collections of nullable numbers. + NullableBytes = new List(Bytes.Select(num => (byte?)num)); + NullableSBytes = new List(SBytes.Select(num => (sbyte?)num)); + NullableShorts = new List(Shorts.Select(num => (short?)num)); + NullableInts = new List(Ints.Select(num => (int?)num)); + NullableLongs = new List(Longs.Select(num => (long?)num)); + NullableUShorts = new List(UShorts.Select(num => (ushort?)num)); + NullableUInts = new List(UInts.Select(num => (uint?)num)); + NullableULongs = new List(ULongs.Select(num => (ulong?)num)); + NullableFloats = new List(Floats.Select(num => (float?)num)); + NullableDoubles = new List(Doubles.Select(num => (double?)num)); + NullableDecimals = new List(Decimals.Select(num => (decimal?)num)); + string jsonString = builder.ToString(); JsonData = Encoding.UTF8.GetBytes(jsonString); } diff --git a/src/libraries/System.Text.Json/tests/Serialization/NumberHandlingTests.cs b/src/libraries/System.Text.Json/tests/Serialization/NumberHandlingTests.cs new file mode 100644 index 00000000000000..60acb54094d6f9 --- /dev/null +++ b/src/libraries/System.Text.Json/tests/Serialization/NumberHandlingTests.cs @@ -0,0 +1,1414 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Collections.ObjectModel; +using System.Globalization; +using System.Linq; +using System.Text.Encodings.Web; +using System.Text.Json.Tests; +using Xunit; + +namespace System.Text.Json.Serialization.Tests +{ + public static partial class NumberHandlingTests + { + private static readonly JsonSerializerOptions s_optionReadFromStr = new JsonSerializerOptions + { + NumberHandling = JsonNumberHandling.AllowReadingFromString + }; + + private static readonly JsonSerializerOptions s_optionWriteAsStr = new JsonSerializerOptions + { + NumberHandling = JsonNumberHandling.WriteAsString + }; + + private static readonly JsonSerializerOptions s_optionReadAndWriteFromStr = new JsonSerializerOptions + { + NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString + }; + + private static readonly JsonSerializerOptions s_optionsAllowFloatConstants = new JsonSerializerOptions + { + NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals + }; + + private static readonly JsonSerializerOptions s_optionReadFromStrAllowFloatConstants = new JsonSerializerOptions + { + NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.AllowNamedFloatingPointLiterals + }; + + private static readonly JsonSerializerOptions s_optionWriteAsStrAllowFloatConstants = new JsonSerializerOptions + { + NumberHandling = JsonNumberHandling.WriteAsString | JsonNumberHandling.AllowNamedFloatingPointLiterals + }; + + [Fact] + public static void Number_AsRootType_RoundTrip() + { + RunAsRootTypeTest(JsonNumberTestData.Bytes); + RunAsRootTypeTest(JsonNumberTestData.SBytes); + RunAsRootTypeTest(JsonNumberTestData.Shorts); + RunAsRootTypeTest(JsonNumberTestData.Ints); + RunAsRootTypeTest(JsonNumberTestData.Longs); + RunAsRootTypeTest(JsonNumberTestData.UShorts); + RunAsRootTypeTest(JsonNumberTestData.UInts); + RunAsRootTypeTest(JsonNumberTestData.ULongs); + RunAsRootTypeTest(JsonNumberTestData.Floats); + RunAsRootTypeTest(JsonNumberTestData.Doubles); + RunAsRootTypeTest(JsonNumberTestData.Decimals); + RunAsRootTypeTest(JsonNumberTestData.NullableBytes); + RunAsRootTypeTest(JsonNumberTestData.NullableSBytes); + RunAsRootTypeTest(JsonNumberTestData.NullableShorts); + RunAsRootTypeTest(JsonNumberTestData.NullableInts); + RunAsRootTypeTest(JsonNumberTestData.NullableLongs); + RunAsRootTypeTest(JsonNumberTestData.NullableUShorts); + RunAsRootTypeTest(JsonNumberTestData.NullableUInts); + RunAsRootTypeTest(JsonNumberTestData.NullableULongs); + RunAsRootTypeTest(JsonNumberTestData.NullableFloats); + RunAsRootTypeTest(JsonNumberTestData.NullableDoubles); + RunAsRootTypeTest(JsonNumberTestData.NullableDecimals); + } + + private static void RunAsRootTypeTest(List numbers) + { + foreach (T number in numbers) + { + string numberAsString = GetNumberAsString(number); + string json = $"{numberAsString}"; + string jsonWithNumberAsString = @$"""{numberAsString}"""; + PerformAsRootTypeSerialization(number, json, jsonWithNumberAsString); + } + } + + private static string GetNumberAsString(T number) + { + return number switch + { + double @double => @double.ToString(JsonTestHelper.DoubleFormatString, CultureInfo.InvariantCulture), + float @float => @float.ToString(JsonTestHelper.SingleFormatString, CultureInfo.InvariantCulture), + decimal @decimal => @decimal.ToString(CultureInfo.InvariantCulture), + _ => number.ToString() + }; + } + + private static void PerformAsRootTypeSerialization(T number, string jsonWithNumberAsNumber, string jsonWithNumberAsString) + { + // Option: read from string + + // Deserialize + Assert.Equal(number, JsonSerializer.Deserialize(jsonWithNumberAsNumber, s_optionReadFromStr)); + Assert.Equal(number, JsonSerializer.Deserialize(jsonWithNumberAsString, s_optionReadFromStr)); + + // Serialize + Assert.Equal(jsonWithNumberAsNumber, JsonSerializer.Serialize(number, s_optionReadFromStr)); + + // Option: write as string + + // Deserialize + Assert.Equal(number, JsonSerializer.Deserialize(jsonWithNumberAsNumber, s_optionWriteAsStr)); + Assert.Throws(() => JsonSerializer.Deserialize(jsonWithNumberAsString, s_optionWriteAsStr)); + + // Serialize + Assert.Equal(jsonWithNumberAsString, JsonSerializer.Serialize(number, s_optionWriteAsStr)); + + // Option: read and write from/to string + + // Deserialize + Assert.Equal(number, JsonSerializer.Deserialize(jsonWithNumberAsNumber, s_optionReadAndWriteFromStr)); + Assert.Equal(number, JsonSerializer.Deserialize(jsonWithNumberAsString, s_optionReadAndWriteFromStr)); + + // Serialize + Assert.Equal(jsonWithNumberAsString, JsonSerializer.Serialize(number, s_optionReadAndWriteFromStr)); + } + + [Fact] + public static void Number_AsBoxedRootType() + { + string numberAsString = @"""2"""; + + int @int = 2; + float @float = 2; + int? nullableInt = 2; + float? nullableFloat = 2; + + Assert.Equal(numberAsString, JsonSerializer.Serialize((object)@int, s_optionReadAndWriteFromStr)); + Assert.Equal(numberAsString, JsonSerializer.Serialize((object)@float, s_optionReadAndWriteFromStr)); + Assert.Equal(numberAsString, JsonSerializer.Serialize((object)nullableInt, s_optionReadAndWriteFromStr)); + Assert.Equal(numberAsString, JsonSerializer.Serialize((object)nullableFloat, s_optionReadAndWriteFromStr)); + + Assert.Equal(2, (int)JsonSerializer.Deserialize(numberAsString, typeof(int), s_optionReadAndWriteFromStr)); + Assert.Equal(2, (float)JsonSerializer.Deserialize(numberAsString, typeof(float), s_optionReadAndWriteFromStr)); + Assert.Equal(2, (int?)JsonSerializer.Deserialize(numberAsString, typeof(int?), s_optionReadAndWriteFromStr)); + Assert.Equal(2, (float?)JsonSerializer.Deserialize(numberAsString, typeof(float?), s_optionReadAndWriteFromStr)); + } + + [Fact] + public static void Number_AsCollectionElement_RoundTrip() + { + RunAsCollectionElementTest(JsonNumberTestData.Bytes); + RunAsCollectionElementTest(JsonNumberTestData.SBytes); + RunAsCollectionElementTest(JsonNumberTestData.Shorts); + RunAsCollectionElementTest(JsonNumberTestData.Ints); + RunAsCollectionElementTest(JsonNumberTestData.Longs); + RunAsCollectionElementTest(JsonNumberTestData.UShorts); + RunAsCollectionElementTest(JsonNumberTestData.UInts); + RunAsCollectionElementTest(JsonNumberTestData.ULongs); + RunAsCollectionElementTest(JsonNumberTestData.Floats); + RunAsCollectionElementTest(JsonNumberTestData.Doubles); + RunAsCollectionElementTest(JsonNumberTestData.Decimals); + RunAsCollectionElementTest(JsonNumberTestData.NullableBytes); + RunAsCollectionElementTest(JsonNumberTestData.NullableSBytes); + RunAsCollectionElementTest(JsonNumberTestData.NullableShorts); + RunAsCollectionElementTest(JsonNumberTestData.NullableInts); + RunAsCollectionElementTest(JsonNumberTestData.NullableLongs); + RunAsCollectionElementTest(JsonNumberTestData.NullableUShorts); + RunAsCollectionElementTest(JsonNumberTestData.NullableUInts); + RunAsCollectionElementTest(JsonNumberTestData.NullableULongs); + RunAsCollectionElementTest(JsonNumberTestData.NullableFloats); + RunAsCollectionElementTest(JsonNumberTestData.NullableDoubles); + RunAsCollectionElementTest(JsonNumberTestData.NullableDecimals); + } + + private static void RunAsCollectionElementTest(List numbers) + { + StringBuilder jsonBuilder_NumbersAsNumbers = new StringBuilder(); + StringBuilder jsonBuilder_NumbersAsStrings = new StringBuilder(); + StringBuilder jsonBuilder_NumbersAsNumbersAndStrings = new StringBuilder(); + StringBuilder jsonBuilder_NumbersAsNumbersAndStrings_Alternate = new StringBuilder(); + bool asNumber = false; + + jsonBuilder_NumbersAsNumbers.Append("["); + jsonBuilder_NumbersAsStrings.Append("["); + jsonBuilder_NumbersAsNumbersAndStrings.Append("["); + jsonBuilder_NumbersAsNumbersAndStrings_Alternate.Append("["); + + foreach (T number in numbers) + { + string numberAsString = GetNumberAsString(number); + + string jsonWithNumberAsString = @$"""{numberAsString}"""; + + jsonBuilder_NumbersAsNumbers.Append($"{numberAsString},"); + jsonBuilder_NumbersAsStrings.Append($"{jsonWithNumberAsString},"); + jsonBuilder_NumbersAsNumbersAndStrings.Append(asNumber + ? $"{numberAsString}," + : $"{jsonWithNumberAsString},"); + jsonBuilder_NumbersAsNumbersAndStrings_Alternate.Append(!asNumber + ? $"{numberAsString}," + : $"{jsonWithNumberAsString},"); + + asNumber = !asNumber; + } + + jsonBuilder_NumbersAsNumbers.Remove(jsonBuilder_NumbersAsNumbers.Length - 1, 1); + jsonBuilder_NumbersAsStrings.Remove(jsonBuilder_NumbersAsStrings.Length - 1, 1); + jsonBuilder_NumbersAsNumbersAndStrings.Remove(jsonBuilder_NumbersAsNumbersAndStrings.Length - 1, 1); + jsonBuilder_NumbersAsNumbersAndStrings_Alternate.Remove(jsonBuilder_NumbersAsNumbersAndStrings_Alternate.Length - 1, 1); + + jsonBuilder_NumbersAsNumbers.Append("]"); + jsonBuilder_NumbersAsStrings.Append("]"); + jsonBuilder_NumbersAsNumbersAndStrings.Append("]"); + jsonBuilder_NumbersAsNumbersAndStrings_Alternate.Append("]"); + + string jsonNumbersAsStrings = jsonBuilder_NumbersAsStrings.ToString(); + + PerformAsCollectionElementSerialization( + numbers, + jsonBuilder_NumbersAsNumbers.ToString(), + jsonNumbersAsStrings, + jsonBuilder_NumbersAsNumbersAndStrings.ToString(), + jsonBuilder_NumbersAsNumbersAndStrings_Alternate.ToString()); + + // Reflection based tests for every collection type. + RunAllCollectionsRoundTripTest(jsonNumbersAsStrings); + } + + private static void PerformAsCollectionElementSerialization( + List numbers, + string json_NumbersAsNumbers, + string json_NumbersAsStrings, + string json_NumbersAsNumbersAndStrings, + string json_NumbersAsNumbersAndStrings_Alternate) + { + List deserialized; + + // Option: read from string + + // Deserialize + deserialized = JsonSerializer.Deserialize>(json_NumbersAsNumbers, s_optionReadFromStr); + AssertIEnumerableEqual(numbers, deserialized); + + deserialized = JsonSerializer.Deserialize>(json_NumbersAsStrings, s_optionReadFromStr); + AssertIEnumerableEqual(numbers, deserialized); + + deserialized = JsonSerializer.Deserialize>(json_NumbersAsNumbersAndStrings, s_optionReadFromStr); + AssertIEnumerableEqual(numbers, deserialized); + + deserialized = JsonSerializer.Deserialize>(json_NumbersAsNumbersAndStrings_Alternate, s_optionReadFromStr); + AssertIEnumerableEqual(numbers, deserialized); + + // Serialize + Assert.Equal(json_NumbersAsNumbers, JsonSerializer.Serialize(numbers, s_optionReadFromStr)); + + // Option: write as string + + // Deserialize + deserialized = JsonSerializer.Deserialize>(json_NumbersAsNumbers, s_optionWriteAsStr); + AssertIEnumerableEqual(numbers, deserialized); + + Assert.Throws(() => JsonSerializer.Deserialize>(json_NumbersAsStrings, s_optionWriteAsStr)); + + Assert.Throws(() => JsonSerializer.Deserialize>(json_NumbersAsNumbersAndStrings, s_optionWriteAsStr)); + + Assert.Throws(() => JsonSerializer.Deserialize>(json_NumbersAsNumbersAndStrings_Alternate, s_optionWriteAsStr)); + + // Serialize + Assert.Equal(json_NumbersAsStrings, JsonSerializer.Serialize(numbers, s_optionWriteAsStr)); + + // Option: read and write from/to string + + // Deserialize + deserialized = JsonSerializer.Deserialize>(json_NumbersAsNumbers, s_optionReadAndWriteFromStr); + AssertIEnumerableEqual(numbers, deserialized); + + deserialized = JsonSerializer.Deserialize>(json_NumbersAsStrings, s_optionReadAndWriteFromStr); + AssertIEnumerableEqual(numbers, deserialized); + + deserialized = JsonSerializer.Deserialize>(json_NumbersAsNumbersAndStrings, s_optionReadAndWriteFromStr); + AssertIEnumerableEqual(numbers, deserialized); + + deserialized = JsonSerializer.Deserialize>(json_NumbersAsNumbersAndStrings_Alternate, s_optionReadAndWriteFromStr); + AssertIEnumerableEqual(numbers, deserialized); + + // Serialize + Assert.Equal(json_NumbersAsStrings, JsonSerializer.Serialize(numbers, s_optionReadAndWriteFromStr)); + } + + private static void AssertIEnumerableEqual(IEnumerable list1, IEnumerable list2) + { + IEnumerator enumerator1 = list1.GetEnumerator(); + IEnumerator enumerator2 = list2.GetEnumerator(); + + while (enumerator1.MoveNext()) + { + enumerator2.MoveNext(); + Assert.Equal(enumerator1.Current, enumerator2.Current); + } + + Assert.False(enumerator2.MoveNext()); + } + + private static void RunAllCollectionsRoundTripTest(string json) + { + foreach (Type type in CollectionTestTypes.DeserializableGenericEnumerableTypes()) + { + if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(HashSet<>)) + { + HashSet obj1 = (HashSet)JsonSerializer.Deserialize(json, type, s_optionReadAndWriteFromStr); + string serialized = JsonSerializer.Serialize(obj1, s_optionReadAndWriteFromStr); + + HashSet obj2 = (HashSet)JsonSerializer.Deserialize(serialized, type, s_optionReadAndWriteFromStr); + + Assert.Equal(obj1.Count, obj2.Count); + foreach (T element in obj1) + { + Assert.True(obj2.Contains(element)); + } + } + else if (type != typeof(byte[])) + { + object obj = JsonSerializer.Deserialize(json, type, s_optionReadAndWriteFromStr); + string serialized = JsonSerializer.Serialize(obj, s_optionReadAndWriteFromStr); + Assert.Equal(json, serialized); + } + } + + foreach (Type type in CollectionTestTypes.DeserializableNonGenericEnumerableTypes()) + { + // Deserialized as collection of JsonElements. + object obj = JsonSerializer.Deserialize(json, type, s_optionReadAndWriteFromStr); + // Serialized as strings with escaping. + string serialized = JsonSerializer.Serialize(obj, s_optionReadAndWriteFromStr); + + // Ensure escaped values were serialized accurately + List list = JsonSerializer.Deserialize>(serialized, s_optionReadAndWriteFromStr); + serialized = JsonSerializer.Serialize(list, s_optionReadAndWriteFromStr); + Assert.Equal(json, serialized); + + // Serialize instance which is a collection of numbers (not JsonElements). + obj = Activator.CreateInstance(type, new[] { list }); + serialized = JsonSerializer.Serialize(obj, s_optionReadAndWriteFromStr); + Assert.Equal(json, serialized); + } + } + + [Fact] + public static void Number_AsDictionaryElement_RoundTrip() + { + var dict = new Dictionary(); + for (int i = 0; i < 10; i++) + { + dict[JsonNumberTestData.Ints[i]] = JsonNumberTestData.Floats[i]; + } + + // Serialize + string serialized = JsonSerializer.Serialize(dict, s_optionReadAndWriteFromStr); + AssertDictionaryElements_StringValues(serialized); + + // Deserialize + dict = JsonSerializer.Deserialize>(serialized, s_optionReadAndWriteFromStr); + + // Test roundtrip + JsonTestHelper.AssertJsonEqual(serialized, JsonSerializer.Serialize(dict, s_optionReadAndWriteFromStr)); + } + + private static void AssertDictionaryElements_StringValues(string serialized) + { + var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(serialized)); + reader.Read(); + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndObject) + { + break; + } + else if (reader.TokenType == JsonTokenType.String) + { +#if BUILDING_INBOX_LIBRARY + Assert.False(reader.ValueSpan.Contains((byte)'\\')); +#else + foreach (byte val in reader.ValueSpan) + { + if (val == (byte)'\\') + { + Assert.True(false, "Unexpected escape token."); + } + } +#endif + } + else + { + Assert.Equal(JsonTokenType.PropertyName, reader.TokenType); + } + } + } + + [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/39674", typeof(PlatformDetection), nameof(PlatformDetection.IsMonoInterpreter))] + public static void DictionariesRoundTrip() + { + RunAllDictionariessRoundTripTest(JsonNumberTestData.ULongs); + RunAllDictionariessRoundTripTest(JsonNumberTestData.Floats); + RunAllDictionariessRoundTripTest(JsonNumberTestData.Doubles); + } + + private static void RunAllDictionariessRoundTripTest(List numbers) + { + StringBuilder jsonBuilder_NumbersAsStrings = new StringBuilder(); + + jsonBuilder_NumbersAsStrings.Append("{"); + + foreach (T number in numbers) + { + string numberAsString = GetNumberAsString(number); + string jsonWithNumberAsString = @$"""{numberAsString}"""; + + jsonBuilder_NumbersAsStrings.Append($"{jsonWithNumberAsString}:"); + jsonBuilder_NumbersAsStrings.Append($"{jsonWithNumberAsString},"); + } + + jsonBuilder_NumbersAsStrings.Remove(jsonBuilder_NumbersAsStrings.Length - 1, 1); + jsonBuilder_NumbersAsStrings.Append("}"); + + string jsonNumbersAsStrings = jsonBuilder_NumbersAsStrings.ToString(); + + foreach (Type type in CollectionTestTypes.DeserializableDictionaryTypes()) + { + object obj = JsonSerializer.Deserialize(jsonNumbersAsStrings, type, s_optionReadAndWriteFromStr); + JsonTestHelper.AssertJsonEqual(jsonNumbersAsStrings, JsonSerializer.Serialize(obj, s_optionReadAndWriteFromStr)); + } + + foreach (Type type in CollectionTestTypes.DeserializableNonDictionaryTypes()) + { + Dictionary dict = JsonSerializer.Deserialize>(jsonNumbersAsStrings, s_optionReadAndWriteFromStr); + + // Serialize instance which is a dictionary of numbers (not JsonElements). + object obj = Activator.CreateInstance(type, new[] { dict }); + string serialized = JsonSerializer.Serialize(obj, s_optionReadAndWriteFromStr); + JsonTestHelper.AssertJsonEqual(jsonNumbersAsStrings, serialized); + } + } + + [Fact] + public static void Number_AsPropertyValue_RoundTrip() + { + var obj = new Class_With_NullableUInt64_And_Float() + { + NullableUInt64Number = JsonNumberTestData.NullableULongs.LastOrDefault(), + FloatNumbers = JsonNumberTestData.Floats + }; + + // Serialize + string serialized = JsonSerializer.Serialize(obj, s_optionReadAndWriteFromStr); + + // Deserialize + obj = JsonSerializer.Deserialize(serialized, s_optionReadAndWriteFromStr); + + // Test roundtrip + JsonTestHelper.AssertJsonEqual(serialized, JsonSerializer.Serialize(obj, s_optionReadAndWriteFromStr)); + } + + private class Class_With_NullableUInt64_And_Float + { + public ulong? NullableUInt64Number { get; set; } + [JsonInclude] + public List FloatNumbers; + } + + [Fact] + public static void Number_AsKeyValuePairValue_RoundTrip() + { + var obj = new KeyValuePair>(JsonNumberTestData.NullableULongs.LastOrDefault(), JsonNumberTestData.Floats); + + // Serialize + string serialized = JsonSerializer.Serialize(obj, s_optionReadAndWriteFromStr); + + // Deserialize + obj = JsonSerializer.Deserialize>>(serialized, s_optionReadAndWriteFromStr); + + // Test roundtrip + JsonTestHelper.AssertJsonEqual(serialized, JsonSerializer.Serialize(obj, s_optionReadAndWriteFromStr)); + } + + [Fact] + public static void Number_AsObjectWithParameterizedCtor_RoundTrip() + { + var obj = new MyClassWithNumbers(JsonNumberTestData.NullableULongs.LastOrDefault(), JsonNumberTestData.Floats); + + // Serialize + string serialized = JsonSerializer.Serialize(obj, s_optionReadAndWriteFromStr); + + // Deserialize + obj = JsonSerializer.Deserialize(serialized, s_optionReadAndWriteFromStr); + + // Test roundtrip + JsonTestHelper.AssertJsonEqual(serialized, JsonSerializer.Serialize(obj, s_optionReadAndWriteFromStr)); + } + + private class MyClassWithNumbers + { + public ulong? Ulong { get; } + public List ListOfFloats { get; } + + public MyClassWithNumbers(ulong? @ulong, List listOfFloats) + { + Ulong = @ulong; + ListOfFloats = listOfFloats; + } + } + + [Fact] + public static void Number_AsObjectWithParameterizedCtor_PropHasAttribute() + { + string json = @"{""ListOfFloats"":[""1""]}"; + // Strict handling on property overrides loose global policy. + Assert.Throws(() => JsonSerializer.Deserialize(json, s_optionReadFromStr)); + + // Serialize + json = @"{""ListOfFloats"":[1]}"; + MyClassWithNumbers_PropsHasAttribute obj = JsonSerializer.Deserialize(json); + + // Number serialized as JSON number due to strict handling on property which overrides loose global policy. + Assert.Equal(json, JsonSerializer.Serialize(obj, s_optionReadAndWriteFromStr)); + } + + private class MyClassWithNumbers_PropsHasAttribute + { + [JsonNumberHandling(JsonNumberHandling.Strict)] + public List ListOfFloats { get; } + + public MyClassWithNumbers_PropsHasAttribute(List listOfFloats) + { + ListOfFloats = listOfFloats; + } + } + + [Fact] + public static void FloatingPointConstants_Pass() + { + // Valid values + PerformFloatingPointSerialization("NaN"); + PerformFloatingPointSerialization("Infinity"); + PerformFloatingPointSerialization("-Infinity"); + + static void PerformFloatingPointSerialization(string testString) + { + string testStringAsJson = $@"""{testString}"""; + string testJson = @$"{{""FloatNumber"":{testStringAsJson},""DoubleNumber"":{testStringAsJson}}}"; + + StructWithNumbers obj; + switch (testString) + { + case "NaN": + obj = JsonSerializer.Deserialize(testJson, s_optionsAllowFloatConstants); + Assert.Equal(float.NaN, obj.FloatNumber); + Assert.Equal(double.NaN, obj.DoubleNumber); + + obj = JsonSerializer.Deserialize(testJson, s_optionReadFromStr); + Assert.Equal(float.NaN, obj.FloatNumber); + Assert.Equal(double.NaN, obj.DoubleNumber); + break; + case "Infinity": + obj = JsonSerializer.Deserialize(testJson, s_optionsAllowFloatConstants); + Assert.Equal(float.PositiveInfinity, obj.FloatNumber); + Assert.Equal(double.PositiveInfinity, obj.DoubleNumber); + + obj = JsonSerializer.Deserialize(testJson, s_optionReadFromStr); + Assert.Equal(float.PositiveInfinity, obj.FloatNumber); + Assert.Equal(double.PositiveInfinity, obj.DoubleNumber); + break; + case "-Infinity": + obj = JsonSerializer.Deserialize(testJson, s_optionsAllowFloatConstants); + Assert.Equal(float.NegativeInfinity, obj.FloatNumber); + Assert.Equal(double.NegativeInfinity, obj.DoubleNumber); + + obj = JsonSerializer.Deserialize(testJson, s_optionReadFromStr); + Assert.Equal(float.NegativeInfinity, obj.FloatNumber); + Assert.Equal(double.NegativeInfinity, obj.DoubleNumber); + break; + default: + Assert.Throws(() => JsonSerializer.Deserialize(testJson, s_optionsAllowFloatConstants)); + return; + } + + JsonTestHelper.AssertJsonEqual(testJson, JsonSerializer.Serialize(obj, s_optionsAllowFloatConstants)); + JsonTestHelper.AssertJsonEqual(testJson, JsonSerializer.Serialize(obj, s_optionWriteAsStr)); + } + } + + [Theory] + [InlineData("naN")] + [InlineData("Nan")] + [InlineData("NAN")] + [InlineData("+Infinity")] + [InlineData("+infinity")] + [InlineData("infinity")] + [InlineData("infinitY")] + [InlineData("INFINITY")] + [InlineData("+INFINITY")] + [InlineData("-infinity")] + [InlineData("-infinitY")] + [InlineData("-INFINITY")] + [InlineData(" NaN")] + [InlineData(" Infinity")] + [InlineData(" -Infinity")] + [InlineData("NaN ")] + [InlineData("Infinity ")] + [InlineData("-Infinity ")] + [InlineData("a-Infinity")] + [InlineData("NaNa")] + [InlineData("Infinitya")] + [InlineData("-Infinitya")] + public static void FloatingPointConstants_Fail(string testString) + { + string testStringAsJson = $@"""{testString}"""; + string testJson = @$"{{""FloatNumber"":{testStringAsJson},""DoubleNumber"":{testStringAsJson}}}"; + Assert.Throws(() => JsonSerializer.Deserialize(testJson, s_optionsAllowFloatConstants)); + Assert.Throws(() => JsonSerializer.Deserialize(testJson, s_optionReadFromStr)); + } + + [Fact] + public static void AllowFloatingPointConstants_WriteAsNumber_IfNotConstant() + { + float @float = 1; + // Not written as "1" + Assert.Equal("1", JsonSerializer.Serialize(@float, s_optionsAllowFloatConstants)); + + double @double = 1; + // Not written as "1" + Assert.Equal("1", JsonSerializer.Serialize(@double, s_optionsAllowFloatConstants)); + } + + [Theory] + [InlineData("NaN")] + [InlineData("Infinity")] + [InlineData("-Infinity")] + public static void Unquoted_FloatingPointConstants_Read_Fail(string testString) + { + Assert.Throws(() => JsonSerializer.Deserialize(testString, s_optionsAllowFloatConstants)); + Assert.Throws(() => JsonSerializer.Deserialize(testString, s_optionReadFromStr)); + Assert.Throws(() => JsonSerializer.Deserialize(testString, s_optionReadFromStrAllowFloatConstants)); + } + + private struct StructWithNumbers + { + public float FloatNumber { get; set; } + public double DoubleNumber { get; set; } + } + + [Fact] + public static void ReadFromString_AllowFloatingPoint() + { + string json = @"{""IntNumber"":""1"",""FloatNumber"":""NaN""}"; + ClassWithNumbers obj = JsonSerializer.Deserialize(json, s_optionReadFromStrAllowFloatConstants); + + Assert.Equal(1, obj.IntNumber); + Assert.Equal(float.NaN, obj.FloatNumber); + + JsonTestHelper.AssertJsonEqual(@"{""IntNumber"":1,""FloatNumber"":""NaN""}", JsonSerializer.Serialize(obj, s_optionReadFromStrAllowFloatConstants)); + } + + [Fact] + public static void WriteAsString_AllowFloatingPoint() + { + string json = @"{""IntNumber"":""1"",""FloatNumber"":""NaN""}"; + Assert.Throws(() => JsonSerializer.Deserialize(json, s_optionWriteAsStrAllowFloatConstants)); + + var obj = new ClassWithNumbers + { + IntNumber = 1, + FloatNumber = float.NaN + }; + + JsonTestHelper.AssertJsonEqual(json, JsonSerializer.Serialize(obj, s_optionWriteAsStrAllowFloatConstants)); + } + + public class ClassWithNumbers + { + public int IntNumber { get; set; } + public float FloatNumber { get; set; } + } + + [Fact] + public static void FloatingPointConstants_IncompatibleNumber() + { + AssertFloatingPointIncompatible_Fails(); + AssertFloatingPointIncompatible_Fails(); + AssertFloatingPointIncompatible_Fails(); + AssertFloatingPointIncompatible_Fails(); + AssertFloatingPointIncompatible_Fails(); + AssertFloatingPointIncompatible_Fails(); + AssertFloatingPointIncompatible_Fails(); + AssertFloatingPointIncompatible_Fails(); + AssertFloatingPointIncompatible_Fails(); + AssertFloatingPointIncompatible_Fails(); + AssertFloatingPointIncompatible_Fails(); + AssertFloatingPointIncompatible_Fails(); + AssertFloatingPointIncompatible_Fails(); + AssertFloatingPointIncompatible_Fails(); + AssertFloatingPointIncompatible_Fails(); + AssertFloatingPointIncompatible_Fails(); + AssertFloatingPointIncompatible_Fails(); + AssertFloatingPointIncompatible_Fails(); + } + + private static void AssertFloatingPointIncompatible_Fails() + { + string[] testCases = new[] + { + @"""NaN""", + @"""Infinity""", + @"""-Infinity""", + }; + + foreach (string test in testCases) + { + Assert.Throws(() => JsonSerializer.Deserialize(test, s_optionReadFromStrAllowFloatConstants)); + } + } + + [Fact] + public static void UnsupportedFormats() + { + AssertUnsupportedFormatThrows(); + AssertUnsupportedFormatThrows(); + AssertUnsupportedFormatThrows(); + AssertUnsupportedFormatThrows(); + AssertUnsupportedFormatThrows(); + AssertUnsupportedFormatThrows(); + AssertUnsupportedFormatThrows(); + AssertUnsupportedFormatThrows(); + AssertUnsupportedFormatThrows(); + AssertUnsupportedFormatThrows(); + AssertUnsupportedFormatThrows(); + AssertUnsupportedFormatThrows(); + AssertUnsupportedFormatThrows(); + AssertUnsupportedFormatThrows(); + AssertUnsupportedFormatThrows(); + AssertUnsupportedFormatThrows(); + AssertUnsupportedFormatThrows(); + AssertUnsupportedFormatThrows(); + AssertUnsupportedFormatThrows(); + AssertUnsupportedFormatThrows(); + } + + private static void AssertUnsupportedFormatThrows() + { + string[] testCases = new[] + { + "$123.46", // Currency + "100.00 %", // Percent + "1234,57", // Fixed point + "00FF", // Hexadecimal + }; + + foreach (string test in testCases) + { + Assert.Throws(() => JsonSerializer.Deserialize(test, s_optionReadFromStr)); + } + } + + [Fact] + public static void EscapingTest() + { + // Cause all characters to be escaped. + var encoderSettings = new TextEncoderSettings(); + encoderSettings.ForbidCharacters('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '+', '-', 'e', 'E'); + + JavaScriptEncoder encoder = JavaScriptEncoder.Create(encoderSettings); + var options = new JsonSerializerOptions(s_optionReadAndWriteFromStr) + { + Encoder = encoder + }; + + PerformEscapingTest(JsonNumberTestData.Bytes, options); + PerformEscapingTest(JsonNumberTestData.SBytes, options); + PerformEscapingTest(JsonNumberTestData.Shorts, options); + PerformEscapingTest(JsonNumberTestData.Ints, options); + PerformEscapingTest(JsonNumberTestData.Longs, options); + PerformEscapingTest(JsonNumberTestData.UShorts, options); + PerformEscapingTest(JsonNumberTestData.UInts, options); + PerformEscapingTest(JsonNumberTestData.ULongs, options); + PerformEscapingTest(JsonNumberTestData.Floats, options); + PerformEscapingTest(JsonNumberTestData.Doubles, options); + PerformEscapingTest(JsonNumberTestData.Decimals, options); + } + + private static void PerformEscapingTest(List numbers, JsonSerializerOptions options) + { + // All input characters are escaped + IEnumerable numbersAsStrings = numbers.Select(num => GetNumberAsString(num)); + string input = JsonSerializer.Serialize(numbersAsStrings, options); + AssertListNumbersEscaped(input); + + // Unescaping works + List deserialized = JsonSerializer.Deserialize>(input, options); + Assert.Equal(numbers.Count, deserialized.Count); + for (int i = 0; i < numbers.Count; i++) + { + Assert.Equal(numbers[i], deserialized[i]); + } + + // Every number is written as a string, and custom escaping is not honored. + string serialized = JsonSerializer.Serialize(deserialized, options); + AssertListNumbersUnescaped(serialized); + } + + private static void AssertListNumbersEscaped(string json) + { + var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json)); + reader.Read(); + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndArray) + { + break; + } + else + { + Assert.Equal(JsonTokenType.String, reader.TokenType); +#if BUILDING_INBOX_LIBRARY + Assert.True(reader.ValueSpan.Contains((byte)'\\')); +#else + bool foundBackSlash = false; + foreach (byte val in reader.ValueSpan) + { + if (val == (byte)'\\') + { + foundBackSlash = true; + break; + } + } + + Assert.True(foundBackSlash, "Expected escape token."); +#endif + } + } + } + + private static void AssertListNumbersUnescaped(string json) + { + var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json)); + reader.Read(); + while (reader.Read()) + { + if (reader.TokenType == JsonTokenType.EndArray) + { + break; + } + else + { + Assert.Equal(JsonTokenType.String, reader.TokenType); +#if BUILDING_INBOX_LIBRARY + Assert.False(reader.ValueSpan.Contains((byte)'\\')); +#else + foreach (byte val in reader.ValueSpan) + { + if (val == (byte)'\\') + { + Assert.True(false, "Unexpected escape token."); + } + } +#endif + } + } + } + + [Fact] + public static void Number_RoundtripNull() + { + Perform_Number_RoundTripNull_Test(); + Perform_Number_RoundTripNull_Test(); + Perform_Number_RoundTripNull_Test(); + Perform_Number_RoundTripNull_Test(); + Perform_Number_RoundTripNull_Test(); + Perform_Number_RoundTripNull_Test(); + Perform_Number_RoundTripNull_Test(); + Perform_Number_RoundTripNull_Test(); + Perform_Number_RoundTripNull_Test(); + Perform_Number_RoundTripNull_Test(); + } + + private static void Perform_Number_RoundTripNull_Test() + { + string nullAsJson = "null"; + string nullAsQuotedJson = $@"""{nullAsJson}"""; + + Assert.Throws(() => JsonSerializer.Deserialize(nullAsJson, s_optionReadAndWriteFromStr)); + Assert.Equal("0", JsonSerializer.Serialize(default(T))); + Assert.Throws(() => JsonSerializer.Deserialize(nullAsQuotedJson, s_optionReadAndWriteFromStr)); + } + + [Fact] + public static void NullableNumber_RoundtripNull() + { + Perform_NullableNumber_RoundTripNull_Test(); + Perform_NullableNumber_RoundTripNull_Test(); + Perform_NullableNumber_RoundTripNull_Test(); + Perform_NullableNumber_RoundTripNull_Test(); + Perform_NullableNumber_RoundTripNull_Test(); + Perform_NullableNumber_RoundTripNull_Test(); + Perform_NullableNumber_RoundTripNull_Test(); + Perform_NullableNumber_RoundTripNull_Test(); + Perform_NullableNumber_RoundTripNull_Test(); + Perform_NullableNumber_RoundTripNull_Test(); + } + + private static void Perform_NullableNumber_RoundTripNull_Test() + { + string nullAsJson = "null"; + string nullAsQuotedJson = $@"""{nullAsJson}"""; + + Assert.Null(JsonSerializer.Deserialize(nullAsJson, s_optionReadAndWriteFromStr)); + Assert.Equal(nullAsJson, JsonSerializer.Serialize(default(T))); + Assert.Throws(() => JsonSerializer.Deserialize(nullAsQuotedJson, s_optionReadAndWriteFromStr)); + } + + [Fact] + public static void Disallow_ArbritaryStrings_On_AllowFloatingPointConstants() + { + string json = @"""12345"""; + + Assert.Throws(() => JsonSerializer.Deserialize(json, s_optionsAllowFloatConstants)); + Assert.Throws(() => JsonSerializer.Deserialize(json, s_optionsAllowFloatConstants)); + Assert.Throws(() => JsonSerializer.Deserialize(json, s_optionsAllowFloatConstants)); + Assert.Throws(() => JsonSerializer.Deserialize(json, s_optionsAllowFloatConstants)); + Assert.Throws(() => JsonSerializer.Deserialize(json, s_optionsAllowFloatConstants)); + Assert.Throws(() => JsonSerializer.Deserialize(json, s_optionsAllowFloatConstants)); + Assert.Throws(() => JsonSerializer.Deserialize(json, s_optionsAllowFloatConstants)); + Assert.Throws(() => JsonSerializer.Deserialize(json, s_optionsAllowFloatConstants)); + Assert.Throws(() => JsonSerializer.Deserialize(json, s_optionsAllowFloatConstants)); + Assert.Throws(() => JsonSerializer.Deserialize(json, s_optionsAllowFloatConstants)); + Assert.Throws(() => JsonSerializer.Deserialize(json, s_optionsAllowFloatConstants)); + Assert.Throws(() => JsonSerializer.Deserialize(json, s_optionsAllowFloatConstants)); + Assert.Throws(() => JsonSerializer.Deserialize(json, s_optionsAllowFloatConstants)); + Assert.Throws(() => JsonSerializer.Deserialize(json, s_optionsAllowFloatConstants)); + Assert.Throws(() => JsonSerializer.Deserialize(json, s_optionsAllowFloatConstants)); + Assert.Throws(() => JsonSerializer.Deserialize(json, s_optionsAllowFloatConstants)); + Assert.Throws(() => JsonSerializer.Deserialize(json, s_optionsAllowFloatConstants)); + Assert.Throws(() => JsonSerializer.Deserialize(json, s_optionsAllowFloatConstants)); + Assert.Throws(() => JsonSerializer.Deserialize(json, s_optionsAllowFloatConstants)); + Assert.Throws(() => JsonSerializer.Deserialize(json, s_optionsAllowFloatConstants)); + Assert.Throws(() => JsonSerializer.Deserialize(json, s_optionsAllowFloatConstants)); + Assert.Throws(() => JsonSerializer.Deserialize(json, s_optionsAllowFloatConstants)); + } + + [Fact] + public static void Attributes_OnMembers_Work() + { + // Bad JSON because Int should not be string. + string intIsString = @"{""Float"":""1234.5"",""Int"":""12345""}"; + + // Good JSON because Float can be string. + string floatIsString = @"{""Float"":""1234.5"",""Int"":12345}"; + + // Good JSON because Float can be number. + string floatIsNumber = @"{""Float"":1234.5,""Int"":12345}"; + + Assert.Throws(() => JsonSerializer.Deserialize(intIsString)); + + ClassWith_Attribute_OnNumber obj = JsonSerializer.Deserialize(floatIsString); + Assert.Equal(1234.5, obj.Float); + Assert.Equal(12345, obj.Int); + + obj = JsonSerializer.Deserialize(floatIsNumber); + Assert.Equal(1234.5, obj.Float); + Assert.Equal(12345, obj.Int); + + // Per options, float should be written as string. + JsonTestHelper.AssertJsonEqual(floatIsString, JsonSerializer.Serialize(obj)); + } + + private class ClassWith_Attribute_OnNumber + { + [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)] + public float Float { get; set; } + + public int Int { get; set; } + } + + [Fact] + public static void Attribute_OnRootType_Works() + { + // Not allowed + string floatIsString = @"{""Float"":""1234"",""Int"":123}"; + + // Allowed + string floatIsNan = @"{""Float"":""NaN"",""Int"":123}"; + + Assert.Throws(() => JsonSerializer.Deserialize(floatIsString)); + + Type_AllowFloatConstants obj = JsonSerializer.Deserialize(floatIsNan); + Assert.Equal(float.NaN, obj.Float); + Assert.Equal(123, obj.Int); + + JsonTestHelper.AssertJsonEqual(floatIsNan, JsonSerializer.Serialize(obj)); + } + + [JsonNumberHandling(JsonNumberHandling.AllowNamedFloatingPointLiterals)] + private class Type_AllowFloatConstants + { + public float Float { get; set; } + + public int Int { get; set; } + } + + [Fact] + public static void AttributeOnType_WinsOver_GlobalOption() + { + // Global options strict, type options loose + string json = @"{""Float"":""12345""}"; + var obj1 = JsonSerializer.Deserialize(json); + + Assert.Equal(@"{""Float"":""12345""}", JsonSerializer.Serialize(obj1)); + + // Global options loose, type options strict + json = @"{""Float"":""12345""}"; + Assert.Throws(() => JsonSerializer.Deserialize(json, s_optionReadAndWriteFromStr)); + + var obj2 = new ClassWith_StrictAttribute() { Float = 12345 }; + Assert.Equal(@"{""Float"":12345}", JsonSerializer.Serialize(obj2, s_optionReadAndWriteFromStr)); + } + + [JsonNumberHandling(JsonNumberHandling.Strict)] + public class ClassWith_StrictAttribute + { + public float Float { get; set; } + } + + [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)] + private class ClassWith_LooseAttribute + { + public float Float { get; set; } + } + + [Fact] + public static void AttributeOnMember_WinsOver_AttributeOnType() + { + string json = @"{""Double"":""NaN""}"; + Assert.Throws(() => JsonSerializer.Deserialize(json)); + + var obj = new ClassWith_Attribute_On_TypeAndMember { Double = float.NaN }; + Assert.Throws(() => JsonSerializer.Serialize(obj)); + } + + [JsonNumberHandling(JsonNumberHandling.AllowNamedFloatingPointLiterals)] + private class ClassWith_Attribute_On_TypeAndMember + { + [JsonNumberHandling(JsonNumberHandling.Strict)] + public double Double { get; set; } + } + + [Fact] + public static void Attribute_OnNestedType_Works() + { + string jsonWithShortProperty = @"{""Short"":""1""}"; + ClassWith_ReadAsStringAttribute obj = JsonSerializer.Deserialize(jsonWithShortProperty); + Assert.Equal(1, obj.Short); + + string jsonWithMyObjectProperty = @"{""MyObject"":{""Float"":""1""}}"; + Assert.Throws(() => JsonSerializer.Deserialize(jsonWithMyObjectProperty)); + } + + [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)] + public class ClassWith_ReadAsStringAttribute + { + public short Short { get; set; } + + public ClassWith_StrictAttribute MyObject { get; set; } + } + + [Fact] + public static void MemberAttributeAppliesToCollection_SimpleElements() + { + RunTest(); + RunTest>(); + RunTest>(); + RunTest>(); + RunTest>(); + RunTest>(); + RunTest>(); + RunTest>(); + RunTest>(); + RunTest(); + RunTest>(); + + static void RunTest() + { + string json = @"{""MyList"":[""1"",""2""]}"; + ClassWithSimpleCollectionProperty obj = global::System.Text.Json.JsonSerializer.Deserialize>(json); + Assert.Equal(json, global::System.Text.Json.JsonSerializer.Serialize(obj)); + } + } + + public class ClassWithSimpleCollectionProperty + { + [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)] + public T MyList { get; set; } + } + + [Fact] + public static void NestedCollectionElementTypeHandling_Overrides_ParentPropertyHandling() + { + // Strict policy on the collection element type overrides read-as-string on the collection property + string json = @"{""MyList"":[{""Float"":""1""}]}"; + Assert.Throws(() => JsonSerializer.Deserialize(json)); + + // Strict policy on the collection element type overrides write-as-string on the collection property + var obj = new ClassWithComplexListProperty + { + MyList = new List { new ClassWith_StrictAttribute { Float = 1 } } + }; + Assert.Equal(@"{""MyList"":[{""Float"":1}]}", JsonSerializer.Serialize(obj)); + } + + public class ClassWithComplexListProperty + { + [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)] + public List MyList { get; set; } + } + + [Fact] + public static void MemberAttributeAppliesToDictionary_SimpleElements() + { + string json = @"{""First"":""1"",""Second"":""2""}"; + ClassWithSimpleDictionaryProperty obj = JsonSerializer.Deserialize(json); + } + + public class ClassWithSimpleDictionaryProperty + { + [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)] + public Dictionary MyDictionary { get; set; } + } + + [Fact] + public static void NestedDictionaryElementTypeHandling_Overrides_ParentPropertyHandling() + { + // Strict policy on the dictionary element type overrides read-as-string on the collection property. + string json = @"{""MyDictionary"":{""Key"":{""Float"":""1""}}}"; + Assert.Throws(() => JsonSerializer.Deserialize(json)); + + // Strict policy on the collection element type overrides write-as-string on the collection property + var obj = new ClassWithComplexDictionaryProperty + { + MyDictionary = new Dictionary { ["Key"] = new ClassWith_StrictAttribute { Float = 1 } } + }; + Assert.Equal(@"{""MyDictionary"":{""Key"":{""Float"":1}}}", JsonSerializer.Serialize(obj)); + } + + public class ClassWithComplexDictionaryProperty + { + [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)] + public Dictionary MyDictionary { get; set; } + } + + [Fact] + public static void TypeAttributeAppliesTo_CustomCollectionElements() + { + string json = @"[""1""]"; + MyCustomList obj = JsonSerializer.Deserialize(json); + Assert.Equal(json, JsonSerializer.Serialize(obj)); + } + + [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)] + public class MyCustomList : List { } + + [Fact] + public static void TypeAttributeAppliesTo_CustomCollectionElements_HonoredWhenProperty() + { + string json = @"{""List"":[""1""]}"; + ClassWithCustomList obj = JsonSerializer.Deserialize(json); + Assert.Equal(json, JsonSerializer.Serialize(obj)); + } + + public class ClassWithCustomList + { + public MyCustomList List { get; set; } + } + + [Fact] + public static void TypeAttributeAppliesTo_CustomDictionaryElements() + { + string json = @"{""Key"":""1""}"; + MyCustomDictionary obj = JsonSerializer.Deserialize(json); + Assert.Equal(json, JsonSerializer.Serialize(obj)); + } + + [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)] + public class MyCustomDictionary : Dictionary { } + + [Fact] + public static void TypeAttributeAppliesTo_CustomDictionaryElements_HonoredWhenProperty() + { + string json = @"{""Dictionary"":{""Key"":""1""}}"; + ClassWithCustomDictionary obj = JsonSerializer.Deserialize(json); + Assert.Equal(json, JsonSerializer.Serialize(obj)); + } + + public class ClassWithCustomDictionary + { + public MyCustomDictionary Dictionary { get; set; } + } + + [Fact] + public static void Attribute_OnType_NotRecursive() + { + // Recursive behavior would allow a string number. + // This is not supported. + string json = @"{""NestedClass"":{""MyInt"":""1""}}"; + Assert.Throws(() => JsonSerializer.Deserialize(json)); + + var obj = new AttributeOnFirstLevel + { + NestedClass = new BadProperty { MyInt = 1 } + }; + Assert.Equal(@"{""NestedClass"":{""MyInt"":1}}", JsonSerializer.Serialize(obj)); + } + + [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)] + public class AttributeOnFirstLevel + { + public BadProperty NestedClass { get; set; } + } + + public class BadProperty + { + public int MyInt { get; set; } + } + + [Fact] + public static void HandlingOnMemberOverridesHandlingOnType_Enumerable() + { + string json = @"{""List"":[""1""]}"; + Assert.Throws(() => JsonSerializer.Deserialize(json)); + + var obj = new MyCustomListWrapper + { + List = new MyCustomList { 1 } + }; + Assert.Equal(@"{""List"":[1]}", JsonSerializer.Serialize(obj)); + } + + public class MyCustomListWrapper + { + [JsonNumberHandling(JsonNumberHandling.Strict)] + public MyCustomList List { get; set; } + } + + [Fact] + public static void HandlingOnMemberOverridesHandlingOnType_Dictionary() + { + string json = @"{""Dictionary"":{""Key"":""1""}}"; + Assert.Throws(() => JsonSerializer.Deserialize(json)); + + var obj1 = new MyCustomDictionaryWrapper + { + Dictionary = new MyCustomDictionary { ["Key"] = 1 } + }; + Assert.Equal(@"{""Dictionary"":{""Key"":1}}", JsonSerializer.Serialize(obj1)); + } + + public class MyCustomDictionaryWrapper + { + [JsonNumberHandling(JsonNumberHandling.Strict)] + public MyCustomDictionary Dictionary { get; set; } + } + + [Fact] + public static void Attribute_NotAllowed_On_NonNumber_NonCollection_Property() + { + string json = @""; + InvalidOperationException ex = Assert.Throws(() => JsonSerializer.Deserialize(json)); + string exAsStr = ex.ToString(); + Assert.Contains("MyProp", exAsStr); + Assert.Contains(typeof(ClassWith_NumberHandlingOn_ObjectProperty).ToString(), exAsStr); + + ex = Assert.Throws(() => JsonSerializer.Serialize(new ClassWith_NumberHandlingOn_ObjectProperty())); + exAsStr = ex.ToString(); + Assert.Contains("MyProp", exAsStr); + Assert.Contains(typeof(ClassWith_NumberHandlingOn_ObjectProperty).ToString(), exAsStr); + } + + public class ClassWith_NumberHandlingOn_ObjectProperty + { + [JsonNumberHandling(JsonNumberHandling.Strict)] + public BadProperty MyProp { get; set; } + } + + [Fact] + public static void Attribute_NotAllowed_On_Property_WithCustomConverter() + { + string json = @""; + InvalidOperationException ex = Assert.Throws(() => JsonSerializer.Deserialize(json)); + string exAsStr = ex.ToString(); + Assert.Contains(typeof(ConverterForInt32).ToString(), exAsStr); + Assert.Contains(typeof(ClassWith_NumberHandlingOn_Property_WithCustomConverter).ToString(), exAsStr); + + ex = Assert.Throws(() => JsonSerializer.Serialize(new ClassWith_NumberHandlingOn_Property_WithCustomConverter())); + exAsStr = ex.ToString(); + Assert.Contains(typeof(ConverterForInt32).ToString(), exAsStr); + Assert.Contains(typeof(ClassWith_NumberHandlingOn_Property_WithCustomConverter).ToString(), exAsStr); + } + + public class ClassWith_NumberHandlingOn_Property_WithCustomConverter + { + [JsonNumberHandling(JsonNumberHandling.Strict)] + [JsonConverter(typeof(ConverterForInt32))] + public int MyProp { get; set; } + } + + [Fact] + public static void Attribute_NotAllowed_On_Type_WithCustomConverter() + { + string json = @""; + InvalidOperationException ex = Assert.Throws(() => JsonSerializer.Deserialize(json)); + string exAsStr = ex.ToString(); + Assert.Contains(typeof(ConverterForMyType).ToString(), exAsStr); + Assert.Contains(typeof(ClassWith_NumberHandlingOn_Type_WithCustomConverter).ToString(), exAsStr); + + ex = Assert.Throws(() => JsonSerializer.Serialize(new ClassWith_NumberHandlingOn_Type_WithCustomConverter())); + exAsStr = ex.ToString(); + Assert.Contains(typeof(ConverterForMyType).ToString(), exAsStr); + Assert.Contains(typeof(ClassWith_NumberHandlingOn_Type_WithCustomConverter).ToString(), exAsStr); + } + + [JsonNumberHandling(JsonNumberHandling.Strict)] + [JsonConverter(typeof(ConverterForMyType))] + public class ClassWith_NumberHandlingOn_Type_WithCustomConverter + { + } + + private class ConverterForMyType : JsonConverter + { + public override ClassWith_NumberHandlingOn_Type_WithCustomConverter Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + throw new NotImplementedException(); + } + + public override void Write(Utf8JsonWriter writer, ClassWith_NumberHandlingOn_Type_WithCustomConverter value, JsonSerializerOptions options) + { + throw new NotImplementedException(); + } + } + + [Fact] + public static void CustomConverterOverridesBuiltInLogic() + { + var options = new JsonSerializerOptions(s_optionReadAndWriteFromStr) + { + Converters = { new ConverterForInt32(), new ConverterForFloat() } + }; + + string json = @"""32"""; + + // Converter returns 25 regardless of input. + Assert.Equal(25, JsonSerializer.Deserialize(json, options)); + + // Converter throws this exception regardless of input. + Assert.Throws(() => JsonSerializer.Serialize(4, options)); + + json = @"""NaN"""; + + // Converter returns 25 if NaN. + Assert.Equal(25, JsonSerializer.Deserialize(json, options)); + + // Converter writes 25 if NaN. + Assert.Equal("25", JsonSerializer.Serialize((float?)float.NaN, options)); + } + + public class ConverterForFloat : JsonConverter + { + public override float? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.String && reader.GetString() == "NaN") + { + return 25; + } + + throw new NotSupportedException(); + } + + public override void Write(Utf8JsonWriter writer, float? value, JsonSerializerOptions options) + { + if (float.IsNaN(value.Value)) + { + writer.WriteNumberValue(25); + return; + } + + throw new NotSupportedException(); + } + } + + [Fact] + public static void JsonNumberHandling_ArgOutOfRangeFail() + { + // Global options + ArgumentOutOfRangeException ex = Assert.Throws( + () => new JsonSerializerOptions { NumberHandling = (JsonNumberHandling)(-1) }); + Assert.Contains("value", ex.ToString()); + Assert.Throws( + () => new JsonSerializerOptions { NumberHandling = (JsonNumberHandling)(8) }); + + ex = Assert.Throws( + () => new JsonNumberHandlingAttribute((JsonNumberHandling)(-1))); + Assert.Contains("handling", ex.ToString()); + Assert.Throws( + () => new JsonNumberHandlingAttribute((JsonNumberHandling)(8))); + } + } +} diff --git a/src/libraries/System.Text.Json/tests/Serialization/Object.ReadTests.cs b/src/libraries/System.Text.Json/tests/Serialization/Object.ReadTests.cs index 544634359a9683..6a36e96d3818b9 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/Object.ReadTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/Object.ReadTests.cs @@ -278,7 +278,7 @@ private class CollectionWithoutPublicParameterlessCtor : IList internal CollectionWithoutPublicParameterlessCtor() { - Debug.Fail("The JsonSerializer should not be callin non-public ctors, by default."); + Debug.Fail("The JsonSerializer should not be calling non-public ctors, by default."); } public CollectionWithoutPublicParameterlessCtor(List list) @@ -286,7 +286,7 @@ public CollectionWithoutPublicParameterlessCtor(List list) _list = list; } - public object this[int index] { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + public object this[int index] { get => _list[index]; set => _list[index] = value; } public bool IsFixedSize => throw new NotImplementedException(); diff --git a/src/libraries/System.Text.Json/tests/Serialization/OptionsTests.cs b/src/libraries/System.Text.Json/tests/Serialization/OptionsTests.cs index a94055600815c5..a7cc37fb68f1c8 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/OptionsTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/OptionsTests.cs @@ -589,6 +589,7 @@ private static JsonSerializerOptions GetFullyPopulatedOptionsInstance() { options.ReadCommentHandling = JsonCommentHandling.Disallow; options.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault; + options.NumberHandling = JsonNumberHandling.AllowReadingFromString; } else { @@ -636,6 +637,10 @@ private static void VerifyOptionsEqual(JsonSerializerOptions options, JsonSerial { Assert.Equal(options.DefaultIgnoreCondition, newOptions.DefaultIgnoreCondition); } + else if (property.Name == "NumberHandling") + { + Assert.Equal(options.NumberHandling, newOptions.NumberHandling); + } else { Assert.True(false, $"Public option was added to JsonSerializerOptions but not copied in the copy ctor: {property.Name}"); diff --git a/src/libraries/System.Text.Json/tests/Serialization/Stream.Collections.cs b/src/libraries/System.Text.Json/tests/Serialization/Stream.Collections.cs index eb371a431949c9..3efdfde63502bb 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/Stream.Collections.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/Stream.Collections.cs @@ -98,7 +98,7 @@ private static async Task TestDeserialization( // TODO: https://github.com/dotnet/runtime/issues/35611. // Can't control order of dictionary elements when serializing, so reference metadata might not match up. - if(!(DictionaryTypes().Contains(type) && options.ReferenceHandler == ReferenceHandler.Preserve)) + if(!(CollectionTestTypes.DictionaryTypes().Contains(type) && options.ReferenceHandler == ReferenceHandler.Preserve)) { JsonTestHelper.AssertJsonEqual(expectedJson, serialized); } @@ -287,7 +287,7 @@ private static IEnumerable BufferSizes() private static IEnumerable CollectionTypes() { - foreach (Type type in EnumerableTypes()) + foreach (Type type in CollectionTestTypes.EnumerableTypes()) { yield return type; } @@ -301,43 +301,17 @@ private static IEnumerable CollectionTypes() yield return type; } // Dictionary types - foreach (Type type in DictionaryTypes()) + foreach (Type type in CollectionTestTypes.DictionaryTypes()) { yield return type; } } - private static IEnumerable EnumerableTypes() - { - yield return typeof(TElement[]); // ArrayConverter - yield return typeof(ConcurrentQueue); // ConcurrentQueueOfTConverter - yield return typeof(GenericICollectionWrapper); // ICollectionOfTConverter - yield return typeof(WrapperForIEnumerable); // IEnumerableConverter - yield return typeof(WrapperForIReadOnlyCollectionOfT); // IEnumerableOfTConverter - yield return typeof(Queue); // IEnumerableWithAddMethodConverter - yield return typeof(WrapperForIList); // IListConverter - yield return typeof(Collection); // IListOfTConverter - yield return typeof(ImmutableList); // ImmutableEnumerableOfTConverter - yield return typeof(HashSet); // ISetOfTConverter - yield return typeof(List); // ListOfTConverter - yield return typeof(Queue); // QueueOfTConverter - } - private static IEnumerable ObjectNotationTypes() { yield return typeof(KeyValuePair); // KeyValuePairConverter } - private static IEnumerable DictionaryTypes() - { - yield return typeof(Dictionary); // DictionaryOfStringTValueConverter - yield return typeof(Hashtable); // IDictionaryConverter - yield return typeof(ConcurrentDictionary); // IDictionaryOfStringTValueConverter - yield return typeof(GenericIDictionaryWrapper); // IDictionaryOfStringTValueConverter - yield return typeof(ImmutableDictionary); // ImmutableDictionaryOfStringTValueConverter - yield return typeof(GenericIReadOnlyDictionaryWrapper); // IReadOnlyDictionaryOfStringTValueConverter - } - private static HashSet StackTypes() => new HashSet { typeof(ConcurrentStack), // ConcurrentStackOfTConverter @@ -389,7 +363,7 @@ public ImmutableStructWithStrings( [InlineData("]")] public static void DeserializeDictionaryStartsWithInvalidJson(string json) { - foreach (Type type in DictionaryTypes()) + foreach (Type type in CollectionTestTypes.DictionaryTypes()) { Assert.ThrowsAsync(async () => { @@ -404,7 +378,7 @@ public static void DeserializeDictionaryStartsWithInvalidJson(string json) [Fact] public static void SerializeEmptyCollection() { - foreach (Type type in EnumerableTypes()) + foreach (Type type in CollectionTestTypes.EnumerableTypes()) { Assert.Equal("[]", JsonSerializer.Serialize(GetEmptyCollection(type))); } @@ -414,7 +388,7 @@ public static void SerializeEmptyCollection() Assert.Equal("[]", JsonSerializer.Serialize(GetEmptyCollection(type))); } - foreach (Type type in DictionaryTypes()) + foreach (Type type in CollectionTestTypes.DictionaryTypes()) { Assert.Equal("{}", JsonSerializer.Serialize(GetEmptyCollection(type))); } diff --git a/src/libraries/System.Text.Json/tests/Serialization/TestClasses/TestClasses.NonGenericCollections.cs b/src/libraries/System.Text.Json/tests/Serialization/TestClasses/TestClasses.NonGenericCollections.cs index adccf4fc1f4b2a..7ef238b63d453a 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/TestClasses/TestClasses.NonGenericCollections.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/TestClasses/TestClasses.NonGenericCollections.cs @@ -218,6 +218,16 @@ public WrapperForIList(IEnumerable items) _list = new List(items); } + public WrapperForIList(IEnumerable items) + { + _list = new List(); + + foreach (object item in items) + { + _list.Add(item); + } + } + public object this[int index] { get => ((IList)_list)[index]; set => ((IList)_list)[index] = value; } public bool IsFixedSize => ((IList)_list).IsFixedSize; diff --git a/src/libraries/System.Text.Json/tests/Serialization/TestClasses/TestClasses.cs b/src/libraries/System.Text.Json/tests/Serialization/TestClasses/TestClasses.cs index 8496e4b5817e86..34f96f79fc94b0 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/TestClasses/TestClasses.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/TestClasses/TestClasses.cs @@ -2,8 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Immutable; +using System.Collections.ObjectModel; using System.Linq; using Xunit; @@ -1889,4 +1891,68 @@ public override string ConvertName(string name) return string.Concat(name.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())).ToLower(); } } + + public static class CollectionTestTypes + { + public static IEnumerable EnumerableTypes() + { + yield return typeof(TElement[]); // ArrayConverter + yield return typeof(ConcurrentQueue); // ConcurrentQueueOfTConverter + yield return typeof(GenericICollectionWrapper); // ICollectionOfTConverter + yield return typeof(WrapperForIEnumerable); // IEnumerableConverter + yield return typeof(WrapperForIReadOnlyCollectionOfT); // IEnumerableOfTConverter + yield return typeof(Queue); // IEnumerableWithAddMethodConverter + yield return typeof(WrapperForIList); // IListConverter + yield return typeof(Collection); // IListOfTConverter + yield return typeof(ImmutableList); // ImmutableEnumerableOfTConverter + yield return typeof(HashSet); // ISetOfTConverter + yield return typeof(List); // ListOfTConverter + yield return typeof(Queue); // QueueOfTConverter + } + + public static IEnumerable DeserializableGenericEnumerableTypes() + { + yield return typeof(TElement[]); // ArrayConverter + yield return typeof(ConcurrentQueue); // ConcurrentQueueOfTConverter + yield return typeof(GenericICollectionWrapper); // ICollectionOfTConverter + yield return typeof(IEnumerable); // IEnumerableConverter + yield return typeof(Collection); // IListOfTConverter + yield return typeof(ImmutableList); // ImmutableEnumerableOfTConverter + yield return typeof(HashSet); // ISetOfTConverter + yield return typeof(List); // ListOfTConverter + yield return typeof(Queue); // QueueOfTConverter + } + + public static IEnumerable DeserializableNonGenericEnumerableTypes() + { + yield return typeof(Queue); // IEnumerableWithAddMethodConverter + yield return typeof(WrapperForIList); // IListConverter + } + + public static IEnumerable DictionaryTypes() + { + yield return typeof(Dictionary); // DictionaryOfStringTValueConverter + yield return typeof(Hashtable); // IDictionaryConverter + yield return typeof(ConcurrentDictionary); // IDictionaryOfStringTValueConverter + yield return typeof(GenericIDictionaryWrapper); // IDictionaryOfStringTValueConverter + yield return typeof(ImmutableDictionary); // ImmutableDictionaryOfStringTValueConverter + yield return typeof(GenericIReadOnlyDictionaryWrapper); // IReadOnlyDictionaryOfStringTValueConverter + } + + public static IEnumerable DeserializableDictionaryTypes() + { + yield return typeof(Dictionary); // DictionaryOfStringTValueConverter + yield return typeof(Hashtable); // IDictionaryConverter + yield return typeof(ConcurrentDictionary); // IDictionaryOfStringTValueConverter + yield return typeof(GenericIDictionaryWrapper); // IDictionaryOfStringTValueConverter + yield return typeof(ImmutableDictionary); // ImmutableDictionaryOfStringTValueConverter + yield return typeof(IReadOnlyDictionary); // IReadOnlyDictionaryOfStringTValueConverter + } + + public static IEnumerable DeserializableNonDictionaryTypes() + { + yield return typeof(Hashtable); // IDictionaryConverter + yield return typeof(SortedList); // IDictionaryConverter + } + } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests.csproj b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests.csproj index 72f5dbc5097b3f..6edf36ca7a3055 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests.csproj +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests.csproj @@ -1,4 +1,4 @@ - + $(NetCoreAppCurrent);$(NetFrameworkCurrent) true @@ -93,6 +93,7 @@ + From 911cf2ceb6bbba691cb10b420bf960eac8857c01 Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Mon, 20 Jul 2020 21:57:21 -0700 Subject: [PATCH 055/458] Disable getappdomainstaticaddress for JIT stress modes (#39667) Issue: https://github.com/dotnet/runtime/issues/37117 --- src/tests/profiler/unittest/getappdomainstaticaddress.csproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tests/profiler/unittest/getappdomainstaticaddress.csproj b/src/tests/profiler/unittest/getappdomainstaticaddress.csproj index 3a10288c5260a8..6d133900cd801b 100644 --- a/src/tests/profiler/unittest/getappdomainstaticaddress.csproj +++ b/src/tests/profiler/unittest/getappdomainstaticaddress.csproj @@ -6,6 +6,10 @@ true 0 true + + true From f0a41ac8765dd3824ffb64d786a6039742252c8b Mon Sep 17 00:00:00 2001 From: Gleb Balykov Date: Tue, 21 Jul 2020 08:45:28 +0300 Subject: [PATCH 056/458] Do not touch crossgen if crossgen is not requested (#39628) --- src/coreclr/build-test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/build-test.sh b/src/coreclr/build-test.sh index f1a26c565e3b02..b7e446c76ec9de 100755 --- a/src/coreclr/build-test.sh +++ b/src/coreclr/build-test.sh @@ -131,7 +131,6 @@ generate_layout() mkdir -p "$CORE_ROOT" chmod +x "$__BinDir"/corerun - chmod +x "$__CrossgenExe" build_MSBuild_projects "Tests_Overlay_Managed" "${__ProjectDir}/tests/src/runtest.proj" "Creating test overlay" "/t:CreateTestOverlay" @@ -149,6 +148,7 @@ generate_layout() # Precompile framework assemblies with crossgen if required if [[ "$__DoCrossgen" != 0 || "$__DoCrossgen2" != 0 ]]; then + chmod +x "$__CrossgenExe" if [[ "$__SkipCrossgenFramework" == 0 ]]; then precompile_coreroot_fx fi From c2d2397354995aaf3afcaeb8ad210cc0a8b5b004 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Tue, 21 Jul 2020 10:44:44 +0200 Subject: [PATCH 057/458] WASM: Enable System.Reflection.MetadataLoadContext tests (#39651) `Tests run: 559, Errors: 0, Failures: 0, Skipped: 0. Time: 5.4221639s` --- eng/testing/tests.mobile.targets | 5 +++++ .../src/Tests/MetadataLoadContext/PathAssemblyResolver.cs | 6 ++++++ src/libraries/tests.proj | 1 - 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets index 284ae301d88880..70887c7ac77f6f 100644 --- a/eng/testing/tests.mobile.targets +++ b/eng/testing/tests.mobile.targets @@ -147,6 +147,11 @@ + + + + + - From cde939d863276fd8e9edc5739f6402a012c707b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Rylek?= Date: Tue, 21 Jul 2020 12:03:17 +0200 Subject: [PATCH 058/458] Fix TableOutOfRangeException in Crossgen2 (#39653) Fixes: https://github.com/dotnet/runtime/issues/39493 Turns out the compilation failure here wasn't caused by Managed C++, it was due to a simple bug in the field RVA copy loop - reading compressed 16-bit field indices as signed, not unsigned, from the FieldRVA ECMA metadata table. Thanks Tomas --- .../DependencyAnalysis/ReadyToRun/CopiedFieldRvaNode.cs | 2 +- .../DependencyAnalysis/ReadyToRun/CopiedMetadataBlobNode.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedFieldRvaNode.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedFieldRvaNode.cs index 8adc7341210bd5..e8596cf24c894a 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedFieldRvaNode.cs +++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedFieldRvaNode.cs @@ -67,7 +67,7 @@ private unsafe byte[] GetRvaData(int targetPointerSize) int currentFieldRid; if (compressedFieldRef) { - currentFieldRid = metadataBlob.ReadInt16(); + currentFieldRid = metadataBlob.ReadUInt16(); } else { diff --git a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedMetadataBlobNode.cs b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedMetadataBlobNode.cs index 8f0ae4281c31d7..b38dbfba67b59e 100644 --- a/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedMetadataBlobNode.cs +++ b/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedMetadataBlobNode.cs @@ -84,7 +84,7 @@ private void WriteFieldRvas(NodeFactory factory, ref ObjectDataBuilder builder, int fieldToken; if (compressedFieldRef) { - fieldToken = reader.ReadInt16(); + fieldToken = reader.ReadUInt16(); } else { From bf0076c80b9b2f1d2080016c7c7edb66ed61fa73 Mon Sep 17 00:00:00 2001 From: Kenneth Pouncey Date: Tue, 21 Jul 2020 13:30:44 +0200 Subject: [PATCH 059/458] [browser][tests] Activate System.Runtime.Extensions UserName tests (#39692) - Added specific tests for Browser --- .../tests/System/Environment.UserName.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Runtime.Extensions/tests/System/Environment.UserName.cs b/src/libraries/System.Runtime.Extensions/tests/System/Environment.UserName.cs index 947cbef2c789f6..2157f63c0250a0 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/Environment.UserName.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/Environment.UserName.cs @@ -5,7 +5,6 @@ namespace System.Tests { - [ActiveIssue("https://github.com/dotnet/runtime/issues/38164", TestPlatforms.Browser)] public class EnvironmentUserName { [Fact] @@ -36,5 +35,14 @@ public void UserName_MatchesEnvironment_Windows() { Assert.Equal(Environment.GetEnvironmentVariable("USERNAME"), Environment.UserName); } + + [Fact] + [PlatformSpecific(TestPlatforms.Browser)] + public void UserName_MatchesEnvironment_Browser() + { + string name = Environment.UserName; + Assert.False(string.IsNullOrWhiteSpace(name)); + Assert.Equal("Browser", name); + } } } From d129af65b2570d519b12009c54b12255d9fe870d Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Tue, 21 Jul 2020 09:58:36 -0400 Subject: [PATCH 060/458] Add CryptoStream.FlushFinalBlockAsync --- ...System.Security.Cryptography.Primitives.cs | 1 + .../Security/Cryptography/CryptoStream.cs | 26 +++++++++++++---- .../tests/CryptoStream.cs | 28 +++++++++++++++++++ 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/libraries/System.Security.Cryptography.Primitives/ref/System.Security.Cryptography.Primitives.cs b/src/libraries/System.Security.Cryptography.Primitives/ref/System.Security.Cryptography.Primitives.cs index 355c6c239b9319..2add4b9ea90d69 100644 --- a/src/libraries/System.Security.Cryptography.Primitives/ref/System.Security.Cryptography.Primitives.cs +++ b/src/libraries/System.Security.Cryptography.Primitives/ref/System.Security.Cryptography.Primitives.cs @@ -82,6 +82,7 @@ public override void EndWrite(System.IAsyncResult asyncResult) { } public override void Flush() { } public override System.Threading.Tasks.Task FlushAsync(System.Threading.CancellationToken cancellationToken) { throw null; } public void FlushFinalBlock() { } + public System.Threading.Tasks.ValueTask FlushFinalBlockAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; } public override int Read(byte[] buffer, int offset, int count) { throw null; } public override System.Threading.Tasks.Task ReadAsync(byte[] buffer, int offset, int count, System.Threading.CancellationToken cancellationToken) { throw null; } public override int ReadByte() { throw null; } diff --git a/src/libraries/System.Security.Cryptography.Primitives/src/System/Security/Cryptography/CryptoStream.cs b/src/libraries/System.Security.Cryptography.Primitives/src/System/Security/Cryptography/CryptoStream.cs index e414e3c6eb08aa..2e426cc4185381 100644 --- a/src/libraries/System.Security.Cryptography.Primitives/src/System/Security/Cryptography/CryptoStream.cs +++ b/src/libraries/System.Security.Cryptography.Primitives/src/System/Security/Cryptography/CryptoStream.cs @@ -100,9 +100,23 @@ public bool HasFlushedFinalBlock // byte[] ciphertext = ms.ToArray(); // cs.Close(); public void FlushFinalBlock() => - FlushFinalBlockAsync(useAsync: false).AsTask().GetAwaiter().GetResult(); + FlushFinalBlockAsync(useAsync: false, default).AsTask().GetAwaiter().GetResult(); + + /// + /// Asynchronously updates the underlying data source or repository with the + /// current state of the buffer, then clears the buffer. + /// + /// The token to monitor for cancellation requests. The default value is . + /// A task that represents the asynchronous flush operation. + public ValueTask FlushFinalBlockAsync(CancellationToken cancellationToken = default) + { + if (cancellationToken.IsCancellationRequested) + return ValueTask.FromCanceled(cancellationToken); + + return FlushFinalBlockAsync(useAsync: true, cancellationToken); + } - private async ValueTask FlushFinalBlockAsync(bool useAsync) + private async ValueTask FlushFinalBlockAsync(bool useAsync, CancellationToken cancellationToken) { if (_finalBlockTransformed) throw new NotSupportedException(SR.Cryptography_CryptoStream_FlushFinalBlockTwice); @@ -116,7 +130,7 @@ private async ValueTask FlushFinalBlockAsync(bool useAsync) byte[] finalBytes = _transform.TransformFinalBlock(_inputBuffer!, 0, _inputBufferIndex); if (useAsync) { - await _stream.WriteAsync(new ReadOnlyMemory(finalBytes)).ConfigureAwait(false); + await _stream.WriteAsync(new ReadOnlyMemory(finalBytes), cancellationToken).ConfigureAwait(false); } else { @@ -129,14 +143,14 @@ private async ValueTask FlushFinalBlockAsync(bool useAsync) { if (!innerCryptoStream.HasFlushedFinalBlock) { - await innerCryptoStream.FlushFinalBlockAsync(useAsync).ConfigureAwait(false); + await innerCryptoStream.FlushFinalBlockAsync(useAsync, cancellationToken).ConfigureAwait(false); } } else { if (useAsync) { - await _stream.FlushAsync().ConfigureAwait(false); + await _stream.FlushAsync(cancellationToken).ConfigureAwait(false); } else { @@ -691,7 +705,7 @@ private async ValueTask DisposeAsyncCore() { if (!_finalBlockTransformed) { - await FlushFinalBlockAsync(useAsync: true).ConfigureAwait(false); + await FlushFinalBlockAsync(useAsync: true, default).ConfigureAwait(false); } if (!_leaveOpen) diff --git a/src/libraries/System.Security.Cryptography.Primitives/tests/CryptoStream.cs b/src/libraries/System.Security.Cryptography.Primitives/tests/CryptoStream.cs index 1d663a2c4fffdf..6156e9c2ea200b 100644 --- a/src/libraries/System.Security.Cryptography.Primitives/tests/CryptoStream.cs +++ b/src/libraries/System.Security.Cryptography.Primitives/tests/CryptoStream.cs @@ -187,6 +187,34 @@ public static void FlushAsync() } } + [Fact] + public static async Task FlushFinalBlockAsync() + { + ICryptoTransform encryptor = new IdentityTransform(1, 1, true); + using (MemoryStream output = new MemoryStream()) + using (CryptoStream encryptStream = new CryptoStream(output, encryptor, CryptoStreamMode.Write)) + { + await encryptStream.WriteAsync(new byte[] { 1, 2, 3, 4, 5 }, 0, 5); + await encryptStream.FlushFinalBlockAsync(); + Assert.True(encryptStream.HasFlushedFinalBlock); + Assert.Equal(5, output.ToArray().Length); + } + } + + [Fact] + public static async Task FlushFinalBlockAsync_Cancelled() + { + ICryptoTransform encryptor = new IdentityTransform(1, 1, true); + using (MemoryStream output = new MemoryStream()) + using (CryptoStream encryptStream = new CryptoStream(output, encryptor, CryptoStreamMode.Write)) + { + await encryptStream.WriteAsync(new byte[] { 1, 2, 3, 4, 5 }, 0, 5); + ValueTask waitable = encryptStream.FlushFinalBlockAsync(new Threading.CancellationToken(canceled: true)); + Assert.True(waitable.IsCanceled); + Assert.False(encryptStream.HasFlushedFinalBlock); + } + } + [Fact] public static void FlushCalledOnFlushAsync_DeriveClass() { From 632cdcab09fda363e460296a77be0be32096f512 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Tue, 21 Jul 2020 08:59:52 -0500 Subject: [PATCH 061/458] Trim more Http DiagnosticsHandler code (#39525) Since the DiagnosticsHandler still gets instantiated in the HttpClientHandler, none of its overriden methods are getting trimmed. This leads to System.Diagnostics.DiagnosticListener still being preserved in a linked application. The fix is to split DiagnosticsHandler.IsEnabled() into two methods: * IsGloballyEnabled() - checks the AppContext switch, and is replaced by the linker by a feature swtich. * IsEnabled() - which checks IsGloballyEnabled() and if there is an Activity or listener available. This allows all but the IsEnabled and IsGloballyEnabled methods to get trimmed on DiagnosticsHandler. Contributes to #38765 --- docs/workflow/trimming/feature-switches.md | 2 +- .../src/ILLink/ILLink.Substitutions.xml | 2 +- .../src/System/Net/Http/DiagnosticsHandler.cs | 7 ++++++- .../src/System/Net/Http/HttpClientHandler.cs | 11 +++++++---- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/docs/workflow/trimming/feature-switches.md b/docs/workflow/trimming/feature-switches.md index ad911e818d7a53..40d3a2299f474b 100644 --- a/docs/workflow/trimming/feature-switches.md +++ b/docs/workflow/trimming/feature-switches.md @@ -14,7 +14,7 @@ configurations but their defaults might vary as any SDK can set the defaults dif | EventSourceSupport | System.Diagnostics.Tracing.EventSource.IsSupported | Any EventSource related code or logic is trimmed when set to false | | InvariantGlobalization | System.Globalization.Invariant | All globalization specific code and data is trimmed when set to true | | UseSystemResourceKeys | System.Resources.UseSystemResourceKeys | Any localizable resources for system assemblies is trimmed when set to true | -| - | System.Net.Http.EnableActivityPropagation | Any dependency related to diagnostics support for System.Net.Http is trimmed when set to false | +| HttpActivityPropagationSupport | System.Net.Http.EnableActivityPropagation | Any dependency related to diagnostics support for System.Net.Http is trimmed when set to false | Any feature-switch which defines property can be set in csproj file or on the command line as any other MSBuild property. Those without predefined property name diff --git a/src/libraries/System.Net.Http/src/ILLink/ILLink.Substitutions.xml b/src/libraries/System.Net.Http/src/ILLink/ILLink.Substitutions.xml index 5715e75fc8303a..5e70f6fbb5d7d5 100644 --- a/src/libraries/System.Net.Http/src/ILLink/ILLink.Substitutions.xml +++ b/src/libraries/System.Net.Http/src/ILLink/ILLink.Substitutions.xml @@ -1,7 +1,7 @@ - + diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs index f69d5ff2f77789..47f260eec04b03 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/DiagnosticsHandler.cs @@ -27,7 +27,12 @@ internal static bool IsEnabled() { // check if there is a parent Activity (and propagation is not suppressed) // or if someone listens to HttpHandlerDiagnosticListener - return Settings.s_activityPropagationEnabled && (Activity.Current != null || Settings.s_diagnosticListener.IsEnabled()); + return IsGloballyEnabled() && (Activity.Current != null || Settings.s_diagnosticListener.IsEnabled()); + } + + internal static bool IsGloballyEnabled() + { + return Settings.s_activityPropagationEnabled; } // SendAsyncCore returns already completed ValueTask for when async: false is passed. diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs index ec2e729113b18b..996e42ca02c36d 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs @@ -18,7 +18,7 @@ public partial class HttpClientHandler : HttpMessageHandler #else private readonly SocketsHttpHandler _underlyingHandler; #endif - private readonly DiagnosticsHandler _diagnosticsHandler; + private readonly DiagnosticsHandler? _diagnosticsHandler; private ClientCertificateOption _clientCertificateOptions; private volatile bool _disposed; @@ -30,7 +30,10 @@ public HttpClientHandler() #else _underlyingHandler = new SocketsHttpHandler(); #endif - _diagnosticsHandler = new DiagnosticsHandler(_underlyingHandler); + if (DiagnosticsHandler.IsGloballyEnabled()) + { + _diagnosticsHandler = new DiagnosticsHandler(_underlyingHandler); + } ClientCertificateOptions = ClientCertificateOption.Manual; } @@ -273,7 +276,7 @@ public SslProtocols SslProtocols protected internal override HttpResponseMessage Send(HttpRequestMessage request, CancellationToken cancellationToken) { - return DiagnosticsHandler.IsEnabled() ? + return DiagnosticsHandler.IsEnabled() && _diagnosticsHandler != null ? _diagnosticsHandler.Send(request, cancellationToken) : _underlyingHandler.Send(request, cancellationToken); } @@ -281,7 +284,7 @@ protected internal override HttpResponseMessage Send(HttpRequestMessage request, protected internal override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { - return DiagnosticsHandler.IsEnabled() ? + return DiagnosticsHandler.IsEnabled() && _diagnosticsHandler != null ? _diagnosticsHandler.SendAsync(request, cancellationToken) : _underlyingHandler.SendAsync(request, cancellationToken); } From 2b94d13664b44bcba2c762f417996dc65552a604 Mon Sep 17 00:00:00 2001 From: Miha Zupan Date: Tue, 21 Jul 2020 17:52:18 +0200 Subject: [PATCH 062/458] Update license header in NameResolutionTelemetry (#39711) --- .../src/System/Net/NameResolutionTelemetry.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libraries/System.Net.NameResolution/src/System/Net/NameResolutionTelemetry.cs b/src/libraries/System.Net.NameResolution/src/System/Net/NameResolutionTelemetry.cs index c216dcbf96db52..81cc5f62597c39 100644 --- a/src/libraries/System.Net.NameResolution/src/System/Net/NameResolutionTelemetry.cs +++ b/src/libraries/System.Net.NameResolution/src/System/Net/NameResolutionTelemetry.cs @@ -1,6 +1,5 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. using System.Diagnostics; using System.Diagnostics.Tracing; From 3b1b623af32a5bfd52cbcadb5208f3afe8db2ef2 Mon Sep 17 00:00:00 2001 From: Omair Majid Date: Tue, 21 Jul 2020 12:15:15 -0400 Subject: [PATCH 063/458] Fix hosted crossgen2 build on arm64 (#39537) --- src/coreclr/src/tools/aot/crossgen2/crossgen2.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/src/tools/aot/crossgen2/crossgen2.csproj b/src/coreclr/src/tools/aot/crossgen2/crossgen2.csproj index b1e2d5a25130e8..2de5f56821453f 100644 --- a/src/coreclr/src/tools/aot/crossgen2/crossgen2.csproj +++ b/src/coreclr/src/tools/aot/crossgen2/crossgen2.csproj @@ -42,7 +42,7 @@ - x64 + x64 unix win From c5b39f3b9ac806cb1c03e2779ebef58d3880297e Mon Sep 17 00:00:00 2001 From: Matt Mitchell Date: Tue, 21 Jul 2020 09:22:40 -0700 Subject: [PATCH 064/458] Enable builds of internal branches (#39437) --- eng/pipelines/runtime-official.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/eng/pipelines/runtime-official.yml b/eng/pipelines/runtime-official.yml index 3d335e198d7d4f..f063eb3e1c0c8c 100644 --- a/eng/pipelines/runtime-official.yml +++ b/eng/pipelines/runtime-official.yml @@ -4,6 +4,7 @@ trigger: include: - master - release/* + - internal/release/* paths: include: - '*' From 1a6016d94c09cf5f3af3817a376b101ad49e1fcd Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Tue, 21 Jul 2020 11:49:36 -0700 Subject: [PATCH 065/458] Disable crossgen2smoke test for GCStress (#39680) It times out in some modes, especially HeapVerify modes. Issue: https://github.com/dotnet/runtime/issues/33949 --- src/tests/readytorun/crossgen2/crossgen2smoke.csproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tests/readytorun/crossgen2/crossgen2smoke.csproj b/src/tests/readytorun/crossgen2/crossgen2smoke.csproj index d70d8f75c527eb..88a0e7537a895c 100644 --- a/src/tests/readytorun/crossgen2/crossgen2smoke.csproj +++ b/src/tests/readytorun/crossgen2/crossgen2smoke.csproj @@ -5,6 +5,9 @@ true 0 + + true + true From b11aea3217da423ad6ef55f78ae48050b4e2bdd1 Mon Sep 17 00:00:00 2001 From: Layomi Akinrinade Date: Tue, 21 Jul 2020 12:23:03 -0700 Subject: [PATCH 066/458] Clean up code following JSON number handling and field support PRs (#39716) * Clean up code following JSON number handling and field support PRs * Move IsValidNumberHandlingValue to better location --- .../System.Text.Json/src/Resources/Strings.resx | 4 ++-- .../System.Text.Json/src/System.Text.Json.csproj | 1 + .../Text/Json/Reader/Utf8JsonReader.TryGet.cs | 2 +- .../Attributes/JsonConverterAttribute.cs | 2 +- .../Attributes/JsonExtensionDataAttribute.cs | 2 +- .../Attributes/JsonIncludeAttribute.cs | 7 +++++-- .../Attributes/JsonNumberHandlingAttribute.cs | 4 ++-- .../Converters/Collection/IListConverter.cs | 1 - .../Text/Json/Serialization/JsonNumberHandling.cs | 6 +++--- .../Serialization/JsonSerializer.Read.Helpers.cs | 7 ------- .../Text/Json/Serialization/JsonSerializer.cs | 15 +++++++++++++++ .../tests/Serialization/ExtensionDataTests.cs | 2 +- 12 files changed, 32 insertions(+), 21 deletions(-) create mode 100644 src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.cs diff --git a/src/libraries/System.Text.Json/src/Resources/Strings.resx b/src/libraries/System.Text.Json/src/Resources/Strings.resx index d5db3cfc6fb1b0..07655cbccea7a5 100644 --- a/src/libraries/System.Text.Json/src/Resources/Strings.resx +++ b/src/libraries/System.Text.Json/src/Resources/Strings.resx @@ -486,7 +486,7 @@ Members '{0}' and '{1}' on type '{2}' cannot both bind with parameter '{3}' in constructor '{4}' on deserialization. - Each parameter in constructor '{0}' on type '{1}' must bind to an object member on deserialization. Each parameter name must be the camel case equivalent of an object member named with the pascal case naming convention. + Each parameter in constructor '{0}' on type '{1}' must bind to an object property or field on deserialization. Each parameter name must match with a property or field on the object. The match can be case-insensitive. The constructor '{0}' on type '{1}' may not have more than 64 parameters for deserialization. @@ -542,4 +542,4 @@ When 'JsonNumberHandlingAttribute' is placed on a property or field, the property or field must be a number or a collection. See member '{0}' on type '{1}'. - \ No newline at end of file + 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 e787defd06be02..64d2b0562b0e1a 100644 --- a/src/libraries/System.Text.Json/src/System.Text.Json.csproj +++ b/src/libraries/System.Text.Json/src/System.Text.Json.csproj @@ -142,6 +142,7 @@ + diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.TryGet.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.TryGet.cs index d08cbcbc28dd06..b888bf3c10f3e4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.TryGet.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Reader/Utf8JsonReader.TryGet.cs @@ -977,7 +977,7 @@ public bool TryGetSingle(out float value) throw ThrowHelper.GetInvalidOperationException_ExpectedNumber(TokenType); } - ReadOnlySpan span = HasValueSequence ? ValueSequence.ToArray() : ValueSpan;; + ReadOnlySpan span = HasValueSequence ? ValueSequence.ToArray() : ValueSpan; if (Utf8Parser.TryParse(span, out float tmp, out int bytesConsumed, _numberFormat) && span.Length == bytesConsumed) diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Attributes/JsonConverterAttribute.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Attributes/JsonConverterAttribute.cs index e4248e726d5d54..098b1e175e01c4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Attributes/JsonConverterAttribute.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Attributes/JsonConverterAttribute.cs @@ -12,7 +12,7 @@ namespace System.Text.Json.Serialization /// The specified converter type must derive from . /// When placed on a property or field, the specified converter will always be used. /// When placed on a type, the specified converter will be used unless a compatible converter is added to - /// or there is another on a member + /// or there is another on a property or field /// of the same type. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Attributes/JsonExtensionDataAttribute.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Attributes/JsonExtensionDataAttribute.cs index 242d50d11e8284..194143cfaf3237 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Attributes/JsonExtensionDataAttribute.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Attributes/JsonExtensionDataAttribute.cs @@ -16,7 +16,7 @@ namespace System.Text.Json.Serialization /// During serializing, the name of the extension data member is not included in the JSON; /// the data contained within the extension data is serialized as properties of the JSON object. /// - /// If there is more than one extension member on a type, or it the member is not of the correct type, + /// If there is more than one extension member on a type, or the member is not of the correct type, /// an is thrown during the first serialization or deserialization of that type. /// [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Attributes/JsonIncludeAttribute.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Attributes/JsonIncludeAttribute.cs index cf5597a574be99..40a6132a20f08d 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Attributes/JsonIncludeAttribute.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Attributes/JsonIncludeAttribute.cs @@ -4,10 +4,13 @@ namespace System.Text.Json.Serialization { /// - /// Indicates that the member should be included for serialization and deserialization. + /// Indicates that the property or field should be included for serialization and deserialization. /// /// - /// When applied to a property, indicates that non-public getters and setters can be used for serialization and deserialization. + /// When applied to a public property, indicates that non-public getters and setters should be used for serialization and deserialization. + /// + /// Non-public properties and fields are not allowed when serializing and deserializing. If the attribute is used on a non-public property or field, + /// an is thrown during the first serialization or deserialization of the declaring type. /// [AttributeUsage(AttributeTargets.Property | System.AttributeTargets.Field, AllowMultiple = false)] public sealed class JsonIncludeAttribute : JsonAttribute diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Attributes/JsonNumberHandlingAttribute.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Attributes/JsonNumberHandlingAttribute.cs index 581d4aacd766e4..ac7661b1d9eb2b 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Attributes/JsonNumberHandlingAttribute.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Attributes/JsonNumberHandlingAttribute.cs @@ -5,13 +5,13 @@ namespace System.Text.Json.Serialization { /// /// When placed on a type, property, or field, indicates what - /// settings should be used when serializing or deserialing numbers. + /// settings should be used when serializing or deserializing numbers. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] public sealed class JsonNumberHandlingAttribute : JsonAttribute { /// - /// Indicates what settings should be used when serializing or deserialing numbers. + /// Indicates what settings should be used when serializing or deserializing numbers. /// public JsonNumberHandling Handling { get; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IListConverter.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IListConverter.cs index 606ddfa7ca3d78..f4e9f29b86120f 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IListConverter.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Collection/IListConverter.cs @@ -82,7 +82,6 @@ protected override bool OnWriteResume(Utf8JsonWriter writer, TCollection value, } } - return true; } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonNumberHandling.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonNumberHandling.cs index 09be0bfc94c81e..0e791730f84f65 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonNumberHandling.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonNumberHandling.cs @@ -23,9 +23,9 @@ public enum JsonNumberHandling /// WriteAsString = 0x2, /// - /// The "NaN", "Infinity", and "-Infinity" tokens can be read as floating-point constants, - /// and the , , and - /// values will be written as their corresponding JSON string representations. + /// The "NaN", "Infinity", and "-Infinity" tokens can be read as + /// floating-point constants, and the and values for these + /// constants will be written as their corresponding JSON string representations. /// AllowNamedFloatingPointLiterals = 0x4 } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Helpers.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Helpers.cs index 8b01c199e6e470..4e7946872454c4 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Helpers.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Read.Helpers.cs @@ -3,7 +3,6 @@ using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; using System.Text.Json.Serialization; namespace System.Text.Json @@ -36,11 +35,5 @@ private static TValue ReadCore(JsonConverter jsonConverter, ref Utf8Json Debug.Assert(value == null || value is TValue); return (TValue)value!; } - - internal static bool IsValidNumberHandlingValue(JsonNumberHandling handling) - { - int handlingValue = (int)handling; - return handlingValue >= 0 && handlingValue <= 7; - } } } diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.cs new file mode 100644 index 00000000000000..8ddd013597fe12 --- /dev/null +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.cs @@ -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. + +using System.Text.Json.Serialization; + +namespace System.Text.Json +{ + public static partial class JsonSerializer + { + internal static bool IsValidNumberHandlingValue(JsonNumberHandling handling) + { + return JsonHelpers.IsInRangeInclusive((int)handling, 0, 7); + } + } +} diff --git a/src/libraries/System.Text.Json/tests/Serialization/ExtensionDataTests.cs b/src/libraries/System.Text.Json/tests/Serialization/ExtensionDataTests.cs index 8899ef5e9c18b9..a005ec38e6ef04 100644 --- a/src/libraries/System.Text.Json/tests/Serialization/ExtensionDataTests.cs +++ b/src/libraries/System.Text.Json/tests/Serialization/ExtensionDataTests.cs @@ -55,7 +55,7 @@ void Verify() } [Fact] - public static void ExtensioFieldNotUsed() + public static void ExtensionFieldNotUsed() { string json = @"{""MyNestedClass"":" + SimpleTestClass.s_json + "}"; ClassWithExtensionField obj = JsonSerializer.Deserialize(json); From f501577ae06c34f43d1fc8676157a245f72c44c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Tue, 21 Jul 2020 21:25:24 +0200 Subject: [PATCH 067/458] WASM: Enable System.Reflection tests (#39696) Disable tests that won't work on browser. --- eng/testing/tests.mobile.targets | 8 ++++++++ .../tests/PortableExecutable/PEBuilderTests.cs | 3 +++ src/libraries/System.Reflection/tests/AssemblyTests.cs | 7 +++++-- .../System.Reflection/tests/CoreCLR/AssemblyTests.cs | 1 + src/libraries/tests.proj | 3 --- 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/eng/testing/tests.mobile.targets b/eng/testing/tests.mobile.targets index 70887c7ac77f6f..5622b19e249bdc 100644 --- a/eng/testing/tests.mobile.targets +++ b/eng/testing/tests.mobile.targets @@ -147,11 +147,19 @@ + + + + + + + + GetBlobRanges(BlobBuilder builder, IEnumerabl } [Fact] + [PlatformSpecific(~TestPlatforms.Browser)] // System.Security.Cryptography isn't supported on browser public void Checksum() { Assert.True(TestChecksumAndAuthenticodeSignature(new MemoryStream(Misc.Signed), Misc.KeyPair)); @@ -661,6 +663,7 @@ public void Checksum() } [Fact] + [PlatformSpecific(~TestPlatforms.Browser)] // System.Security.Cryptography isn't supported on browser public void ChecksumFXAssemblies() { var paths = new[] diff --git a/src/libraries/System.Reflection/tests/AssemblyTests.cs b/src/libraries/System.Reflection/tests/AssemblyTests.cs index a244bbb4222484..e4033244fd9b90 100644 --- a/src/libraries/System.Reflection/tests/AssemblyTests.cs +++ b/src/libraries/System.Reflection/tests/AssemblyTests.cs @@ -142,6 +142,7 @@ public void ExportedTypes(Type type, bool expected) } [Fact] + [PlatformSpecific(~TestPlatforms.Browser)] // entry assembly won't be xunit.console on browser public void GetEntryAssembly() { Assert.NotNull(Assembly.GetEntryAssembly()); @@ -157,7 +158,8 @@ public void GetFile() AssertExtensions.Throws(null, () => typeof(AssemblyTests).Assembly.GetFile("")); Assert.Null(typeof(AssemblyTests).Assembly.GetFile("NonExistentfile.dll")); Assert.NotNull(typeof(AssemblyTests).Assembly.GetFile("System.Reflection.Tests.dll")); - Assert.Equal(typeof(AssemblyTests).Assembly.GetFile("System.Reflection.Tests.dll").Name, typeof(AssemblyTests).Assembly.Location); + if (PlatformDetection.IsNotBrowser) // see https://github.com/dotnet/runtime/issues/39650 + Assert.Equal(typeof(AssemblyTests).Assembly.GetFile("System.Reflection.Tests.dll").Name, typeof(AssemblyTests).Assembly.Location); } [Fact] @@ -165,7 +167,8 @@ public void GetFiles() { Assert.NotNull(typeof(AssemblyTests).Assembly.GetFiles()); Assert.Equal(1, typeof(AssemblyTests).Assembly.GetFiles().Length); - Assert.Equal(typeof(AssemblyTests).Assembly.GetFiles()[0].Name, typeof(AssemblyTests).Assembly.Location); + if (PlatformDetection.IsNotBrowser) // see https://github.com/dotnet/runtime/issues/39650 + Assert.Equal(typeof(AssemblyTests).Assembly.GetFiles()[0].Name, typeof(AssemblyTests).Assembly.Location); } public static IEnumerable GetHashCode_TestData() diff --git a/src/libraries/System.Reflection/tests/CoreCLR/AssemblyTests.cs b/src/libraries/System.Reflection/tests/CoreCLR/AssemblyTests.cs index d75ba5a0ceb21c..544fc17414aa8d 100644 --- a/src/libraries/System.Reflection/tests/CoreCLR/AssemblyTests.cs +++ b/src/libraries/System.Reflection/tests/CoreCLR/AssemblyTests.cs @@ -11,6 +11,7 @@ namespace System.Reflection.Tests public class AssemblyTests { [Fact] + [ActiveIssue("https://github.com/dotnet/runtime/issues/39650", TestPlatforms.Browser)] public void CurrentLocation_HasLocaton() { string location = GetExecutingAssembly().Location; diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index 4ea05eaec8c961..d069428ca23dfe 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -41,9 +41,6 @@ - - - From 932ea66867a52e8858a9a7fa1f8a1952e228c2e3 Mon Sep 17 00:00:00 2001 From: Maxim Lipnin Date: Tue, 21 Jul 2020 22:30:28 +0300 Subject: [PATCH 068/458] [wasm] Enable System.ComponentModel.TypeConverter test suite (#39710) --- .../ExtendedProtectionPolicyTypeConverterTests.cs | 3 +++ .../tests/XTypeDescriptionProviderTests.cs | 1 + src/libraries/tests.proj | 1 - 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/Security/Authentication/ExtendedProtection/ExtendedProtectionPolicyTypeConverterTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/Security/Authentication/ExtendedProtection/ExtendedProtectionPolicyTypeConverterTests.cs index 55bf14930ffd7c..a09110342ff6d3 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/Security/Authentication/ExtendedProtection/ExtendedProtectionPolicyTypeConverterTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/Security/Authentication/ExtendedProtection/ExtendedProtectionPolicyTypeConverterTests.cs @@ -30,12 +30,14 @@ public void CanConvertTo_PositiveTests() } [Fact] + [PlatformSpecific(~TestPlatforms.Browser)] // System.Net.Security is not supported on this platform. public void ConvertTo_NullTypeTests() { Assert.Throws(() => converter.ConvertTo(null, CultureInfo.InvariantCulture, new ExtendedProtectionPolicy(PolicyEnforcement.Never), null)); } [Fact] + [PlatformSpecific(~TestPlatforms.Browser)] // System.Net.Security is not supported on this platform. public void ConvertTo_PositiveTests() { ExtendedProtectionPolicy policy = new ExtendedProtectionPolicy(PolicyEnforcement.Never); @@ -55,6 +57,7 @@ public void ConvertTo_PositiveTests() } [Theory] + [PlatformSpecific(~TestPlatforms.Browser)] // System.Net.Security is not supported on this platform. [InlineData(typeof(int))] [InlineData(typeof(ExtendedProtectionPolicy))] [InlineData(typeof(bool))] diff --git a/src/libraries/System.ComponentModel.TypeConverter/tests/XTypeDescriptionProviderTests.cs b/src/libraries/System.ComponentModel.TypeConverter/tests/XTypeDescriptionProviderTests.cs index 7dde31b29544f5..2b176d835eca5b 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/tests/XTypeDescriptionProviderTests.cs +++ b/src/libraries/System.ComponentModel.TypeConverter/tests/XTypeDescriptionProviderTests.cs @@ -10,6 +10,7 @@ namespace System.Xml.Linq.Tests { + [ActiveIssue("https://github.com/dotnet/runtime/issues/39709", TestPlatforms.Browser)] public class XTypeDescriptionProviderTests { [Fact] diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index d069428ca23dfe..fdd0e1e851169b 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -22,7 +22,6 @@ - From 7adab7c8114286539eed57781e7057eca13a566a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Rylek?= Date: Tue, 21 Jul 2020 21:35:50 +0200 Subject: [PATCH 069/458] Modify build-test scripts to use response files for Crossgen compilation (#39705) This makes it much easier to rerun Crossgen(2) for a particular framework assembly or for the framework composite build as opposed to having to copy over the lengthy command line. Thanks Tomas --- src/coreclr/build-test.cmd | 35 ++++++++++++++++--------- src/coreclr/build-test.sh | 53 +++++++++++++++++++++++--------------- 2 files changed, 55 insertions(+), 33 deletions(-) diff --git a/src/coreclr/build-test.cmd b/src/coreclr/build-test.cmd index 62fe83149b50e5..d0d1a333196792 100644 --- a/src/coreclr/build-test.cmd +++ b/src/coreclr/build-test.cmd @@ -653,17 +653,14 @@ if defined __CompositeBuildMode ( ) for %%F in ("%CORE_ROOT%\System.*.dll";"%CORE_ROOT%\Microsoft.*.dll";%CORE_ROOT%\netstandard.dll;%CORE_ROOT%\mscorlib.dll) do ( - if not "%%~nxF"=="Microsoft.CodeAnalysis.VisualBasic.dll" ( - if not "%%~nxF"=="Microsoft.CodeAnalysis.CSharp.dll" ( - if not "%%~nxF"=="Microsoft.CodeAnalysis.dll" ( if not "%%~nxF"=="System.Runtime.WindowsRuntime.dll" ( if defined __CompositeBuildMode ( echo %%F>>!__CompositeResponseFile! ) else ( - call :PrecompileAssembly "%%F" %%~nxF __TotalPrecompiled __FailedToPrecompile __FailedAssemblies + call :PrecompileAssembly %%F %%~nxF __TotalPrecompiled __FailedToPrecompile __FailedAssemblies echo Processed: !__TotalPrecompiled!, failed !__FailedToPrecompile! ) - ))))) + )) ) if defined __CompositeBuildMode ( @@ -695,19 +692,33 @@ set AssemblyName=%2 REM Intentionally avoid using the .dll extension to prevent REM subsequent compilations from picking it up as a reference -set __CrossgenOutputFile="%CORE_ROOT%\temp.ni._dll" +set __CrossgenOutputFile=%CORE_ROOT%\temp.ni._dll +set __CrossgenResponseFile="%CORE_ROOT%\%AssemblyName%.rsp set __CrossgenCmd= +del /Q %__CrossgenResponseFile% + if defined __DoCrossgen ( - set __CrossgenCmd=!__CrossgenExe! /Platform_Assemblies_Paths "!CORE_ROOT!" /in !AssemblyPath! /out !__CrossgenOutputFile! - echo !__CrossgenCmd! - !__CrossgenCmd! + set __CrossgenCmd=!__CrossgenExe! @!__CrossgenResponseFile! + echo /Platform_Assemblies_Paths "!CORE_ROOT!">>!__CrossgenResponseFile! + echo /in !AssemblyPath!>>!__CrossgenResponseFile! + echo /out !__CrossgenOutputFile!>>!__CrossgenResponseFile! ) else ( - set __CrossgenCmd=!__Crossgen2Dll! -r:"!CORE_ROOT!\System.*.dll" -r:"!CORE_ROOT!\Microsoft.*.dll" -r:"!CORE_ROOT!\mscorlib.dll" -r:"!CORE_ROOT!\netstandard.dll" -O --inputbubble --out:!__CrossgenOutputFile! !AssemblyPath! --targetarch %__BuildArch% - echo !__CrossgenCmd! - call !__CrossgenCmd! + set __CrossgenCmd=!__Crossgen2Dll! @!__CrossgenResponseFile! + echo -r:!CORE_ROOT!\System.*.dll>>!__CrossgenResponseFile! + echo -r:!CORE_ROOT!\Microsoft.*.dll>>!__CrossgenResponseFile! + echo -r:!CORE_ROOT!\mscorlib.dll>>!__CrossgenResponseFile! + echo -r:!CORE_ROOT!\netstandard.dll>>!__CrossgenResponseFile! + echo -O>>!__CrossgenResponseFile! + echo --inputbubble>>!__CrossgenResponseFile! + echo --out:!__CrossgenOutputFile!>>!__CrossgenResponseFile! + echo !AssemblyPath!>>!__CrossgenResponseFile! + echo --targetarch:!__BuildArch!>>!__CrossgenResponseFile! ) +echo !__CrossgenCmd! +call !__CrossgenCmd! + set /a __exitCode = !errorlevel! set /a "%~3+=1" diff --git a/src/coreclr/build-test.sh b/src/coreclr/build-test.sh index b7e446c76ec9de..b67fbef45f92ad 100755 --- a/src/coreclr/build-test.sh +++ b/src/coreclr/build-test.sh @@ -168,35 +168,30 @@ precompile_coreroot_fx() local outputDir="$overlayDir"/out # Delete previously crossgened assemblies - rm "$overlayDir"/*.ni.dll - - # Collect reference assemblies for Crossgen2 - local crossgen2References="" + rm "$overlayDir"/*.ni.dll 2>/dev/null if [[ "$__DoCrossgen2" != 0 ]]; then compilerName=Crossgen2 mkdir "$outputDir" - - skipCrossGenFiles+=('Microsoft.CodeAnalysis.CSharp.dll') - skipCrossGenFiles+=('Microsoft.CodeAnalysis.dll') - skipCrossGenFiles+=('Microsoft.CodeAnalysis.VisualBasic.dll') - - for reference in "$overlayDir"/*.dll; do - crossgen2References+=" -r:${reference}" - done fi echo "${__MsgPrefix}Running ${compilerName} on framework assemblies in CORE_ROOT: '${CORE_ROOT}'" local totalPrecompiled=0 local failedToPrecompile=0 - local compositeCommandLine="${__DotNetCli}" - compositeCommandLine+=" $__Crossgen2Dll" - compositeCommandLine+=" --composite" - compositeCommandLine+=" -O" - compositeCommandLine+=" --out:$outputDir/framework-r2r.dll" - compositeCommandLine+=" --targetarch ${__BuildArch}" + local compositeOutputFile=$outputDir/framework-r2r.dll + local compositeResponseFile=$compositeOutputFile.rsp + local compositeCommandLine="${__DotNetCli} $__Crossgen2Dll @$compositeResponseFile" + + if [[ "$__CompositeBuildMode" != 0 ]]; then + rm $compositeResponseFile 2>/dev/null + echo --composite>>$compositeResponseFile + echo -O>>$compositeResponseFile + echo --out:$compositeOutputFile>>$compositeResponseFile + echo --targetarch:${__BuildArch}>>$compositeResponseFile + fi + declare -a failedAssemblies filesToPrecompile=$(find -L "$overlayDir" -maxdepth 1 -iname Microsoft.\*.dll -o -iname System.\*.dll -o -iname netstandard.dll -o -iname mscorlib.dll -type f) @@ -207,18 +202,32 @@ precompile_coreroot_fx() fi if [[ "$__CompositeBuildMode" != 0 ]]; then - compositeCommandLine+=" $filename" + echo $filename>>$compositeResponseFile continue fi local commandLine="" + local responseFile="$overlayDir/$(basename $filename).rsp" + + rm $responseFile 2>/dev/null if [[ "$__DoCrossgen" != 0 ]]; then - commandLine="$__CrossgenExe /Platform_Assemblies_Paths $overlayDir $filename" + commandLine="$__CrossgenExe @$responseFile" + echo /Platform_Assemblies_Paths>>$responseFile + echo $overlayDir>>$responseFile + echo $filename>>$responseFile fi if [[ "$__DoCrossgen2" != 0 ]]; then - commandLine="${__DotNetCli} $__Crossgen2Dll $crossgen2References -O --inputbubble --out $outputDir/$(basename $filename) $filename --targetarch ${__BuildArch}" + commandLine="${__DotNetCli} $__Crossgen2Dll @$responseFile" + echo -O>>$responseFile + echo --inputbubble>>$responseFile + echo --out:$outputDir/$(basename $filename)>>$responseFile + echo --targetarch:${__BuildArch}>>$responseFile + echo $filename>>$responseFile + for reference in $overlayDir/*.dll; do + echo -r:$reference>>$responseFile + done fi echo Precompiling "$filename" @@ -245,6 +254,8 @@ precompile_coreroot_fx() if [[ "$__CompositeBuildMode" != 0 ]]; then # Compile the entire framework in composite build mode + echo "Response file: $compositeResponseFile" + cat $compositeResponseFile echo "Compiling composite R2R framework: $compositeCommandLine" $compositeCommandLine local exitCode="$?" From ed6eda5baf6018d083c89f47cc612e652b22f5ce Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Tue, 21 Jul 2020 18:08:40 -0400 Subject: [PATCH 070/458] [runtime] Initialize the class if needed in type_is_blittable (). (#39700) * [runtime] Initialize the class if needed in type_is_blittable (). Fixes https://github.com/dotnet/runtime/issues/39100. * Delete workarounds. --- .../Common/src/Interop/Interop.Calendar.cs | 12 ------------ .../src/System/Globalization/CalendarData.Icu.cs | 14 -------------- src/mono/mono/metadata/marshal.c | 8 ++++++-- 3 files changed, 6 insertions(+), 28 deletions(-) diff --git a/src/libraries/Common/src/Interop/Interop.Calendar.cs b/src/libraries/Common/src/Interop/Interop.Calendar.cs index fda13b9ba607b0..bf71a56cf3f08f 100644 --- a/src/libraries/Common/src/Interop/Interop.Calendar.cs +++ b/src/libraries/Common/src/Interop/Interop.Calendar.cs @@ -15,20 +15,8 @@ internal static partial class Globalization [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_GetCalendarInfo")] internal static extern unsafe ResultCode GetCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType calendarDataType, char* result, int resultCapacity); -#if MONO - // Temp workaround for pinvoke callbacks for Mono - // https://github.com/dotnet/runtime/issues/39100 - - internal unsafe delegate void EnumCalendarInfoCallback( - char* calendarString, - IntPtr context); - - [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_EnumCalendarInfo")] - internal static extern bool EnumCalendarInfo(IntPtr callback, string localeName, CalendarId calendarId, CalendarDataType calendarDataType, IntPtr context); -#else [DllImport(Libraries.GlobalizationNative, CharSet = CharSet.Unicode, EntryPoint = "GlobalizationNative_EnumCalendarInfo")] internal static extern unsafe bool EnumCalendarInfo(delegate* callback, string localeName, CalendarId calendarId, CalendarDataType calendarDataType, IntPtr context); -#endif [DllImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_GetLatestJapaneseEra")] internal static extern int GetLatestJapaneseEra(); diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs index df3a17e6a18aa3..af5db2379c4dbc 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/CalendarData.Icu.cs @@ -423,26 +423,12 @@ internal static bool EnumCalendarInfo(string localeName, CalendarId calendarId, return result; } -#if MONO - private static unsafe bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, ref IcuEnumCalendarsData callbackContext) - { - // Temp workaround for pinvoke callbacks for Mono - // https://github.com/dotnet/runtime/issues/39100 - var calendarInfoCallback = new Interop.Globalization.EnumCalendarInfoCallback(EnumCalendarInfoCallback); - return Interop.Globalization.EnumCalendarInfo( - System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate(calendarInfoCallback), - localeName, calendarId, dataType, (IntPtr)Unsafe.AsPointer(ref callbackContext)); - } - - [Mono.MonoPInvokeCallback(typeof(Interop.Globalization.EnumCalendarInfoCallback))] -#else private static unsafe bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, ref IcuEnumCalendarsData callbackContext) { return Interop.Globalization.EnumCalendarInfo(&EnumCalendarInfoCallback, localeName, calendarId, dataType, (IntPtr)Unsafe.AsPointer(ref callbackContext)); } [UnmanagedCallersOnly] -#endif private static unsafe void EnumCalendarInfoCallback(char* calendarStringPtr, IntPtr context) { try diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index fe74f17444e9c3..91358142a40b17 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -3979,9 +3979,13 @@ type_is_blittable (MonoType *type) case MONO_TYPE_U: case MONO_TYPE_PTR: case MONO_TYPE_FNPTR: + case MONO_TYPE_VOID: return TRUE; - default: - return m_class_is_blittable (mono_class_from_mono_type_internal (type)); + default: { + MonoClass *klass = mono_class_from_mono_type_internal (type); + mono_class_init_sizes (klass); + return m_class_is_blittable (klass); + } } } From 69ef55ed6694addb012e6bc7c2712fa8ed3f883e Mon Sep 17 00:00:00 2001 From: Santiago Fernandez Madero Date: Tue, 21 Jul 2020 15:41:58 -0700 Subject: [PATCH 071/458] Fix libraries outerloop builds (#39735) * Fix libraries outerloop builds * Remove liveRuntimeBuildConfig from all configurations build to not make it wait for coreclr to run --- eng/pipelines/libraries/base-job.yml | 13 +++++++++++++ eng/pipelines/libraries/build-job.yml | 6 ++++++ eng/pipelines/libraries/run-test-job.yml | 13 +------------ eng/pipelines/runtime.yml | 1 - 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/eng/pipelines/libraries/base-job.yml b/eng/pipelines/libraries/base-job.yml index 99e62714189943..bf5a9a2321fd46 100644 --- a/eng/pipelines/libraries/base-job.yml +++ b/eng/pipelines/libraries/base-job.yml @@ -20,6 +20,7 @@ parameters: testDisplayName: '' testScope: '' pool: '' + runTests: false jobs: - template: /eng/common/templates/job/job.yml @@ -91,6 +92,9 @@ jobs: - ${{ if ne(parameters.liveRuntimeBuildConfig, '') }}: - _runtimeDownloadPath: '$(Build.SourcesDirectory)/artifacts/transport/${{ parameters.runtimeFlavor }}' - _runtimeConfigurationArg: -rc ${{ parameters.liveRuntimeBuildConfig }} + - ${{ if eq(parameters.runTests, true) }}: + - _runtimeArtifactName: '$(runtimeFlavorName)Product_${{ parameters.runtimeVariant}}_${{ parameters.osGroup }}${{ parameters.osSubgroup }}_${{ parameters.archType }}_${{ parameters.liveRuntimeBuildConfig }}' + - _runtimeArtifactsPathArg: ' /p:RuntimeArtifactsPath=$(_runtimeDownloadPath)' - ${{ if eq(parameters.testDisplayName, '') }}: - _testRunNamePrefixSuffix: $(runtimeFlavorName)_${{ parameters.liveRuntimeBuildConfig }} - ${{ if ne(parameters.testDisplayName, '') }}: @@ -121,4 +125,13 @@ jobs: steps: - template: /eng/pipelines/common/clone-checkout-bundle-step.yml + + - ${{ if and(ne(parameters.liveRuntimeBuildConfig, ''), eq(parameters.runTests, true)) }}: + - template: /eng/pipelines/common/download-artifact-step.yml + parameters: + unpackFolder: $(_runtimeDownloadPath) + artifactFileName: '$(_runtimeArtifactName)$(archiveExtension)' + artifactName: '$(_runtimeArtifactName)' + displayName: '$(runtimeFlavorName) build drop' + - ${{ parameters.steps }} diff --git a/eng/pipelines/libraries/build-job.yml b/eng/pipelines/libraries/build-job.yml index f2e8ff21683c4c..51dcb37ff23fac 100644 --- a/eng/pipelines/libraries/build-job.yml +++ b/eng/pipelines/libraries/build-job.yml @@ -41,6 +41,7 @@ jobs: isOfficialAllConfigurations: ${{ parameters.isOfficialAllConfigurations }} liveRuntimeBuildConfig: ${{ parameters.liveRuntimeBuildConfig }} runtimeFlavor: ${{ parameters.runtimeFlavor }} + runTests: ${{ parameters.runTests }} timeoutInMinutes: ${{ parameters.timeoutInMinutes }} preBuildSteps: ${{ parameters.preBuildSteps }} container: ${{ parameters.container }} @@ -51,6 +52,11 @@ jobs: name: build displayName: 'Build' + ${{ if and(ne(parameters.liveRuntimeBuildConfig, ''), eq(parameters.runTests, true)) }}: + dependsOn: + # Use full product dependency for test runs + - ${{ format('{0}_{1}_product_build_{2}{3}_{4}_{5}', parameters.runtimeFlavor, parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveRuntimeBuildConfig) }} + variables: - librariesTestsArtifactName: ${{ format('libraries_test_assets_{0}_{1}_{2}', parameters.osGroup, parameters.archType, parameters.buildConfig) }} - _subset: libs diff --git a/eng/pipelines/libraries/run-test-job.yml b/eng/pipelines/libraries/run-test-job.yml index cf6324e790685e..74bc7da3d73e37 100644 --- a/eng/pipelines/libraries/run-test-job.yml +++ b/eng/pipelines/libraries/run-test-job.yml @@ -40,6 +40,7 @@ jobs: condition: ${{ parameters.condition }} pool: ${{ parameters.pool }} testScope: ${{ parameters.testScope }} + runTests: true ${{ if ne(parameters.liveRuntimeBuildConfig, '') }}: displayName: ${{ format('Test Run {0} {1}', parameters.liveRuntimeBuildConfig, parameters.runtimeDisplayName) }} name: ${{ format('test_run_{0}_{1}', parameters.liveRuntimeBuildConfig, parameters.runtimeDisplayName) }} @@ -61,10 +62,6 @@ jobs: variables: - librariesTestsArtifactName: ${{ format('libraries_test_assets_{0}_{1}_{2}', parameters.osGroup, parameters.dependsOnTestArchitecture, parameters.dependsOnTestBuildConfiguration) }} - _archiveTestsParameter: /p:ArchiveTests=true - - - ${{ if ne(parameters.liveRuntimeBuildConfig, '') }}: - - _runtimeArtifactName: '$(runtimeFlavorName)Product_${{ parameters.runtimeVariant}}_${{ parameters.osGroup }}${{ parameters.osSubgroup }}_${{ parameters.archType }}_${{ parameters.liveRuntimeBuildConfig }}' - - _runtimeArtifactsPathArg: ' /p:RuntimeArtifactsPath=$(_runtimeDownloadPath)' - ${{ parameters.variables }} @@ -84,14 +81,6 @@ jobs: artifactName: $(librariesTestsArtifactName) artifactFileName: $(librariesTestsArtifactName)$(archiveExtension) unpackFolder: $(Build.SourcesDirectory)/artifacts - - - ${{ if ne(parameters.liveRuntimeBuildConfig, '') }}: - - template: /eng/pipelines/common/download-artifact-step.yml - parameters: - unpackFolder: $(_runtimeDownloadPath) - artifactFileName: '$(_runtimeArtifactName)$(archiveExtension)' - artifactName: '$(_runtimeArtifactName)' - displayName: '$(runtimeFlavorName) build drop' - ${{ if in(parameters.coreclrTestGroup, 'gcstress0x3-gcstress0xc', 'gcstress-extra') }}: # We need to find and download the GC stress dependencies (namely, coredistools). Put them diff --git a/eng/pipelines/runtime.yml b/eng/pipelines/runtime.yml index 6d70e6cd190dbc..e52318b380810b 100644 --- a/eng/pipelines/runtime.yml +++ b/eng/pipelines/runtime.yml @@ -595,7 +595,6 @@ jobs: isFullMatrix: ${{ variables.isFullMatrix }} framework: allConfigurations runTests: true - liveRuntimeBuildConfig: release condition: >- or( eq(dependencies.checkout.outputs['SetPathVars_libraries.containsChange'], true), From e87fbd1030b472b4bc44c375434da65611aa4df0 Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Tue, 21 Jul 2020 16:14:07 -0700 Subject: [PATCH 072/458] Add Overloads for Add(Json/Systemd/Simple)Console (#39725) --- .../Microsoft.Extensions.Logging.Console.cs | 3 + ...tensions.cs => ConsoleLoggerExtensions.cs} | 26 ++++++- .../tests/ConsoleLoggerExtensionsTests.cs | 68 ++++++++++++++++++- 3 files changed, 93 insertions(+), 4 deletions(-) rename src/libraries/Microsoft.Extensions.Logging.Console/src/{ConsoleLoggerFactoryExtensions.cs => ConsoleLoggerExtensions.cs} (84%) diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs index 13f7dfa6c3bdbc..c7ed2ea8cd4f04 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/ref/Microsoft.Extensions.Logging.Console.cs @@ -12,8 +12,11 @@ public static partial class ConsoleLoggerExtensions public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsoleFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder) where TFormatter : Microsoft.Extensions.Logging.Console.ConsoleFormatter where TOptions : Microsoft.Extensions.Logging.Console.ConsoleFormatterOptions { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddConsoleFormatter(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) where TFormatter : Microsoft.Extensions.Logging.Console.ConsoleFormatter where TOptions : Microsoft.Extensions.Logging.Console.ConsoleFormatterOptions { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder AddJsonConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddJsonConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder AddSimpleConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddSimpleConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } + public static Microsoft.Extensions.Logging.ILoggingBuilder AddSystemdConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder) { throw null; } public static Microsoft.Extensions.Logging.ILoggingBuilder AddSystemdConsole(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action configure) { throw null; } } } diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerExtensions.cs similarity index 84% rename from src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs rename to src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerExtensions.cs index 9dbea88f9b253d..2e591ec819fcec 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerFactoryExtensions.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/src/ConsoleLoggerExtensions.cs @@ -49,6 +49,13 @@ public static ILoggingBuilder AddConsole(this ILoggingBuilder builder, Action + /// Add the default console log formatter named 'simple' to the factory with default properties. + /// + /// The to use. + public static ILoggingBuilder AddSimpleConsole(this ILoggingBuilder builder) => + builder.AddFormatterWithName(ConsoleFormatterNames.Simple); + /// /// Add and configure a console log formatter named 'simple' to the factory. /// @@ -59,6 +66,13 @@ public static ILoggingBuilder AddSimpleConsole(this ILoggingBuilder builder, Act return builder.AddConsoleWithFormatter(ConsoleFormatterNames.Simple, configure); } + /// + /// Add a console log formatter named 'json' to the factory with default properties. + /// + /// The to use. + public static ILoggingBuilder AddJsonConsole(this ILoggingBuilder builder) => + builder.AddFormatterWithName(ConsoleFormatterNames.Json); + /// /// Add and configure a console log formatter named 'json' to the factory. /// @@ -79,6 +93,13 @@ public static ILoggingBuilder AddSystemdConsole(this ILoggingBuilder builder, Ac return builder.AddConsoleWithFormatter(ConsoleFormatterNames.Systemd, configure); } + /// + /// Add a console log formatter named 'systemd' to the factory with default properties. + /// + /// The to use. + public static ILoggingBuilder AddSystemdConsole(this ILoggingBuilder builder) => + builder.AddFormatterWithName(ConsoleFormatterNames.Systemd); + internal static ILoggingBuilder AddConsoleWithFormatter(this ILoggingBuilder builder, string name, Action configure) where TOptions : ConsoleFormatterOptions { @@ -86,12 +107,15 @@ internal static ILoggingBuilder AddConsoleWithFormatter(this ILoggingB { throw new ArgumentNullException(nameof(configure)); } - builder.AddConsole((ConsoleLoggerOptions options) => options.FormatterName = name); + builder.AddFormatterWithName(name); builder.Services.Configure(configure); return builder; } + private static ILoggingBuilder AddFormatterWithName(this ILoggingBuilder builder, string name) => + builder.AddConsole((ConsoleLoggerOptions options) => options.FormatterName = name); + /// /// Adds a custom console logger formatter 'TFormatter' to be configured with options 'TOptions'. /// diff --git a/src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleLoggerExtensionsTests.cs b/src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleLoggerExtensionsTests.cs index 85a643012c8298..09388a106b5bdd 100644 --- a/src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleLoggerExtensionsTests.cs +++ b/src/libraries/Microsoft.Extensions.Logging.Console/tests/ConsoleLoggerExtensionsTests.cs @@ -170,7 +170,7 @@ public void AddSimpleConsole_ChangeProperties_IsReadFromLoggingConfiguration() var loggerProvider = new ServiceCollection() .AddLogging(builder => builder .AddConfiguration(configuration) - .AddSimpleConsole(o => {}) + .AddSimpleConsole() ) .BuildServiceProvider() .GetRequiredService(); @@ -186,6 +186,37 @@ public void AddSimpleConsole_ChangeProperties_IsReadFromLoggingConfiguration() Assert.True(formatter.FormatterOptions.IncludeScopes); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/38337", TestPlatforms.Browser)] + public void AddSimpleConsole_OutsideConfig_TakesProperty() + { + var configuration = new ConfigurationBuilder().AddInMemoryCollection(new[] { + new KeyValuePair("Console:FormatterOptions:TimestampFormat", "HH:mm "), + new KeyValuePair("Console:FormatterOptions:UseUtcTimestamp", "true"), + new KeyValuePair("Console:FormatterOptions:IncludeScopes", "false"), + }).Build(); + + var loggerProvider = new ServiceCollection() + .AddLogging(builder => builder + .AddConfiguration(configuration) + .AddSimpleConsole(o => { + o.TimestampFormat = "HH:mm:ss "; + o.IncludeScopes = false; + o.UseUtcTimestamp = true; + }) + ) + .BuildServiceProvider() + .GetRequiredService(); + + var consoleLoggerProvider = Assert.IsType(loggerProvider); + var logger = (ConsoleLogger)consoleLoggerProvider.CreateLogger("Category"); + Assert.Equal(ConsoleFormatterNames.Simple, logger.Options.FormatterName); + var formatter = Assert.IsType(logger.Formatter); + Assert.Equal("HH:mm:ss ", formatter.FormatterOptions.TimestampFormat); + Assert.False(formatter.FormatterOptions.IncludeScopes); + Assert.True(formatter.FormatterOptions.UseUtcTimestamp); + } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [ActiveIssue("https://github.com/dotnet/runtime/issues/38337", TestPlatforms.Browser)] public void AddSystemdConsole_ChangeProperties_IsReadFromLoggingConfiguration() @@ -199,7 +230,7 @@ public void AddSystemdConsole_ChangeProperties_IsReadFromLoggingConfiguration() var loggerProvider = new ServiceCollection() .AddLogging(builder => builder .AddConfiguration(configuration) - .AddSystemdConsole(o => {}) + .AddSystemdConsole() ) .BuildServiceProvider() .GetRequiredService(); @@ -213,6 +244,37 @@ public void AddSystemdConsole_ChangeProperties_IsReadFromLoggingConfiguration() Assert.True(formatter.FormatterOptions.IncludeScopes); } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/38337", TestPlatforms.Browser)] + public void AddSystemdConsole_OutsideConfig_TakesProperty() + { + var configuration = new ConfigurationBuilder().AddInMemoryCollection(new[] { + new KeyValuePair("Console:FormatterOptions:TimestampFormat", "HH:mm "), + new KeyValuePair("Console:FormatterOptions:UseUtcTimestamp", "true"), + new KeyValuePair("Console:FormatterOptions:IncludeScopes", "true"), + }).Build(); + + var loggerProvider = new ServiceCollection() + .AddLogging(builder => builder + .AddConfiguration(configuration) + .AddSystemdConsole(o => { + o.TimestampFormat = "HH:mm:ss "; + o.IncludeScopes = false; + o.UseUtcTimestamp = false; + }) + ) + .BuildServiceProvider() + .GetRequiredService(); + + var consoleLoggerProvider = Assert.IsType(loggerProvider); + var logger = (ConsoleLogger)consoleLoggerProvider.CreateLogger("Category"); + Assert.Equal(ConsoleFormatterNames.Systemd, logger.Options.FormatterName); + var formatter = Assert.IsType(logger.Formatter); + Assert.Equal("HH:mm:ss ", formatter.FormatterOptions.TimestampFormat); + Assert.False(formatter.FormatterOptions.UseUtcTimestamp); + Assert.False(formatter.FormatterOptions.IncludeScopes); + } + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [ActiveIssue("https://github.com/dotnet/runtime/issues/38337", TestPlatforms.Browser)] public void AddJsonConsole_ChangeProperties_IsReadFromLoggingConfiguration() @@ -227,7 +289,7 @@ public void AddJsonConsole_ChangeProperties_IsReadFromLoggingConfiguration() var loggerProvider = new ServiceCollection() .AddLogging(builder => builder .AddConfiguration(configuration) - .AddJsonConsole(o => {}) + .AddJsonConsole() ) .BuildServiceProvider() .GetRequiredService(); From 9e846df9061d45d933076555f33b5f873e83a10c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20K=C3=B6plinger?= Date: Wed, 22 Jul 2020 05:05:43 +0200 Subject: [PATCH 073/458] Add note about the tagging bot to area-owners.md (#39750) Follow-up to https://github.com/dotnet/runtime/pull/39659 Co-authored-by: Dan Moseley --- docs/area-owners.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/area-owners.md b/docs/area-owners.md index 6626a5576cdc63..17b260a9c9eac4 100644 --- a/docs/area-owners.md +++ b/docs/area-owners.md @@ -1,4 +1,6 @@ -If you need to tag folks on an issue or PR, you will generally want to tag the owners (not the lead) +If you need to tag folks on an issue or PR, you will generally want to tag the owners (not the lead). + +Note: Editing this file doesn't update the mapping used by the `@msftbot` issue notification bot to tag owners. Some area owners prefer not to get those notifications. To update those notifications, contact any one of `@danmosemsft`, `@jeffschw`, `@ericstj`, or `@karelz`. If you're a community member interested in these notifications, you won't appear in this table but we can add you to notifications - just let us know. | Area | Lead | Owners (area experts to tag in PR's and issues) | Description | |------------------------------------------------|---------------|-----------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| From d8cf13e0ba9b369a15a83472b6b97463c6d07fe2 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Tue, 21 Jul 2020 20:15:13 -0700 Subject: [PATCH 074/458] Use lib prefix for native library names for consistency (#39717) --- src/coreclr/src/vm/reflectioninvocation.cpp | 1 - .../Common/src/Interop/FreeBSD/Interop.Libraries.cs | 2 +- .../Common/src/Interop/Linux/Interop.Libraries.cs | 2 +- .../Common/src/Interop/OSX/Interop.Libraries.cs | 10 +++++----- .../tests/TestUtilities/Interop/Interop.Libraries.cs | 4 ++-- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/coreclr/src/vm/reflectioninvocation.cpp b/src/coreclr/src/vm/reflectioninvocation.cpp index 41ce136349bed3..f485f9407eea48 100644 --- a/src/coreclr/src/vm/reflectioninvocation.cpp +++ b/src/coreclr/src/vm/reflectioninvocation.cpp @@ -2391,7 +2391,6 @@ FCIMPL1(INT32, ReflectionEnum::InternalGetCorElementType, Object *pRefThis) { return pMT->GetClass_NoLogging()->GetInternalCorElementType(); } FCIMPLEND -#include //******************************************************************************* struct TempEnumValue diff --git a/src/libraries/Common/src/Interop/FreeBSD/Interop.Libraries.cs b/src/libraries/Common/src/Interop/FreeBSD/Interop.Libraries.cs index 5f7687f057d82d..dc12091e1c02c2 100644 --- a/src/libraries/Common/src/Interop/FreeBSD/Interop.Libraries.cs +++ b/src/libraries/Common/src/Interop/FreeBSD/Interop.Libraries.cs @@ -6,6 +6,6 @@ internal static partial class Interop internal static partial class Libraries { internal const string Odbc32 = "libodbc.so.2"; - internal const string MsQuic = "msquic"; + internal const string MsQuic = "libmsquic.so"; } } diff --git a/src/libraries/Common/src/Interop/Linux/Interop.Libraries.cs b/src/libraries/Common/src/Interop/Linux/Interop.Libraries.cs index 57946baca56402..f97cd058bbcc31 100644 --- a/src/libraries/Common/src/Interop/Linux/Interop.Libraries.cs +++ b/src/libraries/Common/src/Interop/Linux/Interop.Libraries.cs @@ -7,6 +7,6 @@ internal static partial class Libraries { internal const string Odbc32 = "libodbc.so.2"; internal const string OpenLdap = "libldap-2.4.so.2"; - internal const string MsQuic = "msquic"; + internal const string MsQuic = "libmsquic.so"; } } diff --git a/src/libraries/Common/src/Interop/OSX/Interop.Libraries.cs b/src/libraries/Common/src/Interop/OSX/Interop.Libraries.cs index 63e497aaa39b59..0681799147525d 100644 --- a/src/libraries/Common/src/Interop/OSX/Interop.Libraries.cs +++ b/src/libraries/Common/src/Interop/OSX/Interop.Libraries.cs @@ -10,12 +10,12 @@ internal static partial class Libraries internal const string CFNetworkLibrary = "/System/Library/Frameworks/CFNetwork.framework/CFNetwork"; internal const string libobjc = "/usr/lib/libobjc.dylib"; internal const string libproc = "/usr/lib/libproc.dylib"; - internal const string LibSystemCommonCrypto = "/usr/lib/system/libcommonCrypto"; - internal const string LibSystemKernel = "/usr/lib/system/libsystem_kernel"; + internal const string LibSystemCommonCrypto = "/usr/lib/system/libcommonCrypto.dylib"; + internal const string LibSystemKernel = "/usr/lib/system/libsystem_kernel.dylib"; internal const string Odbc32 = "libodbc.2.dylib"; - internal const string OpenLdap = "libldap"; + internal const string OpenLdap = "libldap.dylib"; internal const string SystemConfigurationLibrary = "/System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration"; - internal const string AppleCryptoNative = "System.Security.Cryptography.Native.Apple"; - internal const string MsQuic = "msquic"; + internal const string AppleCryptoNative = "libSystem.Security.Cryptography.Native.Apple.dylib"; + internal const string MsQuic = "libmsquic.dylib"; } } diff --git a/src/libraries/Common/tests/TestUtilities/Interop/Interop.Libraries.cs b/src/libraries/Common/tests/TestUtilities/Interop/Interop.Libraries.cs index c8839380369d9b..c182dbeb51bef4 100644 --- a/src/libraries/Common/tests/TestUtilities/Interop/Interop.Libraries.cs +++ b/src/libraries/Common/tests/TestUtilities/Interop/Interop.Libraries.cs @@ -6,7 +6,7 @@ internal static partial class Interop internal static partial class Libraries { // Shims - public const string CryptoNative = "System.Security.Cryptography.Native.OpenSsl"; - public const string SystemNative = "System.Native"; + public const string CryptoNative = "libSystem.Security.Cryptography.Native.OpenSsl"; + public const string SystemNative = "libSystem.Native"; } } From fd1cff8c26edbb7f0a59a52d12127a995c9ebd4d Mon Sep 17 00:00:00 2001 From: Sergey Andreenko Date: Wed, 22 Jul 2020 02:02:32 -0700 Subject: [PATCH 075/458] Move `GetLclOffs` method to `GenTreeLclVarCommon`. (#39623) * Move `GetLclOffs` to `Common`. * Start using it. * Review response. --- src/coreclr/src/jit/codegenarm64.cpp | 19 +++++------ src/coreclr/src/jit/codegenarmarch.cpp | 24 +++----------- src/coreclr/src/jit/codegenlinear.cpp | 8 ++--- src/coreclr/src/jit/codegenxarch.cpp | 42 +++++++----------------- src/coreclr/src/jit/emitarm64.cpp | 6 +--- src/coreclr/src/jit/emitxarch.cpp | 6 +--- src/coreclr/src/jit/gentree.cpp | 25 +++++++++++--- src/coreclr/src/jit/gentree.h | 2 ++ src/coreclr/src/jit/morph.cpp | 2 +- src/coreclr/src/jit/simdcodegenxarch.cpp | 31 +++++++---------- 10 files changed, 62 insertions(+), 103 deletions(-) diff --git a/src/coreclr/src/jit/codegenarm64.cpp b/src/coreclr/src/jit/codegenarm64.cpp index 8ce7617de5d0ed..2edf42d8580ef4 100644 --- a/src/coreclr/src/jit/codegenarm64.cpp +++ b/src/coreclr/src/jit/codegenarm64.cpp @@ -4699,7 +4699,7 @@ void CodeGen::genStoreIndTypeSIMD12(GenTree* treeNode) genConsumeOperands(treeNode->AsOp()); - // Need an addtional integer register to extract upper 4 bytes from data. + // Need an additional integer register to extract upper 4 bytes from data. regNumber tmpReg = treeNode->GetSingleTempReg(); assert(tmpReg != addr->GetRegNum()); @@ -4766,16 +4766,13 @@ void CodeGen::genStoreLclTypeSIMD12(GenTree* treeNode) { assert((treeNode->OperGet() == GT_STORE_LCL_FLD) || (treeNode->OperGet() == GT_STORE_LCL_VAR)); - unsigned offs = 0; - unsigned varNum = treeNode->AsLclVarCommon()->GetLclNum(); - assert(varNum < compiler->lvaCount); + GenTreeLclVarCommon* lclVar = treeNode->AsLclVarCommon(); - if (treeNode->OperGet() == GT_STORE_LCL_FLD) - { - offs = treeNode->AsLclFld()->GetLclOffs(); - } + unsigned offs = lclVar->GetLclOffs(); + unsigned varNum = lclVar->GetLclNum(); + assert(varNum < compiler->lvaCount); - GenTree* op1 = treeNode->AsOp()->gtOp1; + GenTree* op1 = lclVar->gtGetOp1(); if (op1->isContained()) { @@ -4792,8 +4789,8 @@ void CodeGen::genStoreLclTypeSIMD12(GenTree* treeNode) } regNumber operandReg = genConsumeReg(op1); - // Need an addtional integer register to extract upper 4 bytes from data. - regNumber tmpReg = treeNode->GetSingleTempReg(); + // Need an additional integer register to extract upper 4 bytes from data. + regNumber tmpReg = lclVar->GetSingleTempReg(); // store lower 8 bytes GetEmitter()->emitIns_S_R(INS_str, EA_8BYTE, operandReg, varNum, offs); diff --git a/src/coreclr/src/jit/codegenarmarch.cpp b/src/coreclr/src/jit/codegenarmarch.cpp index 7dd95d2fdab6b8..a2d881588ab539 100644 --- a/src/coreclr/src/jit/codegenarmarch.cpp +++ b/src/coreclr/src/jit/codegenarmarch.cpp @@ -1959,11 +1959,7 @@ void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* node) { assert(dstAddr->OperIsLocalAddr()); dstLclNum = dstAddr->AsLclVarCommon()->GetLclNum(); - - if (dstAddr->OperIs(GT_LCL_FLD_ADDR)) - { - dstOffset = dstAddr->AsLclFld()->GetLclOffs(); - } + dstOffset = dstAddr->AsLclVarCommon()->GetLclOffs(); } regNumber srcReg; @@ -2095,11 +2091,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node) assert(dstAddr->OperIsLocalAddr()); dstLclNum = dstAddr->AsLclVarCommon()->GetLclNum(); - - if (dstAddr->OperIs(GT_LCL_FLD_ADDR)) - { - dstOffset = dstAddr->AsLclFld()->GetLclOffs(); - } + dstOffset = dstAddr->AsLclVarCommon()->GetLclOffs(); } unsigned srcLclNum = BAD_VAR_NUM; @@ -2112,11 +2104,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node) if (src->OperIs(GT_LCL_VAR, GT_LCL_FLD)) { srcLclNum = src->AsLclVarCommon()->GetLclNum(); - - if (src->OperIs(GT_LCL_FLD)) - { - srcOffset = src->AsLclFld()->GetLclOffs(); - } + srcOffset = src->AsLclVarCommon()->GetLclOffs(); } else { @@ -2136,11 +2124,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node) { assert(srcAddr->OperIsLocalAddr()); srcLclNum = srcAddr->AsLclVarCommon()->GetLclNum(); - - if (srcAddr->OperIs(GT_LCL_FLD_ADDR)) - { - srcOffset = srcAddr->AsLclFld()->GetLclOffs(); - } + srcOffset = srcAddr->AsLclVarCommon()->GetLclOffs(); } } diff --git a/src/coreclr/src/jit/codegenlinear.cpp b/src/coreclr/src/jit/codegenlinear.cpp index 94306e936549fe..5ce369b5242461 100644 --- a/src/coreclr/src/jit/codegenlinear.cpp +++ b/src/coreclr/src/jit/codegenlinear.cpp @@ -1741,15 +1741,11 @@ void CodeGen::genConsumePutStructArgStk(GenTreePutArgStk* putArgNode, { // The OperLocalAddr is always contained. assert(srcAddr->isContained()); - GenTreeLclVarCommon* lclNode = srcAddr->AsLclVarCommon(); + 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 = 0; - if (srcAddr->OperGet() == GT_LCL_FLD_ADDR) - { - offset = srcAddr->AsLclFld()->GetLclOffs(); - } + unsigned int offset = lclNode->GetLclOffs(); GetEmitter()->emitIns_R_S(INS_lea, EA_PTRSIZE, srcReg, lclNode->GetLclNum(), offset); } else diff --git a/src/coreclr/src/jit/codegenxarch.cpp b/src/coreclr/src/jit/codegenxarch.cpp index 207cef87d94e38..e65dda6b46c7bc 100644 --- a/src/coreclr/src/jit/codegenxarch.cpp +++ b/src/coreclr/src/jit/codegenxarch.cpp @@ -2694,11 +2694,7 @@ void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* node) { assert(dstAddr->OperIsLocalAddr()); dstLclNum = dstAddr->AsLclVarCommon()->GetLclNum(); - - if (dstAddr->OperIs(GT_LCL_FLD_ADDR)) - { - dstOffset = dstAddr->AsLclFld()->GetLclOffs(); - } + dstOffset = dstAddr->AsLclVarCommon()->GetLclOffs(); } regNumber srcIntReg = REG_NA; @@ -2819,11 +2815,9 @@ void CodeGen::genCodeForLoadOffset(instruction ins, emitAttr size, regNumber dst if (baseNode->OperIsLocalAddr()) { - if (baseNode->gtOper == GT_LCL_FLD_ADDR) - { - offset += baseNode->AsLclFld()->GetLclOffs(); - } - emit->emitIns_R_S(ins, size, dst, baseNode->AsLclVarCommon()->GetLclNum(), offset); + const GenTreeLclVarCommon* lclVar = baseNode->AsLclVarCommon(); + offset += lclVar->GetLclOffs(); + emit->emitIns_R_S(ins, size, dst, lclVar->GetLclNum(), offset); } else { @@ -2873,12 +2867,9 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node) else { assert(dstAddr->OperIsLocalAddr()); - dstLclNum = dstAddr->AsLclVarCommon()->GetLclNum(); - - if (dstAddr->OperIs(GT_LCL_FLD_ADDR)) - { - dstOffset = dstAddr->AsLclFld()->GetLclOffs(); - } + const GenTreeLclVarCommon* lclVar = dstAddr->AsLclVarCommon(); + dstLclNum = lclVar->GetLclNum(); + dstOffset = lclVar->GetLclOffs(); } unsigned srcLclNum = BAD_VAR_NUM; @@ -2893,11 +2884,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node) if (src->OperIs(GT_LCL_VAR, GT_LCL_FLD)) { srcLclNum = src->AsLclVarCommon()->GetLclNum(); - - if (src->OperIs(GT_LCL_FLD)) - { - srcOffset = src->AsLclFld()->GetLclOffs(); - } + srcOffset = src->AsLclVarCommon()->GetLclOffs(); } else { @@ -2929,11 +2916,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node) { assert(srcAddr->OperIsLocalAddr()); srcLclNum = srcAddr->AsLclVarCommon()->GetLclNum(); - - if (srcAddr->OperIs(GT_LCL_FLD_ADDR)) - { - srcOffset = srcAddr->AsLclFld()->GetLclOffs(); - } + srcOffset = srcAddr->AsLclVarCommon()->GetLclOffs(); } } @@ -7941,11 +7924,8 @@ void CodeGen::genPutStructArgStk(GenTreePutArgStk* putArgStk) { assert(srcAddr->OperIsLocalAddr()); - srcLclNum = srcAddr->AsLclVarCommon()->GetLclNum(); - if (srcAddr->OperGet() == GT_LCL_FLD_ADDR) - { - srcLclOffset = srcAddr->AsLclFld()->GetLclOffs(); - } + srcLclNum = srcAddr->AsLclVarCommon()->GetLclNum(); + srcLclOffset = srcAddr->AsLclVarCommon()->GetLclOffs(); } for (int i = numSlots - 1; i >= 0; --i) diff --git a/src/coreclr/src/jit/emitarm64.cpp b/src/coreclr/src/jit/emitarm64.cpp index 9a82b01063b710..a23aef5812a618 100644 --- a/src/coreclr/src/jit/emitarm64.cpp +++ b/src/coreclr/src/jit/emitarm64.cpp @@ -13396,11 +13396,7 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR { GenTreeLclVarCommon* varNode = addr->AsLclVarCommon(); unsigned lclNum = varNode->GetLclNum(); - unsigned offset = 0; - if (addr->OperIs(GT_LCL_FLD_ADDR)) - { - offset = varNode->AsLclFld()->GetLclOffs(); - } + unsigned offset = varNode->GetLclOffs(); if (emitInsIsStore(ins)) { emitIns_S_R(ins, attr, dataReg, lclNum, offset); diff --git a/src/coreclr/src/jit/emitxarch.cpp b/src/coreclr/src/jit/emitxarch.cpp index 81f9ce8ef68108..1938efb9ed44ab 100644 --- a/src/coreclr/src/jit/emitxarch.cpp +++ b/src/coreclr/src/jit/emitxarch.cpp @@ -3100,11 +3100,7 @@ void emitter::emitInsStoreInd(instruction ins, emitAttr attr, GenTreeStoreInd* m if (addr->OperIs(GT_LCL_VAR_ADDR, GT_LCL_FLD_ADDR)) { GenTreeLclVarCommon* varNode = addr->AsLclVarCommon(); - unsigned offset = 0; - if (addr->OperIs(GT_LCL_FLD_ADDR)) - { - offset = varNode->AsLclFld()->GetLclOffs(); - } + unsigned offset = varNode->GetLclOffs(); if (data->isContainedIntOrIImmed()) { emitIns_S_I(ins, attr, varNode->GetLclNum(), offset, (int)data->AsIntConCommon()->IconValue()); diff --git a/src/coreclr/src/jit/gentree.cpp b/src/coreclr/src/jit/gentree.cpp index 8ca9a49a2ce7db..03b1d7ef87f1a3 100644 --- a/src/coreclr/src/jit/gentree.cpp +++ b/src/coreclr/src/jit/gentree.cpp @@ -16365,11 +16365,7 @@ bool GenTree::DefinesLocalAddr(Compiler* comp, unsigned width, GenTreeLclVarComm *pLclVarTree = addrArgLcl; if (pIsEntire != nullptr) { - unsigned lclOffset = 0; - if (addrArg->OperIsLocalField()) - { - lclOffset = addrArg->AsLclFld()->GetLclOffs(); - } + unsigned lclOffset = addrArgLcl->GetLclOffs(); if (lclOffset != 0) { @@ -19350,6 +19346,25 @@ regNumber GenTree::ExtractTempReg(regMaskTP mask /* = (regMaskTP)-1 */) return genRegNumFromMask(tempRegMask); } +//------------------------------------------------------------------------ +// GetLclOffs: if `this` is a field or a field address it returns offset +// of the field inside the struct, for not a field it returns 0. +// +// Return Value: +// The offset value. +// +uint16_t GenTreeLclVarCommon::GetLclOffs() const +{ + if (OperIsLocalField()) + { + return AsLclFld()->GetLclOffs(); + } + else + { + return 0; + } +} + #ifdef TARGET_ARM //------------------------------------------------------------------------ // IsOffsetMisaligned: check if the field needs a special handling on arm. diff --git a/src/coreclr/src/jit/gentree.h b/src/coreclr/src/jit/gentree.h index 5e51988d76686c..b6a95a1d3c7a74 100644 --- a/src/coreclr/src/jit/gentree.h +++ b/src/coreclr/src/jit/gentree.h @@ -3180,6 +3180,8 @@ struct GenTreeLclVarCommon : public GenTreeUnOp _gtSsaNum = SsaConfig::RESERVED_SSA_NUM; } + uint16_t GetLclOffs() const; + unsigned GetSsaNum() const { return _gtSsaNum; diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp index 4d420dabaa8091..c333a2799fe45b 100644 --- a/src/coreclr/src/jit/morph.cpp +++ b/src/coreclr/src/jit/morph.cpp @@ -4602,7 +4602,7 @@ GenTree* Compiler::fgMorphMultiregStructArg(GenTree* arg, fgArgTabEntry* fgEntry assert(varNum < lvaCount); LclVarDsc* varDsc = &lvaTable[varNum]; - unsigned baseOffset = argValue->OperIs(GT_LCL_FLD) ? argValue->AsLclFld()->GetLclOffs() : 0; + unsigned baseOffset = varNode->GetLclOffs(); unsigned lastOffset = baseOffset + structSize; // The allocated size of our LocalVar must be at least as big as lastOffset diff --git a/src/coreclr/src/jit/simdcodegenxarch.cpp b/src/coreclr/src/jit/simdcodegenxarch.cpp index a1acdfd2f1a729..4045c9b97f6280 100644 --- a/src/coreclr/src/jit/simdcodegenxarch.cpp +++ b/src/coreclr/src/jit/simdcodegenxarch.cpp @@ -585,9 +585,9 @@ void CodeGen::genSIMDIntrinsicInit(GenTreeSIMD* simdNode) } else if (op1->OperIsLocalAddr()) { - unsigned offset = op1->OperIs(GT_LCL_FLD_ADDR) ? op1->AsLclFld()->GetLclOffs() : 0; - GetEmitter()->emitIns_R_S(ins, emitTypeSize(targetType), targetReg, op1->AsLclVarCommon()->GetLclNum(), - offset); + const GenTreeLclVarCommon* lclVar = op1->AsLclVarCommon(); + unsigned offset = lclVar->GetLclOffs(); + GetEmitter()->emitIns_R_S(ins, emitTypeSize(targetType), targetReg, lclVar->GetLclNum(), offset); } else { @@ -2143,17 +2143,14 @@ void CodeGen::genStoreLclTypeSIMD12(GenTree* treeNode) { assert((treeNode->OperGet() == GT_STORE_LCL_FLD) || (treeNode->OperGet() == GT_STORE_LCL_VAR)); - unsigned offs = 0; - unsigned varNum = treeNode->AsLclVarCommon()->GetLclNum(); - assert(varNum < compiler->lvaCount); + const GenTreeLclVarCommon* lclVar = treeNode->AsLclVarCommon(); - if (treeNode->OperGet() == GT_STORE_LCL_FLD) - { - offs = treeNode->AsLclFld()->GetLclOffs(); - } + unsigned offs = lclVar->GetLclOffs(); + unsigned varNum = lclVar->GetLclNum(); + assert(varNum < compiler->lvaCount); regNumber tmpReg = treeNode->GetSingleTempReg(); - GenTree* op1 = treeNode->AsOp()->gtOp1; + GenTree* op1 = lclVar->gtOp1; if (op1->isContained()) { // This is only possible for a zero-init. @@ -2197,16 +2194,12 @@ void CodeGen::genLoadLclTypeSIMD12(GenTree* treeNode) { assert((treeNode->OperGet() == GT_LCL_FLD) || (treeNode->OperGet() == GT_LCL_VAR)); - regNumber targetReg = treeNode->GetRegNum(); - unsigned offs = 0; - unsigned varNum = treeNode->AsLclVarCommon()->GetLclNum(); + const GenTreeLclVarCommon* lclVar = treeNode->AsLclVarCommon(); + regNumber targetReg = lclVar->GetRegNum(); + unsigned offs = lclVar->GetLclOffs(); + unsigned varNum = lclVar->GetLclNum(); assert(varNum < compiler->lvaCount); - if (treeNode->OperGet() == GT_LCL_FLD) - { - offs = treeNode->AsLclFld()->GetLclOffs(); - } - // Need an additional Xmm register that is different from targetReg to read upper 4 bytes. regNumber tmpReg = treeNode->GetSingleTempReg(); assert(tmpReg != targetReg); From 0cee949b9090ced852ec1485831291c12881a309 Mon Sep 17 00:00:00 2001 From: Juan Hoyos Date: Wed, 22 Jul 2020 03:15:11 -0700 Subject: [PATCH 076/458] CI Integration for Cross OS DAC (#39574) * Transfer assets from Cross OS DAC builds into a pipeline container * Preserve additional properties in subsets' projects * Add packaging projects for Cross OS Dac assets * Pipeline change to package, sign, and publish the cross OS DAC --- .editorconfig | 4 + eng/Subsets.props | 18 +++-- eng/pipelines/coreclr/templates/build-job.yml | 15 ++-- .../coreclr/templates/crossdac-build.yml | 53 +++++++++++++ .../coreclr/templates/crossdac-pack.yml | 74 +++++++++++++++++++ .../coreclr/templates/xplat-pipeline-job.yml | 27 ++++++- eng/pipelines/runtime-official.yml | 17 +++++ ...rosoft.CrossOsDiag.Private.CoreCLR.pkgproj | 21 ++++++ ...Microsoft.CrossOsDiag.Private.CoreCLR.proj | 35 +++++++++ src/coreclr/src/.nuget/coreclr-packages.proj | 30 +------- src/coreclr/src/.nuget/descriptions.json | 5 ++ src/coreclr/src/.nuget/versioning.targets | 31 ++++++++ 12 files changed, 288 insertions(+), 42 deletions(-) create mode 100644 eng/pipelines/coreclr/templates/crossdac-build.yml create mode 100644 eng/pipelines/coreclr/templates/crossdac-pack.yml create mode 100644 src/coreclr/src/.nuget/Microsoft.CrossOsDiag.Private.CoreCLR/Microsoft.CrossOsDiag.Private.CoreCLR.pkgproj create mode 100644 src/coreclr/src/.nuget/Microsoft.CrossOsDiag.Private.CoreCLR/Microsoft.CrossOsDiag.Private.CoreCLR.proj create mode 100644 src/coreclr/src/.nuget/versioning.targets diff --git a/.editorconfig b/.editorconfig index e8c010f6a2e157..9d03bd30636c9f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -184,6 +184,10 @@ indent_size = 2 [*.{props,targets,config,nuspec}] indent_size = 2 +# YAML config files +[*.{yml,yaml}] +indent_size = 2 + # Shell scripts [*.sh] end_of_line = lf diff --git a/eng/Subsets.props b/eng/Subsets.props index b27d1e55a8bdd9..fa72f142f0c5cd 100644 --- a/eng/Subsets.props +++ b/eng/Subsets.props @@ -79,12 +79,14 @@ - - + + + @@ -136,10 +138,14 @@ - + + + + + @@ -256,9 +262,9 @@ - Configuration=$(CoreCLRConfiguration) - Configuration=$(MonoConfiguration) - Configuration=$(LibrariesConfiguration) + %(AdditionalProperties);Configuration=$(CoreCLRConfiguration) + %(AdditionalProperties);Configuration=$(MonoConfiguration) + %(AdditionalProperties);Configuration=$(LibrariesConfiguration) diff --git a/eng/pipelines/coreclr/templates/build-job.yml b/eng/pipelines/coreclr/templates/build-job.yml index 9b7975156ab6e6..f2b45e8072cc61 100644 --- a/eng/pipelines/coreclr/templates/build-job.yml +++ b/eng/pipelines/coreclr/templates/build-job.yml @@ -133,7 +133,7 @@ jobs: - ${{ if and(eq(variables['System.TeamProject'], 'internal'), ne(variables['Build.Reason'], 'PullRequest')) }}: - template: /eng/pipelines/common/restore-internal-tools.yml - - ${{ if in(parameters.osGroup, 'OSX', 'iOS','tvOS') }}: + - ${{ if in(parameters.osGroup, 'OSX', 'iOS','tvOS') }}: - script: | du -sh $(Build.SourcesDirectory)/* df -h @@ -147,16 +147,12 @@ jobs: - script: set __TestIntermediateDir=int&&$(coreClrRepoRootDir)build-runtime$(scriptExt) $(buildConfig) $(archType) -ci $(enforcePgoArg) $(officialBuildIdArg) $(clrInterpreterBuildArg) displayName: Build CoreCLR Runtime - - ${{ if in(parameters.osGroup, 'OSX', 'iOS','tvOS') }}: + - ${{ if in(parameters.osGroup, 'OSX', 'iOS','tvOS') }}: - script: | du -sh $(Build.SourcesDirectory)/* df -h displayName: Disk Usage after Build - - ${{ if and(eq(parameters.osGroup, 'Windows_NT'), ne(parameters.archType, 'x86')) }}: - - script: set __TestIntermediateDir=int&&$(coreClrRepoRootDir)build-runtime$(scriptExt) $(buildConfig) $(archType) -ci -linuxdac $(officialBuildIdArg) - displayName: Build Cross OS Linux DAC for Windows - # Build CoreCLR Managed Components - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -subset clr.corelib+clr.nativecorelib+clr.tools+clr.packages $(crossArg) -arch $(archType) $(osArg) -c $(buildConfig) $(officialBuildIdArg) -ci displayName: Build managed product components and packages @@ -197,6 +193,13 @@ jobs: artifactName: $(buildProductArtifactName) displayName: 'product build' + - ${{ if and(ne(parameters.osGroup, 'OSX'), ne(parameters.archType, 'x86'), ne(parameters.compilerName, 'gcc'), ne(parameters.testGroup, 'clrTools')) }}: + - template: /eng/pipelines/coreclr/templates/crossdac-build.yml + parameters: + archType: ${{ parameters.archType }} + osGroup: ${{ parameters.osGroup }} + osSubgroup: ${{ parameters.osSubgroup }} + - ${{ if and(ne(parameters.compilerName, 'gcc'), ne(parameters.testGroup, ''), ne(parameters.testGroup, 'clrTools')) }}: # Publish test native components for consumption by test execution. - ${{ if ne(parameters.isOfficialBuild, true) }}: diff --git a/eng/pipelines/coreclr/templates/crossdac-build.yml b/eng/pipelines/coreclr/templates/crossdac-build.yml new file mode 100644 index 00000000000000..b17b72af8325ca --- /dev/null +++ b/eng/pipelines/coreclr/templates/crossdac-build.yml @@ -0,0 +1,53 @@ +parameters: + archType: '' + osGroup: '' + osSubgroup: '' + +steps: + # Always build the crossdac, that way we know in CI/PR if things break to build. + - ${{ if eq(parameters.osGroup, 'Windows_NT') }}: + - ${{ if notin(parameters.archType, 'x86') }}: + - script: set __TestIntermediateDir=int&&$(coreClrRepoRootDir)build-runtime$(scriptExt) $(buildConfig) $(archType) -ci -linuxdac $(officialBuildIdArg) + displayName: Build Cross OS Linux DAC for Windows + + + # Make the assets available in a single container for the packaging job. + - ${{ if and(ne(variables['System.TeamProject'], 'public'), ne(variables['Build.Reason'], 'PullRequest')) }}: + - ${{ if eq(parameters.osGroup, 'Windows_NT') }}: + - ${{ if notin(parameters.archType, 'x86', 'arm') }}: + - script: set __TestIntermediateDir=int&&$(coreClrRepoRootDir)build-runtime$(scriptExt) $(buildConfig) $(archType) -ci -alpinedac $(officialBuildIdArg) + displayName: Build Cross OS Linux-musl DAC for Windows + + - task: CopyFiles@2 + displayName: Gather CrossDac Artifacts (Linux) + inputs: + SourceFolder: $(buildLinuxDacRootFolderPath) + Contents: | + **/* + !**/sharedFramework/**/* + TargetFolder: $(buildLinuxDacStagingPath) + + - ${{ if ne(parameters.archType, 'arm') }}: + - task: CopyFiles@2 + displayName: Gather CrossDac Artifacts (Linux_musl) + inputs: + SourceFolder: $(buildMuslDacRootFolderPath) + Contents: | + **/* + !**/sharedFramework/**/* + TargetFolder: '$(buildMuslDacStagingPath)' + + - ${{ if eq(parameters.osGroup, 'Linux') }}: + - task: CopyFiles@2 + displayName: Gather runtime for CrossDac + inputs: + SourceFolder: $(coreClrProductRootFolderPath) + Contents: libcoreclr.so + TargetFolder: '$(crossDacArtifactPath)/${{ parameters.osGroup }}${{ parameters.osSubgroup }}.$(archType).$(buildConfigUpper)/$(crossDacHostArch)' + + - task: PublishBuildArtifacts@1 + displayName: Publish runtime for CrossDac + inputs: + pathtoPublish: $(crossDacArtifactPath) + PublishLocation: Container + artifactName: $(buildCrossDacArtifactName) diff --git a/eng/pipelines/coreclr/templates/crossdac-pack.yml b/eng/pipelines/coreclr/templates/crossdac-pack.yml new file mode 100644 index 00000000000000..f876a85d33febb --- /dev/null +++ b/eng/pipelines/coreclr/templates/crossdac-pack.yml @@ -0,0 +1,74 @@ +parameters: + archType: '' + buildConfig: '' + container: '' + crossDacPlatforms: {} + isOfficialBuild: false + osGroup: '' + osSubgroup: '' + platform: '' + pool: '' + runtimeVariant: '' + stagedBuild: false + testGroup: '' + timeoutInMinutes: '' + variables: {} + +jobs: +- template: xplat-pipeline-job.yml + parameters: + archType: ${{ parameters.archType }} + buildConfig: ${{ parameters.buildConfig }} + container: ${{ parameters.container }} + condition: ${{ parameters.isOfficialBuild }} + helixType: 'build/product/' + osGroup: ${{ parameters.osGroup }} + osSubgroup: ${{ parameters.osSubgroup }} + pool: ${{ parameters.pool }} + runtimeVariant: ${{ parameters.runtimeVariant }} + stagedBuild: ${{ parameters.stagedBuild }} + timeoutInMinutes: ${{ parameters.timeoutInMinutes }} + + name: crossdacpack + displayName: CrossDac Packaging + + variables: + - name: officialBuildIdArg + value: '' + - name: crossDacArgs + value: '' + - ${{ if and(eq(variables['System.TeamProject'], 'internal'), ne(variables['Build.Reason'], 'PullRequest')) }}: + - name: officialBuildIdArg + value: '/p:OfficialBuildId=$(Build.BuildNumber)' + - name: crossDacArgs + value: '/p:CrossDacArtifactsDir=$(crossDacArtifactPath)/$(buildCrossDacArtifactName)' + - ${{ parameters.variables }} + + dependsOn: + - ${{ if ne(parameters.crossDacPlatforms, '') }}: + - ${{ each platform in parameters.crossDacPlatforms }}: + - ${{ parameters.runtimeFlavor }}_${{ parameters.runtimeVariant }}_product_build_${{ platform }}_${{ parameters.buildConfig }} + + steps: + - task: DownloadBuildArtifacts@0 + displayName: Download CrossDac artifacts + inputs: + artifactName: $(buildCrossDacArtifactName) + downloadPath: $(crossDacArtifactPath) + + - script: $(Build.SourcesDirectory)$(dir)build$(scriptExt) -subset crossdacpack -arch $(archType) $(osArg) -c $(buildConfig) $(officialBuildIdArg) $(crossDacArgs) -ci + displayName: Build crossdac packaging + + # Save packages using the prepare-signed-artifacts format. + - template: /eng/pipelines/common/upload-unsigned-artifacts-step.yml + parameters: + name: ${{ parameters.platform }} + + # Upload to artifacts to be signed + - task: PublishPipelineArtifact@1 + displayName: Publish Logs + inputs: + targetPath: $(Build.SourcesDirectory)/artifacts/log + artifactName: 'CrossDacPackagingLogs' + continueOnError: true + condition: always() diff --git a/eng/pipelines/coreclr/templates/xplat-pipeline-job.yml b/eng/pipelines/coreclr/templates/xplat-pipeline-job.yml index dfcf6652e25e4b..0e789b84e91991 100644 --- a/eng/pipelines/coreclr/templates/xplat-pipeline-job.yml +++ b/eng/pipelines/coreclr/templates/xplat-pipeline-job.yml @@ -65,7 +65,7 @@ jobs: - name: binTestsPath value: '$(Build.SourcesDirectory)/artifacts/tests/coreclr' - + # Build product defines what we are trying to build, either coreclr or mono - name: buildProductArtifactName value: 'CoreCLRProduct_${{ parameters.runtimeVariant }}_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' @@ -73,6 +73,31 @@ jobs: - name: buildProductRootFolderPath value: '$(Build.SourcesDirectory)/artifacts/bin/coreclr/$(osGroup).$(archType).$(buildConfigUpper)' + - name: buildCrossDacArtifactName + value: CoreCLRCrossDacArtifacts + + - name: crossDacArtifactPath + value: $(Build.SourcesDirectory)/artifacts/$(buildCrossDacArtifactName) + + - name: buildMuslDacRootFolderPath + value: '$(Build.SourcesDirectory)/artifacts/bin/coreclr/alpine.$(archType).$(buildConfigUpper)' + + - name: buildMuslDacStagingPath + value: '$(crossDacArtifactPath)/Linux_musl.$(archType).$(buildConfigUpper)' + + - name: buildLinuxDacRootFolderPath + value: '$(Build.SourcesDirectory)/artifacts/bin/coreclr/Linux.$(archType).$(buildConfigUpper)' + + - name: buildLinuxDacStagingPath + value: '$(crossDacArtifactPath)/Linux.$(archType).$(buildConfigUpper)' + + - name: crossDacHostArch + value: x64 + + - ${{ if eq(parameters.archType, 'arm') }}: + - name: crossDacHostArch + value: x86 + # We need this because both mono and coreclr build currently depends on CoreClr - name: coreClrProductArtifactName value: 'CoreCLRProduct_${{ parameters.runtimeVariant }}_$(osGroup)$(osSubgroup)_$(archType)_$(buildConfig)' diff --git a/eng/pipelines/runtime-official.yml b/eng/pipelines/runtime-official.yml index f063eb3e1c0c8c..e1a3f8e7eefb1d 100644 --- a/eng/pipelines/runtime-official.yml +++ b/eng/pipelines/runtime-official.yml @@ -62,6 +62,23 @@ stages: jobParameters: isOfficialBuild: ${{ variables.isOfficialBuild }} + - template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/coreclr/templates/crossdac-pack.yml + buildConfig: release + platforms: + - Linux_musl_x64 + jobParameters: + isOfficialBuild: ${{ variables.isOfficialBuild }} + crossDacPlatforms: + - Linux_x64 + - Linux_arm + - Linux_arm64 + - Linux_musl_x64 + - Linux_musl_arm64 + - Windows_NT_x64 + - Windows_NT_arm + - Windows_NT_arm64 # # Build Mono runtime packs # diff --git a/src/coreclr/src/.nuget/Microsoft.CrossOsDiag.Private.CoreCLR/Microsoft.CrossOsDiag.Private.CoreCLR.pkgproj b/src/coreclr/src/.nuget/Microsoft.CrossOsDiag.Private.CoreCLR/Microsoft.CrossOsDiag.Private.CoreCLR.pkgproj new file mode 100644 index 00000000000000..54a1cc17dfbc4a --- /dev/null +++ b/src/coreclr/src/.nuget/Microsoft.CrossOsDiag.Private.CoreCLR/Microsoft.CrossOsDiag.Private.CoreCLR.pkgproj @@ -0,0 +1,21 @@ + + + + + false + + + + + + + + + runtimes/$(PackageTargetRuntime)/native + + + + + + + diff --git a/src/coreclr/src/.nuget/Microsoft.CrossOsDiag.Private.CoreCLR/Microsoft.CrossOsDiag.Private.CoreCLR.proj b/src/coreclr/src/.nuget/Microsoft.CrossOsDiag.Private.CoreCLR/Microsoft.CrossOsDiag.Private.CoreCLR.proj new file mode 100644 index 00000000000000..037a6b102605b5 --- /dev/null +++ b/src/coreclr/src/.nuget/Microsoft.CrossOsDiag.Private.CoreCLR/Microsoft.CrossOsDiag.Private.CoreCLR.proj @@ -0,0 +1,35 @@ + + + + + false + linux-x64;linux-musl-x64;linux-arm64;linux-musl-arm64;linux-arm; + + + + + + + + + <_projectsToBuild Include="@(Project)" Condition="$(SupportedRids.Contains('%(Project.PackageTargetRuntime)'))"> + %(AdditionalProperties);CrossDacBinRoot=$(CrossDacArtifactsDir)/Linux.x64.$(Configuration)/x64 + %(AdditionalProperties);CrossDacBinRoot=$(CrossDacArtifactsDir)/Linux_musl.x64.$(Configuration)/x64 + %(AdditionalProperties);CrossDacBinRoot=$(CrossDacArtifactsDir)/Linux.arm64.$(Configuration)/x64 + %(AdditionalProperties);CrossDacBinRoot=$(CrossDacArtifactsDir)/Linux_musl.arm64.$(Configuration)/x64 + %(AdditionalProperties);CrossDacBinRoot=$(CrossDacArtifactsDir)/Linux.arm.$(Configuration)/x86 + + + + + + + + + + + + + + diff --git a/src/coreclr/src/.nuget/coreclr-packages.proj b/src/coreclr/src/.nuget/coreclr-packages.proj index f460db9bcd3d1b..83b95cd3748202 100644 --- a/src/coreclr/src/.nuget/coreclr-packages.proj +++ b/src/coreclr/src/.nuget/coreclr-packages.proj @@ -13,36 +13,8 @@ - - - - - - - - - - - - - - - - + diff --git a/src/coreclr/src/.nuget/descriptions.json b/src/coreclr/src/.nuget/descriptions.json index e9ac7c58fcc1fc..c172fed61b84c8 100644 --- a/src/coreclr/src/.nuget/descriptions.json +++ b/src/coreclr/src/.nuget/descriptions.json @@ -9,6 +9,11 @@ "Description": "When using NuGet 3.x this package requires at least version {0}.", "CommonTypes": [ ] }, + { + "Name": "Microsoft.CrossOsDiag.Private.CoreCLR", + "Description": "Private transport package for .NET Core cross OS diagnostic tooling.", + "CommonTypes": [ ] + }, { "Name": "Microsoft.NETCore.ILAsm", "Description": "The .NET IL Assembler.", diff --git a/src/coreclr/src/.nuget/versioning.targets b/src/coreclr/src/.nuget/versioning.targets new file mode 100644 index 00000000000000..9b5ea266a93f12 --- /dev/null +++ b/src/coreclr/src/.nuget/versioning.targets @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + From 8087ae540d735ba0fd16223e1053fabfa151ea26 Mon Sep 17 00:00:00 2001 From: Maxim Lipnin Date: Wed, 22 Jul 2020 14:40:18 +0300 Subject: [PATCH 077/458] [wasm] Enable System.Xml.XmlSerializer.ReflectionOnly.Tests, System.Xml.XmlSerializer.Tests, and System.Security.Permissions.Tests test suites (#39767) --- .../System.Security.Permissions/tests/EvidenceBaseTests.cs | 1 + .../tests/MembershipConditionTests.cs | 2 ++ .../System.Security.Permissions/tests/PermissionTests.cs | 1 + src/libraries/tests.proj | 3 --- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Security.Permissions/tests/EvidenceBaseTests.cs b/src/libraries/System.Security.Permissions/tests/EvidenceBaseTests.cs index 9eea6a3dc41bff..ba17fea6bb286b 100644 --- a/src/libraries/System.Security.Permissions/tests/EvidenceBaseTests.cs +++ b/src/libraries/System.Security.Permissions/tests/EvidenceBaseTests.cs @@ -39,6 +39,7 @@ public static void GacInstalledCallMethods() } [Fact] + [PlatformSpecific(~TestPlatforms.Browser)] // System.Security.Cryptography.Algorithms is not supported on this platform. public static void HashCallMethods() { Hash hash = new Hash(Reflection.Assembly.Load(new Reflection.AssemblyName("System.Reflection"))); diff --git a/src/libraries/System.Security.Permissions/tests/MembershipConditionTests.cs b/src/libraries/System.Security.Permissions/tests/MembershipConditionTests.cs index d9758dcbaaf617..660661c1520f30 100644 --- a/src/libraries/System.Security.Permissions/tests/MembershipConditionTests.cs +++ b/src/libraries/System.Security.Permissions/tests/MembershipConditionTests.cs @@ -61,6 +61,7 @@ public static void GacMembershipConditionCallMethods() } [Fact] + [PlatformSpecific(~TestPlatforms.Browser)] // System.Security.Cryptography.Algorithms is not supported on this platform. public static void HashMembershipConditionCallMethods() { HashMembershipCondition hmc = new HashMembershipCondition(Cryptography.SHA1.Create(), new byte[1]); @@ -78,6 +79,7 @@ public static void HashMembershipConditionCallMethods() } [Fact] + [PlatformSpecific(~TestPlatforms.Browser)] // System.Security.Cryptography.X509Certificates is not supported on this platform. public static void PublisherMembershipConditionCallMethods() { PublisherMembershipCondition pmc = new PublisherMembershipCondition(new System.Security.Cryptography.X509Certificates.X509Certificate()); diff --git a/src/libraries/System.Security.Permissions/tests/PermissionTests.cs b/src/libraries/System.Security.Permissions/tests/PermissionTests.cs index 9889feffb6dc35..d09b48f343a567 100644 --- a/src/libraries/System.Security.Permissions/tests/PermissionTests.cs +++ b/src/libraries/System.Security.Permissions/tests/PermissionTests.cs @@ -210,6 +210,7 @@ public static void PrincipalPermissionCallMethods() } [Fact] + [PlatformSpecific(~TestPlatforms.Browser)] // System.Security.Cryptography.X509Certificates is not supported on this platform. public static void PublisherIdentityPermissionCallMethods() { PublisherIdentityPermission pip = new PublisherIdentityPermission(new System.Security.Cryptography.X509Certificates.X509Certificate()); diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index fdd0e1e851169b..871aae867b8bd8 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -38,9 +38,6 @@ - - - From df9873f60d9d2ef91116f031cc8c4941d321e67b Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Wed, 22 Jul 2020 09:15:42 -0500 Subject: [PATCH 078/458] [wasm] WasmAppBuilder write the json as json (#39660) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Write the json as json Co-authored-by: Alexander Köplinger --- .../WasmAppBuilder/WasmAppBuilder.cs | 127 +++++++++++------- 1 file changed, 80 insertions(+), 47 deletions(-) diff --git a/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs b/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs index c16e13d1a0073c..94ad3a5267fda0 100644 --- a/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs +++ b/tools-local/tasks/mobile.tasks/WasmAppBuilder/WasmAppBuilder.cs @@ -9,6 +9,8 @@ using System.IO; using System.Linq; using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Reflection; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; @@ -34,6 +36,47 @@ public class WasmAppBuilder : Task SortedDictionary? _assemblies; Resolver? _resolver; + private class WasmAppConfig + { + [JsonPropertyName("assembly_root")] + public string AssemblyRoot { get; set; } = "managed"; + [JsonPropertyName("enable_debugging")] + public int EnableDebugging { get; set; } = 0; + [JsonPropertyName("assets")] + public List Assets { get; } = new List(); + [JsonPropertyName("remote_sources")] + public List RemoteSources { get; set; } = new List(); + } + + private class AssetEntry { + protected AssetEntry (string name, string behavior) + { + Name = name; + Behavior = behavior; + } + [JsonPropertyName("behavior")] + public string Behavior { get; init; } + [JsonPropertyName("name")] + public string Name { get; init; } + } + + private class AssemblyEntry : AssetEntry + { + public AssemblyEntry(string name) : base(name, "assembly") {} + } + + private class VfsEntry : AssetEntry { + public VfsEntry(string name) : base(name, "vfs") {} + [JsonPropertyName("virtual_path")] + public string? VirtualPath { get; set; } + } + + private class IcuData : AssetEntry { + public IcuData(string name = "icudt.dat") : base(name, "icu") {} + [JsonPropertyName("load_remote")] + public bool LoadRemote { get; set; } + } + public override bool Execute () { if (!File.Exists(MainAssembly)) @@ -55,7 +98,7 @@ public override bool Execute () _resolver = new Resolver(paths); var mlc = new MetadataLoadContext(_resolver, "System.Private.CoreLib"); - var mainAssembly = mlc.LoadFromAssemblyPath (MainAssembly); + var mainAssembly = mlc.LoadFromAssemblyPath(MainAssembly); Add(mlc, mainAssembly); if (ExtraAssemblies != null) @@ -67,71 +110,61 @@ public override bool Execute () } } + var config = new WasmAppConfig (); + // Create app Directory.CreateDirectory(AppDir!); - Directory.CreateDirectory(Path.Join(AppDir, "managed")); + Directory.CreateDirectory(Path.Join(AppDir, config.AssemblyRoot)); foreach (var assembly in _assemblies!.Values) - File.Copy(assembly.Location, Path.Join(AppDir, "managed", Path.GetFileName(assembly.Location)), true); + File.Copy(assembly.Location, Path.Join(AppDir, config.AssemblyRoot, Path.GetFileName(assembly.Location)), true); foreach (var f in new string[] { "dotnet.wasm", "dotnet.js", "dotnet.timezones.blat", "icudt.dat" }) File.Copy(Path.Join (MicrosoftNetCoreAppRuntimePackDir, "native", f), Path.Join(AppDir, f), true); File.Copy(MainJS!, Path.Join(AppDir, "runtime.js"), true); - using (var sw = File.CreateText(Path.Join(AppDir, "mono-config.js"))) - { - sw.WriteLine("config = {"); - sw.WriteLine("\tassembly_root: \"managed\","); - sw.WriteLine("\tenable_debugging: 0,"); - sw.WriteLine("\tassets: ["); + foreach (var assembly in _assemblies.Values) + config.Assets.Add(new AssemblyEntry (Path.GetFileName(assembly.Location))); - foreach (var assembly in _assemblies.Values) - sw.WriteLine($"\t\t{{ behavior: \"assembly\", name: \"{Path.GetFileName(assembly.Location)}\" }},"); + if (FilesToIncludeInFileSystem != null) + { + string supportFilesDir = Path.Join(AppDir, "supportFiles"); + Directory.CreateDirectory(supportFilesDir); - if (FilesToIncludeInFileSystem != null) + var i = 0; + foreach (var item in FilesToIncludeInFileSystem) { - string supportFilesDir = Path.Join(AppDir, "supportFiles"); - Directory.CreateDirectory(supportFilesDir); - - var i = 0; - foreach (var item in FilesToIncludeInFileSystem) + string? targetPath = item.GetMetadata("TargetPath"); + if (string.IsNullOrEmpty(targetPath)) { - string? targetPath = item.GetMetadata("TargetPath"); - if (string.IsNullOrEmpty(targetPath)) - { - targetPath = Path.GetFileName(item.ItemSpec); - } - - // We normalize paths from `\` to `/` as MSBuild items could use `\`. - targetPath = targetPath.Replace('\\', '/'); + targetPath = Path.GetFileName(item.ItemSpec); + } - var generatedFileName = $"{i++}_{Path.GetFileName(item.ItemSpec)}"; + // We normalize paths from `\` to `/` as MSBuild items could use `\`. + targetPath = targetPath.Replace('\\', '/'); - File.Copy(item.ItemSpec, Path.Join(supportFilesDir, generatedFileName), true); + var generatedFileName = $"{i++}_{Path.GetFileName(item.ItemSpec)}"; - var actualItemName = "supportFiles/" + generatedFileName; + File.Copy(item.ItemSpec, Path.Join(supportFilesDir, generatedFileName), true); - sw.WriteLine("\t\t{"); - sw.WriteLine("\t\t\tbehavior: \"vfs\","); - sw.WriteLine($"\t\t\tname: \"{actualItemName}\","); - sw.WriteLine($"\t\t\tvirtual_path: \"{targetPath}\","); - sw.WriteLine("\t\t},"); - } + var asset = new VfsEntry ($"supportFiles/{generatedFileName}") { + VirtualPath = targetPath + }; + config.Assets.Add(asset); } + } - var enableRemote = (RemoteSources != null) && (RemoteSources!.Length > 0); - var sEnableRemote = enableRemote ? "true" : "false"; - - sw.WriteLine($"\t\t{{ behavior: \"icu\", name: \"icudt.dat\", load_remote: {sEnableRemote} }},"); - sw.WriteLine($"\t\t{{ behavior: \"vfs\", name: \"dotnet.timezones.blat\", virtual_path: \"/usr/share/zoneinfo/\" }}"); - sw.WriteLine ("\t],"); + config.Assets.Add(new IcuData { LoadRemote = RemoteSources?.Length > 0 }); + config.Assets.Add(new VfsEntry ("dotnet.timezones.blat") { VirtualPath = "/usr/share/zoneinfo/"}); - if (enableRemote) { - sw.WriteLine("\tremote_sources: ["); - foreach (var source in RemoteSources!) - sw.WriteLine("\t\t\"" + source.ItemSpec + "\", "); - sw.WriteLine ("\t],"); - } + if (RemoteSources?.Length > 0) { + foreach (var source in RemoteSources) + if (source != null && source.ItemSpec != null) + config.RemoteSources.Add(source.ItemSpec); + } - sw.WriteLine ("};"); + using (var sw = File.CreateText(Path.Join(AppDir, "mono-config.js"))) + { + var json = JsonSerializer.Serialize (config, new JsonSerializerOptions { WriteIndented = true }); + sw.Write($"config = {json};"); } using (var sw = File.CreateText(Path.Join(AppDir, "run-v8.sh"))) From 1d0eb4b68b97b5429971924347d001de618a9fc6 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 22 Jul 2020 07:27:01 -0700 Subject: [PATCH 079/458] Use function pointers in more places (#39752) --- .../InteropServices/Marshal.CoreCLR.cs | 31 ++- src/coreclr/src/vm/ecalllist.h | 3 - src/coreclr/src/vm/marshalnative.cpp | 77 ------ src/coreclr/src/vm/marshalnative.h | 7 - .../RuntimeBinder/ComInterop/ComInterop.cs | 15 -- .../ComInterop/ComRuntimeHelpers.cs | 230 ++---------------- 6 files changed, 50 insertions(+), 313 deletions(-) diff --git a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs index 513a96b668cfbf..33d43881adb3ac 100644 --- a/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs +++ b/src/coreclr/src/System.Private.CoreLib/src/System/Runtime/InteropServices/Marshal.CoreCLR.cs @@ -701,14 +701,33 @@ public static TWrapper CreateWrapperOfType([AllowNull] T o) [MethodImpl(MethodImplOptions.InternalCall)] public static extern bool IsTypeVisibleFromCom(Type t); - [MethodImpl(MethodImplOptions.InternalCall)] - public static extern int /* HRESULT */ QueryInterface(IntPtr /* IUnknown */ pUnk, ref Guid iid, out IntPtr ppv); + public static unsafe int QueryInterface(IntPtr pUnk, ref Guid iid, out IntPtr ppv) + { + if (pUnk == IntPtr.Zero) + throw new ArgumentNullException(nameof(pUnk)); - [MethodImpl(MethodImplOptions.InternalCall)] - public static extern int /* ULONG */ AddRef(IntPtr /* IUnknown */ pUnk); + fixed (Guid* pIID = &iid) + fixed (IntPtr* p = &ppv) + { + return ((delegate * stdcall )(*(*(void***)pUnk + 0 /* IUnknown.QueryInterface slot */)))(pUnk, pIID, p); + } + } - [MethodImpl(MethodImplOptions.InternalCall)] - public static extern int /* ULONG */ Release(IntPtr /* IUnknown */ pUnk); + public static unsafe int AddRef(IntPtr pUnk) + { + if (pUnk == IntPtr.Zero) + throw new ArgumentNullException(nameof(pUnk)); + + return ((delegate * stdcall )(*(*(void***)pUnk + 1 /* IUnknown.AddRef slot */)))(pUnk); + } + + public static unsafe int Release(IntPtr pUnk) + { + if (pUnk == IntPtr.Zero) + throw new ArgumentNullException(nameof(pUnk)); + + return ((delegate * stdcall )(*(*(void***)pUnk + 2 /* IUnknown.Release slot */)))(pUnk); + } [MethodImpl(MethodImplOptions.InternalCall)] public static extern void GetNativeVariantForObject(object? obj, /* VARIANT * */ IntPtr pDstNativeVariant); diff --git a/src/coreclr/src/vm/ecalllist.h b/src/coreclr/src/vm/ecalllist.h index d6b592a8bb88ab..de55a1913441c3 100644 --- a/src/coreclr/src/vm/ecalllist.h +++ b/src/coreclr/src/vm/ecalllist.h @@ -776,12 +776,10 @@ FCFuncStart(gInteropMarshalFuncs) FCFuncElement("IsComObject", MarshalNative::IsComObject) FCFuncElement("GetObjectForIUnknownNative", MarshalNative::GetObjectForIUnknownNative) FCFuncElement("GetUniqueObjectForIUnknownNative", MarshalNative::GetUniqueObjectForIUnknownNative) - FCFuncElement("AddRef", MarshalNative::AddRef) FCFuncElement("GetNativeVariantForObject", MarshalNative::GetNativeVariantForObject) FCFuncElement("GetObjectForNativeVariant", MarshalNative::GetObjectForNativeVariant) FCFuncElement("InternalFinalReleaseComObject", MarshalNative::FinalReleaseComObject) FCFuncElement("IsTypeVisibleFromCom", MarshalNative::IsTypeVisibleFromCom) - FCFuncElement("QueryInterface", MarshalNative::QueryInterface) FCFuncElement("CreateAggregatedObject", MarshalNative::CreateAggregatedObject) FCFuncElement("AreComObjectsAvailableForCleanup", MarshalNative::AreComObjectsAvailableForCleanup) FCFuncElement("InternalCreateWrapperOfType", MarshalNative::InternalCreateWrapperOfType) @@ -792,7 +790,6 @@ FCFuncStart(gInteropMarshalFuncs) FCFuncElement("GetIDispatchForObjectNative", MarshalNative::GetIDispatchForObjectNative) FCFuncElement("GetComInterfaceForObjectNative", MarshalNative::GetComInterfaceForObjectNative) FCFuncElement("InternalReleaseComObject", MarshalNative::ReleaseComObject) - FCFuncElement("Release", MarshalNative::Release) FCFuncElement("GetTypedObjectForIUnknown", MarshalNative::GetTypedObjectForIUnknown) FCFuncElement("ChangeWrapperHandleStrength", MarshalNative::ChangeWrapperHandleStrength) FCFuncElement("CleanupUnusedObjectsInCurrentContext", MarshalNative::CleanupUnusedObjectsInCurrentContext) diff --git a/src/coreclr/src/vm/marshalnative.cpp b/src/coreclr/src/vm/marshalnative.cpp index e4f95bb77394d4..46a7742ff7ce74 100644 --- a/src/coreclr/src/vm/marshalnative.cpp +++ b/src/coreclr/src/vm/marshalnative.cpp @@ -1226,83 +1226,6 @@ FCIMPL1(FC_BOOL_RET, MarshalNative::IsTypeVisibleFromCom, ReflectClassBaseObject } FCIMPLEND - -//==================================================================== -// IUnknown Helpers -//==================================================================== -// IUnknown::QueryInterface -FCIMPL3(HRESULT, MarshalNative::QueryInterface, IUnknown* pUnk, REFGUID iid, void** ppv) -{ - CONTRACTL - { - FCALL_CHECK; - PRECONDITION(CheckPointer(pUnk, NULL_OK)); - PRECONDITION(CheckPointer(ppv)); - } - CONTRACTL_END; - - HRESULT hr = S_OK; - HELPER_METHOD_FRAME_BEGIN_RET_0(); - - if (!pUnk) - COMPlusThrowArgumentNull(W("pUnk")); - - hr = SafeQueryInterface(pUnk,iid,(IUnknown**)ppv); - LogInteropQI(pUnk, iid, hr, "PInvoke::QI"); - - HELPER_METHOD_FRAME_END(); - return hr; -} -FCIMPLEND - -// IUnknown::AddRef -FCIMPL1(ULONG, MarshalNative::AddRef, IUnknown* pUnk) -{ - CONTRACTL - { - FCALL_CHECK; - PRECONDITION(CheckPointer(pUnk, NULL_OK)); - } - CONTRACTL_END; - - ULONG cbRef = 0; - HELPER_METHOD_FRAME_BEGIN_RET_0(); - - if (!pUnk) - COMPlusThrowArgumentNull(W("pUnk")); - - cbRef = SafeAddRef(pUnk); - LogInteropAddRef(pUnk, cbRef, "PInvoke.AddRef"); - - HELPER_METHOD_FRAME_END(); - return cbRef; -} -FCIMPLEND - -//IUnknown::Release -FCIMPL1(ULONG, MarshalNative::Release, IUnknown* pUnk) -{ - CONTRACTL - { - FCALL_CHECK; - PRECONDITION(CheckPointer(pUnk, NULL_OK)); - } - CONTRACTL_END; - - ULONG cbRef = 0; - HELPER_METHOD_FRAME_BEGIN_RET_0(); - - if (!pUnk) - COMPlusThrowArgumentNull(W("pUnk")); - - cbRef = SafeRelease(pUnk); - LogInteropRelease(pUnk, cbRef, "PInvoke.Release"); - - HELPER_METHOD_FRAME_END(); - return cbRef; -} -FCIMPLEND - FCIMPL2(void, MarshalNative::GetNativeVariantForObject, Object* ObjUNSAFE, LPVOID pDestNativeVariant) { CONTRACTL diff --git a/src/coreclr/src/vm/marshalnative.h b/src/coreclr/src/vm/marshalnative.h index 574d40c9d2c50e..5218e12c6fabb0 100644 --- a/src/coreclr/src/vm/marshalnative.h +++ b/src/coreclr/src/vm/marshalnative.h @@ -151,13 +151,6 @@ class MarshalNative //==================================================================== static FCDECL1(FC_BOOL_RET, IsTypeVisibleFromCom, ReflectClassBaseObject* refClassUNSAFE); - //==================================================================== - // IUnknown Helpers - //==================================================================== - static FCDECL3(HRESULT, QueryInterface, IUnknown* pUnk, REFGUID iid, void** ppv); - static FCDECL1(ULONG, AddRef, IUnknown* pUnk); - static FCDECL1(ULONG, Release, IUnknown* pUnk); - //==================================================================== // These methods convert OLE variants to and from objects. //==================================================================== diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ComInterop/ComInterop.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ComInterop/ComInterop.cs index 275a6d50538656..b146f6fd807755 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ComInterop/ComInterop.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ComInterop/ComInterop.cs @@ -41,21 +41,6 @@ int TryInvoke( IntPtr puArgErr); } - /// - /// Layout of the IDispatch vtable - /// - internal enum IDispatchMethodIndices - { - IUnknown_QueryInterface, - IUnknown_AddRef, - IUnknown_Release, - - IDispatch_GetTypeInfoCount, - IDispatch_GetTypeInfo, - IDispatch_GetIDsOfNames, - IDispatch_Invoke - } - [ComImport] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [Guid("B196B283-BAB4-101A-B69C-00AA00341D07")] diff --git a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ComInterop/ComRuntimeHelpers.cs b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ComInterop/ComRuntimeHelpers.cs index 01bc32bf59ae22..0814a30a0e88b7 100644 --- a/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ComInterop/ComRuntimeHelpers.cs +++ b/src/libraries/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/ComInterop/ComRuntimeHelpers.cs @@ -260,9 +260,9 @@ public static object GetObjectForVariant(Variant variant) } // This method is intended for use through reflection and should only be used directly by IUnknownReleaseNotZero - public static int IUnknownRelease(IntPtr interfacePointer) + public static unsafe int IUnknownRelease(IntPtr interfacePointer) { - return s_iUnknownRelease(interfacePointer); + return ((delegate* stdcall)(*(*(void***)interfacePointer + 2 /* IUnknown.Release slot */)))(interfacePointer); } // This method is intended for use through reflection and should not be used directly @@ -275,7 +275,7 @@ public static void IUnknownReleaseNotZero(IntPtr interfacePointer) } // This method is intended for use through reflection and should not be used directly - public static int IDispatchInvoke( + public static unsafe int IDispatchInvoke( IntPtr dispatchPointer, int memberDispId, ComTypes.INVOKEKIND flags, @@ -284,31 +284,30 @@ public static int IDispatchInvoke( out ExcepInfo excepInfo, out uint argErr) { - int hresult = s_iDispatchInvoke( - dispatchPointer, - memberDispId, - flags, - ref dispParams, - out result, - out excepInfo, - out argErr - ); - - if (hresult == ComHresults.DISP_E_MEMBERNOTFOUND - && (flags & ComTypes.INVOKEKIND.INVOKE_FUNC) != 0 - && (flags & (ComTypes.INVOKEKIND.INVOKE_PROPERTYPUT | ComTypes.INVOKEKIND.INVOKE_PROPERTYPUTREF)) == 0) + Guid IID_NULL = default; + + fixed (ComTypes.DISPPARAMS* pDispParams = &dispParams) + fixed (Variant* pResult = &result) + fixed (ExcepInfo* pExcepInfo = &excepInfo) + fixed (uint* pArgErr = &argErr) { - // Re-invoke with no result argument to accomodate Word - hresult = _IDispatchInvokeNoResult( - dispatchPointer, - memberDispId, - ComTypes.INVOKEKIND.INVOKE_FUNC, - ref dispParams, - out result, - out excepInfo, - out argErr); + var pfnIDispatchInvoke = (delegate* stdcall ) + (*(*(void***)dispatchPointer + 6 /* IDispatch.Invoke slot */)); + + int hresult = pfnIDispatchInvoke(dispatchPointer, + memberDispId, &IID_NULL, 0, (ushort)flags, pDispParams, pResult, pExcepInfo, pArgErr); + + if (hresult == ComHresults.DISP_E_MEMBERNOTFOUND + && (flags & ComTypes.INVOKEKIND.INVOKE_FUNC) != 0 + && (flags & (ComTypes.INVOKEKIND.INVOKE_PROPERTYPUT | ComTypes.INVOKEKIND.INVOKE_PROPERTYPUTREF)) == 0) + { + // Re-invoke with no result argument to accomodate Word + hresult = pfnIDispatchInvoke(dispatchPointer, + memberDispId, &IID_NULL, 0, (ushort)ComTypes.INVOKEKIND.INVOKE_FUNC, pDispParams, null, pExcepInfo, pArgErr); + } + + return hresult; } - return hresult; } // This method is intended for use through reflection and should not be used directly @@ -338,12 +337,6 @@ public static IntPtr GetIdsOfNamedParameters(IDispatch dispatch, string[] names, #region non-public members - private static void EmitLoadArg(ILGenerator il, int index) - { - Requires.Condition(index >= 0, nameof(index)); - il.Emit(OpCodes.Ldarg, index); - } - private static readonly object s_lock = new object(); private static ModuleBuilder s_dynamicModule; @@ -368,179 +361,6 @@ internal static ModuleBuilder DynamicModule } } - /// - /// We will emit an indirect call to an unmanaged function pointer from the vtable of the given interface pointer. - /// This approach can take only ~300 instructions on x86 compared with ~900 for Marshal.Release. We are relying on - /// the JIT-compiler to do pinvoke-stub-inlining and calling the pinvoke target directly. - /// - private delegate int IUnknownReleaseDelegate(IntPtr interfacePointer); - private static readonly IUnknownReleaseDelegate s_iUnknownRelease = Create_IUnknownRelease(); - - private static IUnknownReleaseDelegate Create_IUnknownRelease() - { - DynamicMethod dm = new DynamicMethod("IUnknownRelease", typeof(int), new Type[] { typeof(IntPtr) }, DynamicModule); - - ILGenerator method = dm.GetILGenerator(); - - // return functionPtr(...) - - method.Emit(OpCodes.Ldarg_0); - - // functionPtr = *(IntPtr*)(*(interfacePointer) + VTABLE_OFFSET) - int iunknownReleaseOffset = ((int)IDispatchMethodIndices.IUnknown_Release) * Marshal.SizeOf(typeof(IntPtr)); - method.Emit(OpCodes.Ldarg_0); - method.Emit(OpCodes.Ldind_I); - method.Emit(OpCodes.Ldc_I4, iunknownReleaseOffset); - method.Emit(OpCodes.Add); - method.Emit(OpCodes.Ldind_I); - - method.EmitCalli(OpCodes.Calli, CallingConvention.Winapi, typeof(int), new[] { typeof(IntPtr) }); - - method.Emit(OpCodes.Ret); - - return dm.CreateDelegate(); - } - - internal static readonly IntPtr s_nullInterfaceId = GetNullInterfaceId(); - - private static IntPtr GetNullInterfaceId() - { - int size = Marshal.SizeOf(Guid.Empty); - IntPtr ptr = Marshal.AllocHGlobal(size); - for (int i = 0; i < size; i++) - { - Marshal.WriteByte(ptr, i, 0); - } - return ptr; - } - - /// - /// We will emit an indirect call to an unmanaged function pointer from the vtable of the given IDispatch interface pointer. - /// It is not possible to express this in C#. Using an indirect pinvoke call allows us to do our own marshalling. - /// We can allocate the Variant arguments cheaply on the stack. We are relying on the JIT-compiler to do - /// pinvoke-stub-inlining and calling the pinvoke target directly. - /// The alternative of calling via a managed interface declaration of IDispatch would have a performance - /// penalty of going through a CLR stub that would have to re-push the arguments on the stack, etc. - /// Marshal.GetDelegateForFunctionPointer could be used here, but its too expensive (~2000 instructions on x86). - /// - private delegate int IDispatchInvokeDelegate( - IntPtr dispatchPointer, - int memberDispId, - ComTypes.INVOKEKIND flags, - ref ComTypes.DISPPARAMS dispParams, - out Variant result, - out ExcepInfo excepInfo, - out uint argErr - ); - - private static readonly IDispatchInvokeDelegate s_iDispatchInvoke = Create_IDispatchInvoke(true); - private static IDispatchInvokeDelegate s_iDispatchInvokeNoResultImpl; - - private static IDispatchInvokeDelegate _IDispatchInvokeNoResult - { - get - { - if (s_iDispatchInvokeNoResultImpl == null) - { - lock (s_iDispatchInvoke) - { - if (s_iDispatchInvokeNoResultImpl == null) - { - s_iDispatchInvokeNoResultImpl = Create_IDispatchInvoke(false); - } - } - } - return s_iDispatchInvokeNoResultImpl; - } - } - - private static IDispatchInvokeDelegate Create_IDispatchInvoke(bool returnResult) - { - const int dispatchPointerIndex = 0; - const int memberDispIdIndex = 1; - const int flagsIndex = 2; - const int dispParamsIndex = 3; - const int resultIndex = 4; - const int exceptInfoIndex = 5; - const int argErrIndex = 6; - Debug.Assert(argErrIndex + 1 == typeof(IDispatchInvokeDelegate).GetMethod(nameof(IDispatchInvokeDelegate.Invoke)).GetParameters().Length); - - Type[] paramTypes = new Type[argErrIndex + 1]; - paramTypes[dispatchPointerIndex] = typeof(IntPtr); - paramTypes[memberDispIdIndex] = typeof(int); - paramTypes[flagsIndex] = typeof(ComTypes.INVOKEKIND); - paramTypes[dispParamsIndex] = typeof(ComTypes.DISPPARAMS).MakeByRefType(); - paramTypes[resultIndex] = typeof(Variant).MakeByRefType(); - paramTypes[exceptInfoIndex] = typeof(ExcepInfo).MakeByRefType(); - paramTypes[argErrIndex] = typeof(uint).MakeByRefType(); - - // Define the dynamic method in our assembly so we skip verification - DynamicMethod dm = new DynamicMethod("IDispatchInvoke", typeof(int), paramTypes, DynamicModule); - ILGenerator method = dm.GetILGenerator(); - - // return functionPtr(...) - - EmitLoadArg(method, dispatchPointerIndex); - EmitLoadArg(method, memberDispIdIndex); - - // burn the address of our empty IID in directly. This is never freed, relocated, etc... - // Note passing this as a Guid directly results in a ~30% perf hit for IDispatch invokes so - // we also pass it directly as an IntPtr instead. - if (IntPtr.Size == 4) - { - method.Emit(OpCodes.Ldc_I4, UnsafeMethods.s_nullInterfaceId.ToInt32()); // riid - } - else - { - method.Emit(OpCodes.Ldc_I8, UnsafeMethods.s_nullInterfaceId.ToInt64()); // riid - } - method.Emit(OpCodes.Conv_I); - - method.Emit(OpCodes.Ldc_I4_0); // lcid - EmitLoadArg(method, flagsIndex); - - EmitLoadArg(method, dispParamsIndex); - method.Emit(OpCodes.Conv_I); - - if (returnResult) - { - EmitLoadArg(method, resultIndex); - method.Emit(OpCodes.Conv_I); - } - else - { - method.Emit(OpCodes.Ldsfld, typeof(IntPtr).GetField(nameof(IntPtr.Zero))); - } - EmitLoadArg(method, exceptInfoIndex); - method.Emit(OpCodes.Conv_I); - EmitLoadArg(method, argErrIndex); - method.Emit(OpCodes.Conv_I); - - // functionPtr = *(IntPtr*)(*(dispatchPointer) + VTABLE_OFFSET) - int idispatchInvokeOffset = ((int)IDispatchMethodIndices.IDispatch_Invoke) * Marshal.SizeOf(typeof(IntPtr)); - EmitLoadArg(method, dispatchPointerIndex); - method.Emit(OpCodes.Ldind_I); - method.Emit(OpCodes.Ldc_I4, idispatchInvokeOffset); - method.Emit(OpCodes.Add); - method.Emit(OpCodes.Ldind_I); - - Type[] invokeParamTypes = new Type[] { - typeof(IntPtr), // dispatchPointer - typeof(int), // memberDispId - typeof(IntPtr), // riid - typeof(int), // lcid - typeof(ushort), // flags - typeof(IntPtr), // dispParams - typeof(IntPtr), // result - typeof(IntPtr), // excepInfo - typeof(IntPtr), // argErr - }; - method.EmitCalli(OpCodes.Calli, CallingConvention.Winapi, typeof(int), invokeParamTypes); - - method.Emit(OpCodes.Ret); - return dm.CreateDelegate(); - } - #endregion } } From 290bc3a244485529bd3ea32d985e510f5f5a9f73 Mon Sep 17 00:00:00 2001 From: Maxim Lipnin Date: Wed, 22 Jul 2020 17:45:43 +0300 Subject: [PATCH 080/458] [wasm] Enable System.Linq.Expressions.Tests test suite (#39772) --- src/libraries/System.Linq.Expressions/tests/Call/CallTests.cs | 1 + .../tests/IndexExpression/IndexExpressionTests.cs | 1 + .../tests/Variables/RuntimeVariablesTests.cs | 2 ++ src/libraries/tests.proj | 1 - 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Linq.Expressions/tests/Call/CallTests.cs b/src/libraries/System.Linq.Expressions/tests/Call/CallTests.cs index 43e504c46dfe7f..67eb00e82e3ac3 100644 --- a/src/libraries/System.Linq.Expressions/tests/Call/CallTests.cs +++ b/src/libraries/System.Linq.Expressions/tests/Call/CallTests.cs @@ -290,6 +290,7 @@ public static IEnumerable Call_NoParameters_TestData() [Theory] [PerCompilationType(nameof(Call_NoParameters_TestData))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/39771", TestPlatforms.Browser)] public static void Call_NoParameters(Expression instance, MethodInfo method, object expected, bool useInterpreter) { Expression call = Expression.Call(instance, method); diff --git a/src/libraries/System.Linq.Expressions/tests/IndexExpression/IndexExpressionTests.cs b/src/libraries/System.Linq.Expressions/tests/IndexExpression/IndexExpressionTests.cs index 438bdf04ea701c..37b48b8270549b 100644 --- a/src/libraries/System.Linq.Expressions/tests/IndexExpression/IndexExpressionTests.cs +++ b/src/libraries/System.Linq.Expressions/tests/IndexExpression/IndexExpressionTests.cs @@ -654,6 +654,7 @@ public void UnreadableIndex() [Theory, ClassData(typeof(CompilationTypes))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/39771", TestPlatforms.Browser)] public static void ConstrainedVirtualCall(bool useInterpreter) { // Virtual call via base declaration to valuetype. diff --git a/src/libraries/System.Linq.Expressions/tests/Variables/RuntimeVariablesTests.cs b/src/libraries/System.Linq.Expressions/tests/Variables/RuntimeVariablesTests.cs index 9f843394d734da..cc514e6c4bc326 100644 --- a/src/libraries/System.Linq.Expressions/tests/Variables/RuntimeVariablesTests.cs +++ b/src/libraries/System.Linq.Expressions/tests/Variables/RuntimeVariablesTests.cs @@ -52,6 +52,7 @@ public void IRuntimeVariablesListChecksBounds(bool useInterpreter) [Theory] [ClassData(typeof(CompilationTypes))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/39771", TestPlatforms.Browser)] public void ReadAndWriteVars(bool useInterpreter) { ParameterExpression x = Expression.Variable(typeof(int)); @@ -82,6 +83,7 @@ public void ReadAndWriteVars(bool useInterpreter) [Theory] [ClassData(typeof(CompilationTypes))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/39771", TestPlatforms.Browser)] public void AliasingAllowed(bool useInterpreter) { ParameterExpression x = Expression.Variable(typeof(int)); diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index 871aae867b8bd8..98273a01002a84 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -30,7 +30,6 @@ - From 90a31ee2675d85dd50d3727085891940e841c805 Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Wed, 22 Jul 2020 12:16:51 -0400 Subject: [PATCH 081/458] Fix some scenarios for DynamicRevocationTests on macOS. --- .../X509Certificates/CertificateAuthority.cs | 2 +- .../RevocationTests/DynamicRevocationTests.cs | 28 ++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/CertificateAuthority.cs b/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/CertificateAuthority.cs index f619379b0f812c..84a2607e002e5f 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/CertificateAuthority.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/CertificateAuthority.cs @@ -488,7 +488,7 @@ byKey [2] KeyHash } } } - writer.WriteGeneralizedTime(now); + writer.WriteGeneralizedTime(now, omitFractionalSeconds: true); using (writer.PushSequence()) { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/DynamicRevocationTests.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/DynamicRevocationTests.cs index 8e720bec8a2f15..ac869243d76e95 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/DynamicRevocationTests.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/RevocationTests/DynamicRevocationTests.cs @@ -11,7 +11,6 @@ namespace System.Security.Cryptography.X509Certificates.Tests.RevocationTests { [OuterLoop("These tests run serially at about 1 second each, and the code shouldn't change that often.")] - [ActiveIssue("https://github.com/dotnet/runtime/issues/31249", TestPlatforms.OSX)] public static class DynamicRevocationTests { // The CI machines are doing an awful lot of things at once, be generous with the timeout; @@ -20,6 +19,8 @@ public static class DynamicRevocationTests private static readonly Oid s_tlsServerOid = new Oid("1.3.6.1.5.5.7.3.1", null); private static readonly X509ChainStatusFlags ThisOsRevocationStatusUnknown = + PlatformDetection.IsOSX ? + X509ChainStatusFlags.RevocationStatusUnknown : X509ChainStatusFlags.RevocationStatusUnknown | X509ChainStatusFlags.OfflineRevocation; @@ -57,6 +58,16 @@ public static IEnumerable AllViableRevocation continue; } + // https://github.com/dotnet/runtime/issues/31249 + // not all scenarios are working on macOS. + if (PlatformDetection.IsOSX) + { + if (!endEntityRevocation.HasFlag(PkiOptions.EndEntityRevocationViaOcsp)) + { + continue; + } + } + yield return new object[] { designationOptions | issuerRevocation | endEntityRevocation }; } } @@ -83,6 +94,7 @@ public static void NothingRevoked(PkiOptions pkiOptions) [Theory] [MemberData(nameof(AllViableRevocation))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/31249", TestPlatforms.OSX)] public static void RevokeIntermediate(PkiOptions pkiOptions) { SimpleTest( @@ -129,6 +141,7 @@ public static void RevokeEndEntity(PkiOptions pkiOptions) [Theory] [MemberData(nameof(AllViableRevocation))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/31249", TestPlatforms.OSX)] public static void RevokeIntermediateAndEndEntity(PkiOptions pkiOptions) { SimpleTest( @@ -157,6 +170,7 @@ public static void RevokeIntermediateAndEndEntity(PkiOptions pkiOptions) [Theory] [MemberData(nameof(AllViableRevocation))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/31249", TestPlatforms.OSX)] public static void RevokeRoot(PkiOptions pkiOptions) { SimpleTest( @@ -193,6 +207,7 @@ public static void RevokeRoot(PkiOptions pkiOptions) [Theory] [MemberData(nameof(AllViableRevocation))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/31249", TestPlatforms.OSX)] public static void RevokeRootAndEndEntity(PkiOptions pkiOptions) { SimpleTest( @@ -227,6 +242,7 @@ public static void RevokeRootAndEndEntity(PkiOptions pkiOptions) [Theory] [MemberData(nameof(AllViableRevocation))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/31249", TestPlatforms.OSX)] public static void RevokeRootAndIntermediate(PkiOptions pkiOptions) { SimpleTest( @@ -262,6 +278,7 @@ public static void RevokeRootAndIntermediate(PkiOptions pkiOptions) [Theory] [MemberData(nameof(AllViableRevocation))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/31249", TestPlatforms.OSX)] public static void RevokeEverything(PkiOptions pkiOptions) { SimpleTest( @@ -384,6 +401,7 @@ public static void RevokeEndEntity_IssuerUnrelatedOcsp(PkiOptions pkiOptions) [Theory] [InlineData(PkiOptions.OcspEverywhere)] [InlineData(PkiOptions.IssuerRevocationViaOcsp | PkiOptions.AllEndEntityRevocation)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/31249", TestPlatforms.OSX)] public static void RevokeEndEntity_RootUnrelatedOcsp(PkiOptions pkiOptions) { SimpleTest( @@ -472,6 +490,7 @@ public static void RevokeEndEntity_RootUnrelatedOcsp(PkiOptions pkiOptions) [InlineData(false, true)] [InlineData(true, false)] [InlineData(true, true)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/31249", TestPlatforms.OSX)] public static void RevokeIntermediate_PolicyErrors_NotTimeValid(bool policyErrors, bool notTimeValid) { SimpleTest( @@ -558,6 +577,7 @@ public static void RevokeIntermediate_PolicyErrors_NotTimeValid(bool policyError [InlineData(false, true)] [InlineData(true, false)] [InlineData(true, true)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/31249", TestPlatforms.OSX)] public static void RevokeEndEntity_PolicyErrors_NotTimeValid(bool policyErrors, bool notTimeValid) { SimpleTest( @@ -639,6 +659,7 @@ public static void RevokeEndEntity_PolicyErrors_NotTimeValid(bool policyErrors, [Theory] [MemberData(nameof(AllViableRevocation))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/31249", TestPlatforms.OSX)] public static void RevokeEndEntity_RootRevocationOffline(PkiOptions pkiOptions) { BuildPrivatePki( @@ -712,6 +733,7 @@ public static void RevokeEndEntity_RootRevocationOffline(PkiOptions pkiOptions) [Theory] [MemberData(nameof(AllViableRevocation))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/31249", TestPlatforms.OSX)] public static void NothingRevoked_RootRevocationOffline(PkiOptions pkiOptions) { BuildPrivatePki( @@ -798,6 +820,7 @@ public static void RevokeEndEntityWithInvalidRevocationSignature(PkiOptions pkiO [Theory] [MemberData(nameof(AllViableRevocation))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/31249", TestPlatforms.OSX)] public static void RevokeIntermediateWithInvalidRevocationSignature(PkiOptions pkiOptions) { SimpleTest( @@ -826,6 +849,7 @@ public static void RevokeEndEntityWithInvalidRevocationName(PkiOptions pkiOption [Theory] [MemberData(nameof(AllViableRevocation))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/31249", TestPlatforms.OSX)] public static void RevokeIntermediateWithInvalidRevocationName(PkiOptions pkiOptions) { SimpleTest( @@ -863,6 +887,7 @@ public static void RevokeEndEntityWithExpiredRevocation(PkiOptions pkiOptions) [Theory] [MemberData(nameof(AllViableRevocation))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/31249", TestPlatforms.OSX)] public static void RevokeIntermediateWithExpiredRevocation(PkiOptions pkiOptions) { SimpleTest( @@ -903,6 +928,7 @@ public static void CheckEndEntityWithExpiredRevocation(PkiOptions pkiOptions) [Theory] [MemberData(nameof(AllViableRevocation))] + [ActiveIssue("https://github.com/dotnet/runtime/issues/31249", TestPlatforms.OSX)] public static void CheckIntermediateWithExpiredRevocation(PkiOptions pkiOptions) { SimpleTest( From 8ddc9456665b3decba81fd348e571e7d2b28b18d Mon Sep 17 00:00:00 2001 From: Kevin Jones Date: Wed, 22 Jul 2020 12:18:14 -0400 Subject: [PATCH 082/458] Allow higher iteration counts for PBES2 --- .../Cryptography/PasswordBasedEncryption.cs | 16 +--- .../DSA/DSAKeyFileTests.cs | 41 +++++++++ .../EC/ECKeyFileTests.cs | 35 ++++++++ .../RSA/RSAKeyFileTests.cs | 73 ++++++++++++++++ .../tests/Pkcs12/Pkcs12Documents.cs | 86 +++++++++++++++++++ .../tests/Pkcs12/Pkcs12InfoTests.cs | 61 +++++++++++++ 6 files changed, 299 insertions(+), 13 deletions(-) diff --git a/src/libraries/Common/src/System/Security/Cryptography/PasswordBasedEncryption.cs b/src/libraries/Common/src/System/Security/Cryptography/PasswordBasedEncryption.cs index aad2de80b86fc3..07459e85f6f4bb 100644 --- a/src/libraries/Common/src/System/Security/Cryptography/PasswordBasedEncryption.cs +++ b/src/libraries/Common/src/System/Security/Cryptography/PasswordBasedEncryption.cs @@ -863,7 +863,7 @@ private static unsafe int Pkcs12PbeDecrypt( algorithmIdentifier.Parameters.Value, AsnEncodingRules.BER); - int iterationCount = NormalizeIterationCount(pbeParameters.IterationCount); + int iterationCount = NormalizeIterationCount(pbeParameters.IterationCount, IterationLimit); Span iv = stackalloc byte[cipher.BlockSize / 8]; Span key = stackalloc byte[cipher.KeySize / 8]; ReadOnlySpan saltSpan = pbeParameters.Salt.Span; @@ -1070,19 +1070,9 @@ internal static void WritePbeAlgorithmIdentifier( writer.PopSequence(); } - internal static int NormalizeIterationCount(uint iterationCount) - { - if (iterationCount == 0 || iterationCount > IterationLimit) - { - throw new CryptographicException(SR.Argument_InvalidValue); - } - - return (int)iterationCount; - } - - internal static int NormalizeIterationCount(int iterationCount) + internal static int NormalizeIterationCount(int iterationCount, int? iterationLimit = null) { - if (iterationCount <= 0 || iterationCount > IterationLimit) + if (iterationCount <= 0 || (iterationLimit.HasValue && iterationCount > iterationLimit.Value)) { throw new CryptographicException(SR.Argument_InvalidValue); } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DSA/DSAKeyFileTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DSA/DSAKeyFileTests.cs index 18f8aed713c8b0..97ff89830817cb 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DSA/DSAKeyFileTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/DSA/DSAKeyFileTests.cs @@ -562,6 +562,47 @@ public static void DecryptPkcs12WithBytes() } } + [Fact] + public static void DecryptPkcs12PbeTooManyIterations() + { + // pbeWithSHAAnd3-KeyTripleDES-CBC with 600,001 iterations + byte[] high3DesIterationKey = Convert.FromBase64String(@" +MIIBezAlBgoqhkiG9w0BDAEDMBcEEDH/8QAPoG1utiuJkzA4u4kCAwknwQSCAVD9BOoJTlihH9zP +0AmAXtBa7fjJGnq4tZBJSYmJbNxszTSvM3tEkzyiqFWd6Ptm9bf0cOybad2LXIWnrtlIclGD0ibH +earAf1YvAIBFlbDXfVF8v5//XL2R1d8kcp4fqTVKdRunTSvPS0rIFP5Mrfj89WacHO3HQOB6UMMT +ZYSdI3qZj+6Rlo0a7/MEO23Y0zR9XLdUhyra+UixzVi05VslPoWn1dsFksbklwtV+IRJ9biMjCta +8fr3uqHmtb57121dA3p4A2dya8bgcHOJlMPsYxJ012GV4twULSyaZz6hXOzVh3AL5uLlrzSkV7ZQ +dkOGlpaaJkhGKtkfxRe82w3ZXhuLsVt3vPciDbbF5hIDf8JX7X1aANq5Ka9Tcs3Lyd/FVdkceqn7 +KaC843/LqYiSNoD7rBPpSpkyLtldwhqc7o2Wz7tyb1Oj8WF47AJD5OI="); + + using (DSA key = DSAFactory.Create()) + { + Assert.ThrowsAny( + () => key.ImportEncryptedPkcs8PrivateKey("test", high3DesIterationKey, out _)); + } + } + + [Fact] + public static void ReadWriteDsa1024EncryptedPkcs8_Pbes2HighIterations() + { + // pkcs5PBES2 hmacWithSHA256 aes128-CBC with 600,001 iterations + ReadBase64EncryptedPkcs8(@" +MIIBtjBgBgkqhkiG9w0BBQ0wUzAyBgkqhkiG9w0BBQwwJQQQ+ZTlQ9PG0lKomeY4b7lpZgIDCSfB +MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAECBBDoHELpGkGH/pPcq1/id3l4BIIBUHF74QMFkUdy +XZiUndRy+u2d5KNct89WYj8b3Fb7/VTZQwWRfoIZbC2Of769SMvd2R1ViWNG/ZPX7gxZ2keHFiNL +v/Dj6sNdfFGDF8RyPGOzFQSYu/PYteCHMCh4cYtLQqaGARbKQ1R46dfSyBgQ8IFh9Mnz7T57wSSt +Af3nJkTjfvS28hjtErrufv0XrLCy95+K/fX80GicWuAsC/sLDbbMiiKWzOlLhug4uX5/gSRM3Oqy +LGssZuyeza1fTIgU8NjijYQ/kJJUwEWjjn1PA7BWtDWYaqG5wLyz6z50S6pbpLRelvxV5s9dX1Yq +aylTdOmNGHG+7yEVFQ+sgvJJVIG9mz+YP9tBbzm65UvbzPrXSvNldgm2XUF0Z8LZMRqrurKLYjLE ++TA4wBPaTRUeF0/9Sgk7MXcKHEjhG+OlTP9MExv6Wq3mIREamzu+EtVcPg==", + "test", + new PbeParameters( + PbeEncryptionAlgorithm.Aes128Cbc, + HashAlgorithmName.SHA256, + 600_001), + DSATestData.GetDSA1024Params()); + } + private static void ReadBase64EncryptedPkcs8( string base64EncPkcs8, string password, diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/ECKeyFileTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/ECKeyFileTests.cs index 4fd534e937a1d2..4775d6b0013c1f 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/ECKeyFileTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/ECKeyFileTests.cs @@ -951,6 +951,41 @@ public void DecryptPkcs12WithBytes() } } + [Fact] + public void DecryptPkcs12PbeTooManyIterations() + { + // pbeWithSHAAnd3-KeyTripleDES-CBC with 600,001 iterations + byte[] high3DesIterationKey = Convert.FromBase64String(@" +MIG6MCUGCiqGSIb3DQEMAQMwFwQQWOZyFrGwhyGTEd2nbKuLSQIDCSfBBIGQCgPLkx0OwmK3lJ9o +VAdJAg/2nvOhboOHciu5I6oh5dRkxeDjUJixsadd3uhiZb5v7UgiohBQsFv+PWU12rmz6sgWR9rK +V2UqV6Y5vrHJDlNJGI+CQKzOTF7LXyOT+EqaXHD+25TM2/kcZjZrOdigkgQBAFhbfn2/hV/t0TPe +Tj/54rcY3i0gXT6da/r/o+qV"); + + using (T key = CreateKey()) + { + Assert.ThrowsAny( + () => key.ImportEncryptedPkcs8PrivateKey("test", high3DesIterationKey, out _)); + } + } + + [Fact] + public void ReadWriteEc256EncryptedPkcs8_Pbes2HighIterations() + { + // pkcs5PBES2 hmacWithSHA256 aes128-CBC with 600,001 iterations + ReadWriteBase64EncryptedPkcs8(@" +MIH1MGAGCSqGSIb3DQEFDTBTMDIGCSqGSIb3DQEFDDAlBBA+rne0bUkwr614vLfQkwO4AgMJJ8Ew +DAYIKoZIhvcNAgkFADAdBglghkgBZQMEAQIEEIm3c9r5igQ9Vlv1mKTZYp0EgZC8KZfmJtfYmsl4 +Z0Dc85ugFvtFHVeRbcvfYmFns23WL3gpGQ0mj4BKxttX+WuDk9duAsCslNLvXFY7m3MQRkWA6QHT +A8DiR3j0l5TGBkErbTUrjmB3ftvEmmF9mleRLj6qEYmmKdCV2Tfk1YBOZ2mpB9bpCPipUansyqWs +xoMaz20Yx+2TSN5dSm2FcD+0YFI=", + "test", + new PbeParameters( + PbeEncryptionAlgorithm.Aes128Cbc, + HashAlgorithmName.SHA256, + 600_001), + EccTestData.GetNistP256ReferenceKey()); + } + private void ReadWriteBase64EncryptedPkcs8( string base64EncryptedPkcs8, string password, diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyFileTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyFileTests.cs index 35b50774b15670..f2a79bcc72904f 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyFileTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/RSA/RSAKeyFileTests.cs @@ -1248,6 +1248,79 @@ public static void DecryptPkcs12WithBytes() } } + [Fact] + public static void DecryptPkcs12PbeTooManyIterations() + { + // pbeWithSHAAnd3-KeyTripleDES-CBC with 600,001 iterations + byte[] high3DesIterationKey = Convert.FromBase64String(@" +MIIE8zAlBgoqhkiG9w0BDAEDMBcEELqdfpwjkWlJZnr3xs2n+qACAwknwQSCBMgnZse/OHib1lMC +jBuUdjQCib5+HEBd2PwrjRw8k/i3kOsPeuDRsTMVvqumYpN6frYWLxRSbd3oe7n5D6bxpBrGuhfO +d/98Ustg1BDXPSdJzOyCXjS4nm+pr5ZETXxM8HUISvmpC62mrBJue3JwHVXbpXFepMcy9ywfSfjg +GhNzSYPQwHLFLVHVd3Dcb8mApgVf9aMJIjw9SeE9KQ6PeOk1LXQsoMFf3h/Sap/nuR4M9F/qa9u/ +SEtjptJRlRDecXhQLS7su6cjQ/3Z5PQObORlqF2RASOaEYRyrjjvQjH0+ZAIkQ6zyv1PrPpbeT9I +U5Hzlu00hfNyAy3TfR50EqT2jP7D6ugFbvnHoDRx0e3STTgBrfFc1tbdLijnq/rxb4QNBIV70+Kw +QL2mc8CdM/lP4hT4f1vdtgLdRF2gmxndZolveNc5nAheUwqNa8I16OzZnny9090KztJxhGWd57H8 +QCvz2mS6z7FANeyo9cTZilHwwErkLUgmoaQXnnrs46VwF8oeH9ZhLiO4W+OfNLm6QvB/e3/inUj/ +FZFxnTYCvSeRBTD5YhME+SnyGPbJiHOPJuSIwWXyRpZeg6wmMWfduEeGuThNNSf4Fxm0baFrC6CZ +4+jT0CurP6L4NxLPBafWP7BcA2XCeVQGQd1GT9cX2I1NkRcU7Q2u7oxWKMJaj0OELC+lZTTv6y3Q +x3I96z0Eddm1qfKQr9HQq+i8LXMwSxqNH+LOtdOEA3kqYq4GU6MdPr8Nx1TaGsiwLcz14GqPl3UQ +5so2ZKHZZsa9NSer/fWVaOwmYc50JW3N4jJpDFRjKVFP5GSzLfdTwl9nduM4atu4D9KZthQCwNGC +nEZ1nwGJywmO/XvLWopOMj0cUx2GQYOUV2Hfu93+MriiKjTFEnMcT7B/BOFRpgz4jg4S+6DcHwJh +cpdIvViajQXM3WwpxnVzskAxYNTYGV0aI9ZjrGBD4vZXM1s9hTlAZc41EmTqZlJPNZ75OzKD9LJS +Iot/jiWjJ03+WT8VVqw/mfTSy2apCE3pGGKdde6wlcR/N6JI1+lQahC+0j9yvUCZyqhiiVpcwaOa +dsxxZMJ+DiilMuRXMJCxKvx5kBZTpjuKR/WnKzSE70wgB1ulJE0RkZTYjWSUSf54bHC2XRGZLtfU +sXDcycjA33H+b0cxe25OZNJUTOoFJqji9RqBvzHuAVMXJvZESORMKbl6q47DbWwFvivfweUJNVO+ +3fzCcrCfAFLwI0j+KaoVr0Qrfedr7OhVEZ/v57aYidUSl2VIpLmpJTUKRnvZ0rlg/WBauwWH1X4M +u7AExd+aHO8iv0gj+rTg5co0EcOu9i8cbAowg1ZZ1m6zXvHD7fZgE9iamBmklVOQwQXOJO7BCecn +C0ezYU4Ii8uo0fXJOMWkIA7KLGaQxBrxygnFK3A0RKNos7OXiLdB8RGDqjUZyqLUb3z/YisQEX8f +R40NElq8tzOa/TudOpNAqC8mgS25uTm7ws472gUE0z9uvcq1/MgkqE++xgmLAxGUN/l7EHSAmYKG +i33DDR38LaRqG9ho3brf466OkNooBv4MpD5SA63yfooytxOgeuaqbuTzKP/OSRqJNab9wctA9nfJ +gms2YM+honjUS1sXk1zdm/8="); + + using (RSA key = RSAFactory.Create()) + { + Assert.ThrowsAny( + () => key.ImportEncryptedPkcs8PrivateKey("test", high3DesIterationKey, out _)); + } + } + + [Fact] + public static void ReadWriteRsa2048EncryptedPkcs8_Pbes2HighIterations() + { + // pkcs5PBES2 hmacWithSHA256 aes128-CBC with 600,001 iterations + ReadBase64EncryptedPkcs8(@" +MIIFNjBgBgkqhkiG9w0BBQ0wUzAyBgkqhkiG9w0BBQwwJQQQAx6OUUzmK+vwC7a+OwhXygIDCSfB +MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAECBBCoLaQQpG01FJnpQdIRq2ioBIIE0MPy/p2uwTnP +mScPxFbrpBiPQHz5PKRjKLCN5JLArsppSz+XSHxfItFUSfBKEE7dYJrEXARmhA8e2roCrZkQnb9o +TX551EivHZhqmd91p6WHYb3ZCDQ6la1JfiuV4aJiJOlG0bDAkzEaiM9m9LE3G0J3Z3ELX+mGEGKD +W+Bz1a9jr204IJQc2VihTFe5t3mujV3X9UFZH3kqOCEreVVmmD64Ea2uDJ6dk3VgGhQ9QLjTDjc5 +OSjdfuyuA4gliK/7ibFubtmnVTDSbAm5Excy9tvJqVhejv/wRhfeYZ2rpv3tTLP58WKt25GEmyyV +j86v3LB7DFnnBy4NkLCE55oVe64v/8StyEjEkMxz7Owz/ZW65EccPdk7JHZeBXPXNUdLxk1x40vW +nSRzqhLckfggDwtTCk0kwGUNGBMqr2ezXKrSeO3Qj05dAUvFt9PvbnrVtSnOjFPwx0exiDMUxOFE +Sz63M2tNNAJr43w60DXaIvMMoZ1kF1mwwL5GT+cs3Dn5KFHNLkZ5irIoHAkmKRHplI15Oqr+Ws2n +MUtV9BjDjtYHlwp1s1oFpHr9hu8HHv7QIEvyZbyMdKfPv9PEaNJR0SRhkyave+vl9zHCBhP1H2wU +4fESU1y+cJXZ5WUiJZ5C1wDYWyN5Q2z67Fd4OQXhRwHCeTCZPz3bykpadwlsihCNHrYybfLn61oz +2CswZjBeQuhDmUKWaj87fsNvSEHaEGTDnyLGEzgNb1OuIrqGiT0DvjfRsVED4ZL6jlDKgAaJe+Uq +EMt1UzKmAPeBA/IFOrNPw5B+rgKjVpsCdToX9I9b3cCvKhjxguuggpzkEOF4cdgR2MJk1mqdo7ck +2fI2A5kJx9SuEVL6eKqxyFkPdBMmljKyhomAjdBAIKQ4xt2ojEip7Q9qhmWK3U3meOiIc3qrsM/K +pGDiwH1CHc/0FbHAghiARawXAtzGGyfMXsZkUTAVnEqDfu5uw4pOlv+rm5GLWfLU8p73yc+kVfPR +MdWZI6Ftct0FP/KEibc6VSaENoVRAk+XApadkeFaEUQzFzoU7RhN9FONmnCL8Ui76Kfi1kLAxYJo +rXFQjatiLOAxV50uJSkE1ppmrU1YWHVyC3RkLLnQfq0Ypz9/x7W4PVDfCJQdnCCtOfHL5Qm8fL0l +uE22Y+gPDzoM1BEKvSgmZWTlZrovXwL4u70/nPeaB1HAVUEzsoEMOSSWDkHuhmgiZHUgQwkvzNjA +I3AJk0rl2tGBWdgsDtiiQamkXm0VwubTedIt2vj9h9kJYtUlvkCg7KfKxmTSJUynOyKfI1Mhx3vW +fvni4lYc7KLUEkcNMqNu5AliaPEJQksNNkRiyX7wK5TvA+v9mlqm6Gg7GuJ2oa1DiFf8MUB9CgiJ +pniangzMBkuSd+zvCAo9YAJoyrJoR2ibcWwo4wRSVwYsVF3bB4nB2w1GHQ6HAnPKHSjVDJZyoEh6 +TvoFEWjb86tn2BR+qMKqXNBVSrgF2pa06BIs0daHKimYKaU0bnuzE/T+pckJfI0VvWB/Z8jvE1Xy +gpX/dwXfODsj4zcOw4gyP70lDxUWLEPtxhS5Ti0FEuge1XKn3+GOp3clVjGpXKpJTNLsPA/wlqlo +8/ojymwPxe641Pcfa4DsMgfleHnUOEbNZ4je", + "test", + new PbeParameters( + PbeEncryptionAlgorithm.Aes128Cbc, + HashAlgorithmName.SHA256, + 600_001), + TestData.RSA2048Params); + } + private static void ReadBase64EncryptedPkcs8( string base64EncPkcs8, string password, diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs12/Pkcs12Documents.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs12/Pkcs12Documents.cs index 550ee41b80a510..0fc7f919bbd769 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs12/Pkcs12Documents.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs12/Pkcs12Documents.cs @@ -136,6 +136,92 @@ internal static class Pkcs12Documents "21300906052B0E03021A050004148B12EE39C54B03EF4C1B0C2D8A3A9624D629" + "285A0408E398C69C57E4782102020400").HexToByteArray(); + internal static readonly ReadOnlyMemory HighPbeIterationCount3Des = ( + "308209c40201033082098906092a864886f70d010701a082097a04820976" + + "308209723082043006092a864886f70d010706a08204213082041d020100" + + "3082041606092a864886f70d010701301d060a2a864886f70d010c010330" + + "0f04083fd435a905e8b19e02030927c1808203e8d3a24907621301625ce2" + + "f42b8dd0fc0c0ce57d512af3275af385874b01adf017de2a9c6fa5c78c15" + + "729453073d0dbc11e4c9dcc6d01f332bd06a5786962b85dfd4becca62619" + + "efd189ddb4b1abc109983a8cd4c41958a4dcce10e34a70f39b742d892bd6" + + "94a4f2b6fc1b760e08b81fe38b3e9c25cf81acb3e30e59d4608f104fd911" + + "a123b15d0c93a9b96e99f72ad50faac027bdccc121abdeb61e9bec4e6969" + + "08a6480ae693e956fb006213cd9fa5c492665439c5a436d4b5ca8d8f382a" + + "2b54dcc12c6ea3a44b819eb2c85c20a0dfdd623f3235e3b13c6856cd538d" + + "edeeb71bc078d7e8d13b4fad0f809925aa93a7bb288ba07562723580d2e1" + + "d34d83398d31205cf00b8e406898e922f2ac9aa8d0135b268944c17423ce" + + "4887ac3068838b0a5cfadd308d10787aaa24683be495ced256ef4ebd8e16" + + "60b0fe942793ec66c669a273417cf20be43ae7d7c56665803c653b8f00b5" + + "f0963e72d23d0db6a0a0182662f7d88ff832b10498b6d557bb4a8bf2f0cd" + + "8b89e0865102ca9cbe0a5c5eef55530fbdd92389a6911769b870c2a83a0b" + + "c8b6f4afdba398d88d36fc8b1995da29c9b0f437e8959a8fd9a9dec621e9" + + "ee0fb6181b904f936abcdede183e7668e9c09f0d9565c055a3542ebd8414" + + "c96797afdf98f63730bd6840018fb30d974cc5c5bc538b05699ef4119653" + + "ac2189b917ff15409fc449bf72eda1b551bdc7cee240e8b22ac3391ae148" + + "37870aaba99a78b84c47ed2c0788dd60dbc0bfd1498651ba1a8a07f26bb0" + + "0ab4002ca865b45301a38c353a3a1a6c1d7a2b7870770707312e68200f80" + + "9c583595b3c3a7fb9ceed6ef2d2b953d8543d554459a226605757c64f93a" + + "fa6bedeb63f49d9642aedd71f0678f1aa50c3130a2577e73896e6cf5680e" + + "e32c25f615c4578b736193da4b9a1e55371083713bcc84ad4a6665535725" + + "1fffb3656ce306070381b3dabe23dfd22ed1af0ac2c8494a9c98a69db00c" + + "b728b56c6c1acd8518f11541aa75ee62a7bf74140527217279f113c2d737" + + "4e876b9b2624f6f3599a3db16bab5e5b8dd888a2e3fff5c4dc9ddd7ed100" + + "dc2a56ea3c57ad4811cae5fe21e704bb1480768353364a56bc6e7baf0105" + + "d3a3a97e16591257d5e1a06d3d8a3e2e1b7444b240d77de4704cd402f9d3" + + "1b005e799d29d4b139e07e9e0b322f153dff2216e390496025ed85501ca7" + + "83f41063ad3f62f71e2d40856e39f90b74f0b860385083b75fcc34e5e7e4" + + "77e68bc8c8c7ef9f789f85efe9aa170a5e37e43ac42a5d2cc47489d27ee5" + + "03c9a6d19a32c6170643b38c017c31a1d51013f8a86831594432a7c02f80" + + "d656696b5edd6f4d27bc07325b5cfb118b543abc038928f86995fb296630" + + "cbb183d407e8f16b50b2fefd8f21469fc83e45abba920d9a6c88179b023b" + + "3082053a06092a864886f70d010701a082052b0482052730820523308205" + + "1f060b2a864886f70d010c0a0102a08204e7308204e3301d060a2a864886" + + "f70d010c0103300f0408e8dc7d11c3405bae02030927c1048204c0698ab9" + + "d1d3f6a2eab118cf2166f0db512cd132acddbab92807639a08305fde746c" + + "35c512498cd4f656faf165be0f28fafd9f5cbb3b4b3704b16a6de18f7b2f" + + "0950b73db868bec47717b56079c78a3069798e3c40ec6199d55c723c18cd" + + "deb02278c860de652a65f964e6e82a0bd6bc6f94cccad6761dd2afb724db" + + "cecd62eea36b13114f0aa5ea280e4468b433e37b791209cdd7f599ba9dfc" + + "f09c3f9e3781a1ec2712fd24ae8bc75b44e3071331478d112354281b4fe2" + + "4dc3417320514ffcee7e921fac4fb5095aef11e2e60de5f4e51fb3bbf62b" + + "8593502b93e9048d4481ab84a8fa7f9e411a5aa4943d4401f7d8376345d6" + + "eacff571b4e7197eb934640b88d3967651135902f8a4a1ce3f030c68ce24" + + "3616e30eb58d9be9bc256834df10893e88bb1a57948b34b8be8294154492" + + "c84e3e7c931858a48137a8becf5316cb009fe0ed30701952a3b745222d01" + + "b28174896092d2e98e7561bce56a87afe045c4a730380c1e4ed452cdc6d0" + + "c5ddae41d303d0a8ddfecb8b0ee161f13dfc0ebd6b59f923d49e89ac3576" + + "34d16c583865e39b9c0a24f7b7c7baac2cd21cfa77a3342cfd4015a4d4cc" + + "41440d0dc49a9972e2970cffac37f7503d4ec1f546b4144d26802b90b38e" + + "63dc4baec79e439fdfff5133ded301d07fa902790f17ffb471f4f78a5d66" + + "51ac3465f1b8d08060eb5bcc1fe9261176e08bc6c3f6a890614bfd428e9d" + + "04c197241966fa2ce025adc7e89ef3d2384660ef6d05aa1f6d365859f5b3" + + "b3009a8d3f0ee4bf907c6458b6877d63b815b096039603de5a2232588cd5" + + "8c7f1eae5e4bf43495bb208e2b2d9e02ac849c60cc43dab30d5359ec7838" + + "eeb290eb8c98f15b1273c3a82103394175b690b2579ba445a223850a54ef" + + "624e8f481509be45159b5a509d472eaf20248fc30d7945940a3250bd9174" + + "25bc5cae77c3659461fb79fb3a8f09f0f01c49737a6cdb34fa3ca4987bde" + + "2d3e64edd2fc54e86649ba6accc3417764f52f86c67d2aa07869de9191f8" + + "9592d845da1bb23b4bddbd0943fdabd2438e1a5b8dc6ae4a40709a853da9" + + "69a06148045e17ae3b5199d76959f56707770e5b7fe168588c322f4e2afc" + + "05ec72398f3a97a2112729114147613c4578945409295ae9e49c78d6482c" + + "89c4731aa069b4977b66d235830d94d34384ffc0b57460d97fec507d48ff" + + "6da7410d1411926b250fe85e1f7b7260cc2986a2486125d5d9228aa77fb8" + + "a3d4f09ff133d0e58a3878b94c9a0c4fdb0c95a62102aa39f96a15822573" + + "7a40b4f41b3bbe41430d643ae873258a2c8f237de943f9a2c02903ead1cb" + + "9973ad6f39f65f7eb1152aebf1c429db19ecba6d05ed60ec5d4d0bd54222" + + "67d10439876c4cf4966b308c0362cc9b87a94d7de4fee67c2a02f6f6bb0c" + + "b8b9c0dd0fa2163f0039009342476e8e1cb0a5e80bae734ae219322b562c" + + "47eae320687a773c10365e922c9b20e7c3fa1e07ee7b6efdd31bcd1a5cad" + + "a72bf102cbd8d5e193a504d9ce10bbb2c078ce6590276d5bd2136de5a95a" + + "55e11d881ebfb6903df4df5df762833aafb658d7febba3498819dcf2b7af" + + "2e24e4b620b6d91c4d408f86914e15cbb1dfeaea0c1dcf2df85ca4289830" + + "c5a3812e167f75b558fb0c57f9e6864560e81420d7b60de5a554d5dafa11" + + "571868b271733182ea2851de72ce93e353c11bba216990b7181a53c2b3d5" + + "d8e8c019f5f73cdb6a985144ff3125302306092a864886f70d0109153116" + + "04149566f15bed2cb2da568ec392507a9abfcb2920003032302130090605" + + "2b0e03021a05000414c429b968eeca558cc2ec486f89b78c024bdecf2804" + + "087cbeafa8089685a102030927c1").HexToByteArray(); + internal const string OracleWalletPassword = "123Wallet"; } } diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs12/Pkcs12InfoTests.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs12/Pkcs12InfoTests.cs index 45652762123e6c..cb0ad4e0a7c046 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs12/Pkcs12InfoTests.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/Pkcs12/Pkcs12InfoTests.cs @@ -256,5 +256,66 @@ public static void VerifyMacWithNoMac() Assert.Throws(() => info.VerifyMac("hi")); } + + [Theory] + [MemberData(nameof(DecodeWithHighPbeIterationsData))] + public static void DecodeWithHighPbeIterations( + PbeEncryptionAlgorithm encryptionAlgorithm, + HashAlgorithmName hashAlgorithmName, + int iterations) + { + string pw = nameof(CreateAndSealPkcs12); + byte[] data = CreateAndSealPkcs12(encryptionAlgorithm, hashAlgorithmName, iterations); + Pkcs12Info info = Pkcs12Info.Decode(data, out _, skipCopy: true); + info.AuthenticatedSafe.Single().Decrypt(pw); + } + + [Fact] + public static void DecodeWithTooManyPbeIterations() + { + const string pw = "test"; + Pkcs12Info info = Pkcs12Info.Decode(Pkcs12Documents.HighPbeIterationCount3Des, out _, skipCopy: true); + foreach (Pkcs12SafeContents contents in info.AuthenticatedSafe) + { + if (contents.ConfidentialityMode == Pkcs12ConfidentialityMode.None) + { + continue; + } + + Assert.ThrowsAny(() => contents.Decrypt(pw)); + } + } + + public static IEnumerable DecodeWithHighPbeIterationsData + { + get + { + yield return new object[] { PbeEncryptionAlgorithm.Aes128Cbc, HashAlgorithmName.SHA256, 700_000 }; + yield return new object[] { PbeEncryptionAlgorithm.Aes192Cbc, HashAlgorithmName.SHA256, 700_000 }; + yield return new object[] { PbeEncryptionAlgorithm.Aes256Cbc, HashAlgorithmName.SHA256, 700_000 }; + yield return new object[] { PbeEncryptionAlgorithm.TripleDes3KeyPkcs12, HashAlgorithmName.SHA1, 600_000 }; + } + } + + private static byte[] CreateAndSealPkcs12( + PbeEncryptionAlgorithm encryptionAlgorithm, + HashAlgorithmName hashAlgorithmName, + int iterations) + { + PbeParameters pbeParameters = new PbeParameters( + encryptionAlgorithm, + hashAlgorithmName, + iterations); + + using RSA rsa = RSA.Create(); + string pw = nameof(CreateAndSealPkcs12); + Pkcs12Builder builder = new Pkcs12Builder(); + Pkcs12SafeContents contents = new Pkcs12SafeContents(); + contents.AddShroudedKey(rsa, pw, pbeParameters); + builder.AddSafeContentsEncrypted(contents, pw, pbeParameters); + builder.SealWithMac(pw, hashAlgorithmName, iterations); + + return builder.Encode(); + } } } From ea8262910cc1c072e612c6cdd0693e27ea218b92 Mon Sep 17 00:00:00 2001 From: Jose Perez Rodriguez Date: Wed, 22 Jul 2020 10:49:22 -0700 Subject: [PATCH 083/458] Add runtimelab.yml for dotnet/runtimelab experiments CI and build infrastructure (#39749) * Add runtimelab.yml for dotnet/runtimelab experiments CI and build infrastructure * rename one of the ymls based on feedback --- eng/Subsets.props | 2 +- .../templates/runtimes/build-test-job.yml | 6 +- .../templates/runtimes/run-test-job.yml | 23 ++- eng/pipelines/libraries/build-job.yml | 52 +---- .../libraries/prepare-for-bin-publish.yml | 55 ++++++ eng/pipelines/libraries/run-test-job.yml | 18 +- eng/pipelines/runtimelab.yml | 185 ++++++++++++++++++ .../runtimelab-post-build-steps.yml | 59 ++++++ .../corehost/{build.proj => corehost.proj} | 0 src/libraries/libraries-packages.proj | 4 +- .../ICustomMarshaler_TargetWindows.csproj | 2 +- 11 files changed, 337 insertions(+), 69 deletions(-) create mode 100644 eng/pipelines/libraries/prepare-for-bin-publish.yml create mode 100644 eng/pipelines/runtimelab.yml create mode 100644 eng/pipelines/runtimelab/runtimelab-post-build-steps.yml rename src/installer/corehost/{build.proj => corehost.proj} (100%) diff --git a/eng/Subsets.props b/eng/Subsets.props index fa72f142f0c5cd..958389db150f65 100644 --- a/eng/Subsets.props +++ b/eng/Subsets.props @@ -209,7 +209,7 @@ - + diff --git a/eng/pipelines/common/templates/runtimes/build-test-job.yml b/eng/pipelines/common/templates/runtimes/build-test-job.yml index 0f3c188d20e89a..56fa8dffddc1b7 100644 --- a/eng/pipelines/common/templates/runtimes/build-test-job.yml +++ b/eng/pipelines/common/templates/runtimes/build-test-job.yml @@ -22,6 +22,7 @@ parameters: runtimeFlavor: 'coreclr' runtimeFlavorDisplayName: 'CoreCLR' runtimeVariant: '' + dependsOn: [] ### Build managed test components (native components are getting built as part ### of the the product build job). @@ -63,10 +64,13 @@ jobs: # See https://docs.microsoft.com/azure/devops/pipelines/process/conditions condition: and(succeeded(), ${{ parameters.condition }}) + ${{ if ne(parameters.dependsOn[0], '') }}: + dependsOn: ${{ parameters.dependsOn }} + # TODO: Build of managed test components currently depends on the corresponding build job # because it needs System.Private.Corelib; we should be able to remove this dependency # by switching over to using reference assembly. - ${{ if ne(parameters.stagedBuild, true) }}: + ${{ if and(ne(parameters.stagedBuild, true), eq(parameters.dependsOn[0], '')) }}: dependsOn: - ${{ format('coreclr_{0}_product_build_{1}{2}_{3}_{4}', parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, coalesce(parameters.liveRuntimeBuildConfig, parameters.buildConfig)) }} - ${{ if ne(parameters.liveLibrariesBuildConfig, '') }}: diff --git a/eng/pipelines/common/templates/runtimes/run-test-job.yml b/eng/pipelines/common/templates/runtimes/run-test-job.yml index 39616a833b0e4c..4d93701584fe62 100644 --- a/eng/pipelines/common/templates/runtimes/run-test-job.yml +++ b/eng/pipelines/common/templates/runtimes/run-test-job.yml @@ -20,6 +20,7 @@ parameters: pool: '' runtimeFlavor: 'coreclr' runtimeFlavorDisplayName: 'CoreCLR' + dependsOn: [] ### Test run job @@ -47,15 +48,19 @@ jobs: ${{ if eq(variables['System.TeamProject'], 'internal') }}: continueOnError: true - dependsOn: - - ${{ if in(parameters.testGroup, 'innerloop', 'clrinterpreter') }}: - - '${{ parameters.runtimeFlavor }}_common_test_build_p0_AnyOS_AnyCPU_${{parameters.buildConfig }}' - - ${{ if notIn(parameters.testGroup, 'innerloop', 'clrinterpreter') }}: - - '${{ parameters.runtimeFlavor }}_common_test_build_p1_AnyOS_AnyCPU_${{parameters.buildConfig }}' - - ${{ if ne(parameters.stagedBuild, true) }}: - - ${{ format('{0}_{1}_product_build_{2}{3}_{4}_{5}', parameters.runtimeFlavor, parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} - - ${{ if ne(parameters.liveLibrariesBuildConfig, '') }}: - - ${{ format('libraries_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveLibrariesBuildConfig) }} + ${{ if ne(parameters.dependsOn[0], '') }}: + dependsOn: ${{ parameters.dependsOn }} + + ${{ if eq(parameters.dependsOn[0], '') }}: + dependsOn: + - ${{ if in(parameters.testGroup, 'innerloop', 'clrinterpreter') }}: + - '${{ parameters.runtimeFlavor }}_common_test_build_p0_AnyOS_AnyCPU_${{parameters.buildConfig }}' + - ${{ if notIn(parameters.testGroup, 'innerloop', 'clrinterpreter') }}: + - '${{ parameters.runtimeFlavor }}_common_test_build_p1_AnyOS_AnyCPU_${{parameters.buildConfig }}' + - ${{ if ne(parameters.stagedBuild, true) }}: + - ${{ format('{0}_{1}_product_build_{2}{3}_{4}_{5}', parameters.runtimeFlavor, parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} + - ${{ if ne(parameters.liveLibrariesBuildConfig, '') }}: + - ${{ format('libraries_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveLibrariesBuildConfig) }} # Compute job name from template parameters ${{ if in(parameters.testGroup, 'innerloop', 'clrinterpreter') }}: diff --git a/eng/pipelines/libraries/build-job.yml b/eng/pipelines/libraries/build-job.yml index 51dcb37ff23fac..f4b02cf062158d 100644 --- a/eng/pipelines/libraries/build-job.yml +++ b/eng/pipelines/libraries/build-job.yml @@ -99,55 +99,9 @@ jobs: displayName: Disk Usage after Build - ${{ if eq(parameters.runTests, false) }}: - - ${{ if ne(parameters.isOfficialBuild, true) }}: - - task: CopyFiles@2 - displayName: Prepare testhost folder to publish - inputs: - sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/testhost - targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/testhost - - - task: CopyFiles@2 - displayName: Prepare runtime folder to publish - inputs: - sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/runtime - targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/runtime - - - task: CopyFiles@2 - displayName: Prepare ref folder to publish - inputs: - sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/ref - targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/ref - - - task: CopyFiles@2 - displayName: Prepare shared framework ref assemblies to publish - inputs: - sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/ref/microsoft.netcore.app - targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/ref/microsoft.netcore.app - - - task: CopyFiles@2 - displayName: Prepare shared framework runtime folder to publish - inputs: - sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/pkg - targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/pkg - - - task: CopyFiles@2 - displayName: Prepare docs folder to publish - inputs: - sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/docs - targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/docs - - - task: CopyFiles@2 - displayName: Prepare native folder to publish - inputs: - sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/native - targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/native - - - task: CopyFiles@2 - displayName: Prepare artifacts packages folder to publish - inputs: - sourceFolder: $(Build.SourcesDirectory)/artifacts/packages - targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/packages - condition: and(succeeded(), eq(variables['_librariesBuildProducedPackages'], true)) + - template: /eng/pipelines/libraries/prepare-for-bin-publish.yml + parameters: + isOfficialBuild: ${{ parameters.isOfficialBuild }} - template: /eng/pipelines/common/upload-artifact-step.yml parameters: diff --git a/eng/pipelines/libraries/prepare-for-bin-publish.yml b/eng/pipelines/libraries/prepare-for-bin-publish.yml new file mode 100644 index 00000000000000..fa71beaae65fd1 --- /dev/null +++ b/eng/pipelines/libraries/prepare-for-bin-publish.yml @@ -0,0 +1,55 @@ +# Steps used to prepare the Artifacts Staging Directory with required files for +# executing libraries tests as well as shared framework assets +parameters: + isOfficialBuild: '' + +steps: + - ${{ if ne(parameters.isOfficialBuild, true) }}: + - task: CopyFiles@2 + displayName: Prepare testhost folder to publish + inputs: + sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/testhost + targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/testhost + + - task: CopyFiles@2 + displayName: Prepare runtime folder to publish + inputs: + sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/runtime + targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/runtime + + - task: CopyFiles@2 + displayName: Prepare ref folder to publish + inputs: + sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/ref + targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/ref + + - task: CopyFiles@2 + displayName: Prepare shared framework ref assemblies to publish + inputs: + sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/ref/microsoft.netcore.app + targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/ref/microsoft.netcore.app + + - task: CopyFiles@2 + displayName: Prepare docs folder to publish + inputs: + sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/docs + targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/docs + + - task: CopyFiles@2 + displayName: Prepare shared framework runtime folder to publish + inputs: + sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/pkg + targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/pkg + + - task: CopyFiles@2 + displayName: Prepare native folder to publish + inputs: + sourceFolder: $(Build.SourcesDirectory)/artifacts/bin/native + targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/bin/native + + - task: CopyFiles@2 + displayName: Prepare artifacts packages folder to publish + inputs: + sourceFolder: $(Build.SourcesDirectory)/artifacts/packages + targetFolder: $(Build.ArtifactStagingDirectory)/artifacts/packages + condition: and(succeeded(), eq(variables['_librariesBuildProducedPackages'], true)) diff --git a/eng/pipelines/libraries/run-test-job.yml b/eng/pipelines/libraries/run-test-job.yml index 74bc7da3d73e37..6c5e397d4dd09a 100644 --- a/eng/pipelines/libraries/run-test-job.yml +++ b/eng/pipelines/libraries/run-test-job.yml @@ -22,6 +22,7 @@ parameters: # stress modes that each test will be run with. This is the same usage as 'testGroup' in # eng/pipelines/common/templates/runtimes/run-test-job.yml. coreclrTestGroup: '' + dependsOn: [] jobs: - template: /eng/pipelines/libraries/base-job.yml @@ -51,13 +52,16 @@ jobs: testDisplayName: ${{ parameters.runtimeFlavor }}_interpreter_${{ parameters.liveRuntimeBuildConfig }} dependsOn: - - ${{ if notIn(parameters.framework, 'allConfigurations', 'net472') }}: - - ${{ format('libraries_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} - # tests are built as part of product build - - ${{ if or(ne(parameters.archType, parameters.dependsOnTestArchitecture), ne(parameters.buildConfig, parameters.dependsOnTestBuildConfiguration)) }}: - - ${{ format('libraries_build_{0}_{1}_{2}', parameters.osGroup, parameters.dependsOnTestArchitecture, parameters.dependsOnTestBuildConfiguration) }} - - ${{ if ne(parameters.liveRuntimeBuildConfig, '') }}: - - ${{ format('{0}_{1}_product_build_{2}{3}_{4}_{5}', parameters.runtimeFlavor, parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveRuntimeBuildConfig) }} + - ${{ if ne(parameters.dependsOn[0], '') }}: + - ${{ parameters.dependsOn }} + - ${{ if eq(parameters.dependsOn[0], '') }}: + - ${{ if notIn(parameters.framework, 'allConfigurations', 'net472') }}: + - ${{ format('libraries_build_{0}{1}_{2}_{3}', parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.buildConfig) }} + # tests are built as part of product build + - ${{ if or(ne(parameters.archType, parameters.dependsOnTestArchitecture), ne(parameters.buildConfig, parameters.dependsOnTestBuildConfiguration)) }}: + - ${{ format('libraries_build_{0}_{1}_{2}', parameters.osGroup, parameters.dependsOnTestArchitecture, parameters.dependsOnTestBuildConfiguration) }} + - ${{ if ne(parameters.liveRuntimeBuildConfig, '') }}: + - ${{ format('{0}_{1}_product_build_{2}{3}_{4}_{5}', parameters.runtimeFlavor, parameters.runtimeVariant, parameters.osGroup, parameters.osSubgroup, parameters.archType, parameters.liveRuntimeBuildConfig) }} variables: - librariesTestsArtifactName: ${{ format('libraries_test_assets_{0}_{1}_{2}', parameters.osGroup, parameters.dependsOnTestArchitecture, parameters.dependsOnTestBuildConfiguration) }} diff --git a/eng/pipelines/runtimelab.yml b/eng/pipelines/runtimelab.yml new file mode 100644 index 00000000000000..6f00e775b943dd --- /dev/null +++ b/eng/pipelines/runtimelab.yml @@ -0,0 +1,185 @@ +# Setting batch to true, triggers one build at a time. +# if there is a push while a build in progress, it will wait, +# until the running build finishes, and produce a build with all the changes +# that happened during the last build. +trigger: + batch: true + branches: + include: + # Add Experiment branch here + paths: + include: + - '*' + - docs/manpages/* + exclude: + - eng/Version.Details.xml + - .github/* + - docs/* + - CODE-OF-CONDUCT.md + - CONTRIBUTING.md + - LICENSE.TXT + - PATENTS.TXT + - README.md + - SECURITY.md + - THIRD-PARTY-NOTICES.TXT + +pr: + branches: + include: + # Add Experiment branch here + paths: + include: + - '*' + - docs/manpages/* + exclude: + - eng/Version.Details.xml + - .github/* + - docs/* + - CODE-OF-CONDUCT.md + - CONTRIBUTING.md + - LICENSE.TXT + - PATENTS.TXT + - README.md + - SECURITY.md + - THIRD-PARTY-NOTICES.TXT + +variables: + - template: /eng/pipelines/common/variables.yml + +jobs: +# +# Checkout repository +# +- template: /eng/pipelines/common/checkout-job.yml + +# +# Build with Debug config and Checked runtimeConfiguration +# +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + buildConfig: Checked + platforms: + - Linux_x64 + - Windows_NT_x64 + jobParameters: + testGroup: innerloop + buildArgs: -s clr+libs+installer -c debug -runtimeConfiguration Checked + extraStepsTemplate: /eng/pipelines/runtimelab/runtimelab-post-build-steps.yml + +# +# Build with Release config and Release runtimeConfiguration +# +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + buildConfig: Release + platforms: + - Linux_x64 + - Windows_NT_x64 + jobParameters: + testGroup: innerloop + buildArgs: -s clr+libs+libs.tests+installer -c $(_BuildConfig) /p:ArchiveTests=true + extraStepsTemplate: /eng/pipelines/runtimelab/runtimelab-post-build-steps.yml + extraStepsParameters: + uploadTests: true + +# +# Build with Release allConfigurations to produce packages +# +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/global-build-job.yml + buildConfig: release + platforms: + - Windows_NT_x64 + jobParameters: + testGroup: innerloop + nameSuffix: All_Configurations + buildArgs: -s libs -c $(_BuildConfig) -allConfigurations + +# +# CoreCLR Test builds using live libraries release build +# +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/templates/runtimes/build-test-job.yml + buildConfig: Checked + platforms: + - Linux_x64 + jobParameters: + testGroup: innerloop + liveLibrariesBuildConfig: Release + dependsOn: + - build_Linux_x64_Checked_ + - build_Linux_x64_Release_ + +# +# CoreCLR Test executions using live libraries +# +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/templates/runtimes/run-test-job.yml + buildConfig: Checked + platforms: + - Linux_x64 + helixQueueGroup: pr + helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml + jobParameters: + testGroup: innerloop + liveLibrariesBuildConfig: Release + dependsOn: + - coreclr_common_test_build_p0_AnyOS_AnyCPU_Checked + +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/common/templates/runtimes/run-test-job.yml + buildConfig: Checked + platforms: + - Windows_NT_x64 + helixQueueGroup: pr + helixQueuesTemplate: /eng/pipelines/coreclr/templates/helix-queues-setup.yml + jobParameters: + testGroup: innerloop + liveLibrariesBuildConfig: Release + dependsOn: + - coreclr_common_test_build_p0_AnyOS_AnyCPU_Checked + - build_Windows_NT_x64_Checked_ + - build_Windows_NT_x64_Release_ + +# +# Libraries Release Test Execution against a release coreclr runtime +# +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/libraries/run-test-job.yml + buildConfig: Release + platforms: + - Linux_x64 + helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml + jobParameters: + isFullMatrix: false + isOfficialBuild: false + testScope: innerloop + liveRuntimeBuildConfig: Release + dependsOnTestBuildConfiguration: Release + dependsOnTestArchitecture: x64 + dependsOn: + - build_Linux_x64_Release_ + +- template: /eng/pipelines/common/platform-matrix.yml + parameters: + jobTemplate: /eng/pipelines/libraries/run-test-job.yml + buildConfig: Release + platforms: + - Windows_NT_x64 + helixQueuesTemplate: /eng/pipelines/libraries/helix-queues-setup.yml + jobParameters: + isFullMatrix: false + isOfficialBuild: false + testScope: innerloop + liveRuntimeBuildConfig: Release + dependsOnTestBuildConfiguration: Release + dependsOnTestArchitecture: x64 + dependsOn: + - build_Windows_NT_x64_Release_ diff --git a/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml b/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml new file mode 100644 index 00000000000000..e5fbcba7bc9515 --- /dev/null +++ b/eng/pipelines/runtimelab/runtimelab-post-build-steps.yml @@ -0,0 +1,59 @@ +parameters: + buildConfig: '' + archType: '' + osGroup: '' + osSubgroup: '' + uploadTests: false + +steps: + # Build coreclr native test output + - script: $(Build.SourcesDirectory)/src/coreclr/build-test$(scriptExt) skipstressdependencies skipmanaged skipgeneratelayout $(buildConfigUpper) ${{ parameters.archType }} + displayName: Build native test components + + # Copy all build output into artifacts staging directory + - template: /eng/pipelines/libraries/prepare-for-bin-publish.yml + + # Zip CoreCLR Build Output + - template: /eng/pipelines/common/upload-artifact-step.yml + parameters: + rootFolder: $(Build.SourcesDirectory)/artifacts/bin/coreclr/${{ parameters.osGroup }}.${{ parameters.archType }}.$(buildConfigUpper) + archiveType: $(archiveType) + tarCompression: $(tarCompression) + includeRootFolder: false + archiveExtension: $(archiveExtension) + artifactName: CoreCLRProduct__${{ parameters.osGroup }}${{ parameters.osSubgroup }}_${{ parameters.archType }}_${{ parameters.buildConfig }} + displayName: 'CoreCLR product build' + + # Zip Test Build + - ${{ if eq(parameters.uploadTests, true) }}: + - template: /eng/pipelines/common/upload-artifact-step.yml + parameters: + rootFolder: $(Build.SourcesDirectory)/artifacts/helix + includeRootFolder: true + archiveType: $(archiveType) + archiveExtension: $(archiveExtension) + tarCompression: $(tarCompression) + artifactName: libraries_test_assets_${{ parameters.osGroup }}_${{ parameters.archType }}_${{ parameters.buildConfig }} + displayName: Test Assets + + # Zip product native assets for use by Tests + - template: /eng/pipelines/common/upload-artifact-step.yml + parameters: + rootFolder: $(Build.SourcesDirectory)/artifacts/tests/coreclr/obj/${{ parameters.osGroup }}.${{ parameters.archType }}.$(buildConfigUpper) + includeRootFolder: false + archiveType: $(archiveType) + tarCompression: $(tarCompression) + archiveExtension: $(archiveExtension) + artifactName: CoreCLRNativeTestArtifacts_${{ parameters.osGroup }}${{ parameters.osSubgroup }}_${{ parameters.archType }}_${{ parameters.buildConfig }} + displayName: 'native test components' + + # Zip Libraries Build Output + - template: /eng/pipelines/common/upload-artifact-step.yml + parameters: + rootFolder: $(Build.ArtifactStagingDirectory)/artifacts + archiveType: $(archiveType) + tarCompression: $(tarCompression) + includeRootFolder: false + archiveExtension: $(archiveExtension) + artifactName: libraries_bin_${{ parameters.osGroup }}${{ parameters.osSubgroup }}_${{ parameters.archType }}_${{ parameters.buildConfig }} + displayName: Build Assets diff --git a/src/installer/corehost/build.proj b/src/installer/corehost/corehost.proj similarity index 100% rename from src/installer/corehost/build.proj rename to src/installer/corehost/corehost.proj diff --git a/src/libraries/libraries-packages.proj b/src/libraries/libraries-packages.proj index 2301e84828275c..f2eef864898f23 100644 --- a/src/libraries/libraries-packages.proj +++ b/src/libraries/libraries-packages.proj @@ -4,6 +4,7 @@ BuildAllProjects=true $(AdditionalBuildTargetFrameworks);package-$(Configuration) + true @@ -15,7 +16,8 @@ - + + diff --git a/src/tests/Interop/ICustomMarshaler/Primitives/ICustomMarshaler_TargetWindows.csproj b/src/tests/Interop/ICustomMarshaler/Primitives/ICustomMarshaler_TargetWindows.csproj index 854fbdda3febdd..3c152f7cb31b83 100644 --- a/src/tests/Interop/ICustomMarshaler/Primitives/ICustomMarshaler_TargetWindows.csproj +++ b/src/tests/Interop/ICustomMarshaler/Primitives/ICustomMarshaler_TargetWindows.csproj @@ -10,6 +10,6 @@ - + From 1616d2e7c91d12ef9bde2e05b5d770b2f553d61d Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 22 Jul 2020 11:10:44 -0700 Subject: [PATCH 084/458] Add rules for changing InstructionSetDesc.txt (#39777) --- .../Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt b/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt index 615fc9648ed58a..d8fe3984a92515 100644 --- a/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt +++ b/src/coreclr/src/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt @@ -15,6 +15,10 @@ ; Copy instruction sets defined for other architecture at this point in the file. ; copyinstructionsets,, +; UPDATE JIT/EE INTERFACE GUID WHEN CHANGING THESE DEFINITIONS. The instruction set definitions are part of JIT/EE interface contract. + +; DO NOT CHANGE R2R NUMERIC VALUES OF THE EXISTING SETS. Changing R2R numberic values definitions would be R2R format breaking change. + ; Definition of X86 instruction sets definearch ,X86 ,32Bit ,X64 From 49fe9460fc472190426774fe4b5015d0fce79974 Mon Sep 17 00:00:00 2001 From: Viktor Hofer Date: Wed, 22 Jul 2020 20:15:17 +0200 Subject: [PATCH 085/458] Fix double-writes in test projects (#39778) * Fix double-writes in test projects --- eng/testing/xunit/xunit.console.targets | 13 ++++++++++++- eng/testing/xunit/xunit.props | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/eng/testing/xunit/xunit.console.targets b/eng/testing/xunit/xunit.console.targets index 837b432a99eb7d..6364d461124c57 100644 --- a/eng/testing/xunit/xunit.console.targets +++ b/eng/testing/xunit/xunit.console.targets @@ -37,6 +37,7 @@ Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp'" /> @@ -62,7 +63,9 @@ @@ -74,5 +77,13 @@ CopyToOutputDirectory="PreserveNewest" Visible="false" /> + + + + + + + + diff --git a/eng/testing/xunit/xunit.props b/eng/testing/xunit/xunit.props index 8b21cecac618e3..69355a452a48ee 100644 --- a/eng/testing/xunit/xunit.props +++ b/eng/testing/xunit/xunit.props @@ -16,7 +16,7 @@ - + + diff --git a/src/libraries/System.Private.Xml/tests/Xslt/XslCompiledTransformApi/System.Xml.Xsl.XslCompiledTransformApi.Tests.csproj b/src/libraries/System.Private.Xml/tests/Xslt/XslCompiledTransformApi/System.Xml.Xsl.XslCompiledTransformApi.Tests.csproj index b372333e9628e5..d9d8f1aa2f51cb 100644 --- a/src/libraries/System.Private.Xml/tests/Xslt/XslCompiledTransformApi/System.Xml.Xsl.XslCompiledTransformApi.Tests.csproj +++ b/src/libraries/System.Private.Xml/tests/Xslt/XslCompiledTransformApi/System.Xml.Xsl.XslCompiledTransformApi.Tests.csproj @@ -14,6 +14,13 @@ + + + + + + + - \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/XslTransformApi/ReaderType.cs b/src/libraries/System.Private.Xml/tests/Xslt/XslTransformApi/ReaderType.cs new file mode 100644 index 00000000000000..719551b9f1360f --- /dev/null +++ b/src/libraries/System.Private.Xml/tests/Xslt/XslTransformApi/ReaderType.cs @@ -0,0 +1,10 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Xml.Tests +{ + public enum ReaderType + { + XmlTextReader, XmlNodeReader, XmlValidatingReader, XsltReader, Unknown + } +} \ No newline at end of file diff --git a/src/libraries/System.Private.Xml/tests/Xslt/XslTransformApi/System.Xml.Xsl.XslTransformApi.Tests.csproj b/src/libraries/System.Private.Xml/tests/Xslt/XslTransformApi/System.Xml.Xsl.XslTransformApi.Tests.csproj index 12b7f905cb450a..904076419ca091 100644 --- a/src/libraries/System.Private.Xml/tests/Xslt/XslTransformApi/System.Xml.Xsl.XslTransformApi.Tests.csproj +++ b/src/libraries/System.Private.Xml/tests/Xslt/XslTransformApi/System.Xml.Xsl.XslTransformApi.Tests.csproj @@ -13,6 +13,7 @@ + diff --git a/src/libraries/System.Private.Xml/tests/Xslt/XslTransformApi/XSLTransform.cs b/src/libraries/System.Private.Xml/tests/Xslt/XslTransformApi/XSLTransform.cs index 8a8bbd8c93944c..a0bac0cd72b7e2 100644 --- a/src/libraries/System.Private.Xml/tests/Xslt/XslTransformApi/XSLTransform.cs +++ b/src/libraries/System.Private.Xml/tests/Xslt/XslTransformApi/XSLTransform.cs @@ -27,11 +27,6 @@ public enum DocType XmlDocument, XPathDocument, Unknown } - public enum ReaderType - { - XmlTextReader, XmlNodeReader, XmlValidatingReader, XsltReader, Unknown - } - //////////////////////////////////////////////////////////////// // Module declaration for LTM usage // From d77ef3e1cae0433aef28a6798a5899b20a3ab95d Mon Sep 17 00:00:00 2001 From: Tammy Qiu Date: Wed, 22 Jul 2020 15:41:40 -0400 Subject: [PATCH 090/458] [wasm] add zone.tab to dotnet.timezones.blat (#39731) * [wasm] add zone.tab to dotnet.timezones.blat to allow system time zones to load * renable GetSystemTimeZones() * reduce size of data file by removing unnecessary timezones --- .../tests/System/TimeZoneInfoTests.cs | 1 - src/mono/wasm/runtime/dotnet.timezones.blat | Bin 634408 -> 635142 bytes 2 files changed, 1 deletion(-) diff --git a/src/libraries/System.Runtime/tests/System/TimeZoneInfoTests.cs b/src/libraries/System.Runtime/tests/System/TimeZoneInfoTests.cs index f7de159162633c..ebe6a600e0d2f9 100644 --- a/src/libraries/System.Runtime/tests/System/TimeZoneInfoTests.cs +++ b/src/libraries/System.Runtime/tests/System/TimeZoneInfoTests.cs @@ -1805,7 +1805,6 @@ public static void NewfoundlandTimeZone(string dateTimeString, bool expectedDST, } [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/39342", TestPlatforms.Browser)] public static void GetSystemTimeZones() { ReadOnlyCollection timeZones = TimeZoneInfo.GetSystemTimeZones(); diff --git a/src/mono/wasm/runtime/dotnet.timezones.blat b/src/mono/wasm/runtime/dotnet.timezones.blat index 4302a00818494d3073d2e65302bf80c37d17edf7..30b4d13614ef256ef711e7eb2c6bfa04f7acbec3 100644 GIT binary patch delta 785 zcmY*XO>fgM7#1IcITwVq8y9Pnrd4r>9Xm_MPH9&HUAsk1s%fBUa$9c=O6|!>G;IfZ zKmuvk-4REwoVfBs5C?t(KLB^5W3%+gdiCmgpXdGf`g8T;@70Bp=Yx0O7WUmG^mh4N zN%6eogJnd54MGkME}#Bbx%~BK@xz7t>B7BdaNpp8!9#-ugGUCB4Hmy&xZv~qCt(jb zUfruZc-?0Kxcsv8YzmsZY7X@6KsG@{i3ts#q6F;yC@qKcO91C5J!Ja5ep{EkwRJ}`Y z%*;~iIhd`}0E82vv!PMu>M-V2u0TWc^DKvJ#ms4zl)gdz2<@l9!Gr`hrt542ghy8++2NU1gUsse1Dkq2o4F!p;Mdty zXD2GptT;8 Date: Wed, 22 Jul 2020 12:54:37 -0700 Subject: [PATCH 091/458] Add events around type load and r2r usage (#39656) - Allows for investigation of type loader performance - Uses a new keyword, as this event will generate many strings which is itself fairly slow - Changes R2R events from Verbose events to Informational events - These events are already controlled by a separate keyword, and don't need to also be only emitted when Verbose eventing is on --- src/coreclr/src/inc/eventtrace.h | 2 + src/coreclr/src/inc/eventtracebase.h | 2 + src/coreclr/src/vm/ClrEtwAll.man | 77 ++++++++++++++++++++++++++- src/coreclr/src/vm/clsload.cpp | 11 ++++ src/coreclr/src/vm/eventtrace.cpp | 76 ++++++++++++++++++++++++++ src/coreclr/src/vm/readytoruninfo.cpp | 2 + 6 files changed, 168 insertions(+), 2 deletions(-) diff --git a/src/coreclr/src/inc/eventtrace.h b/src/coreclr/src/inc/eventtrace.h index ef999a716c6943..1a930deebfa3e1 100644 --- a/src/coreclr/src/inc/eventtrace.h +++ b/src/coreclr/src/inc/eventtrace.h @@ -172,6 +172,8 @@ namespace ETW static void Cleanup(); static VOID DeleteTypeHashNoLock(AllLoggedTypes **ppAllLoggedTypes); static VOID FlushObjectAllocationEvents(); + static UINT32 TypeLoadBegin(); + static VOID TypeLoadEnd(UINT32 typeLoad, TypeHandle th, UINT16 loadLevel); private: static BOOL ShouldLogType(TypeHandle th); diff --git a/src/coreclr/src/inc/eventtracebase.h b/src/coreclr/src/inc/eventtracebase.h index 771460b2db14de..863f704ab87b57 100644 --- a/src/coreclr/src/inc/eventtracebase.h +++ b/src/coreclr/src/inc/eventtracebase.h @@ -918,6 +918,7 @@ namespace ETW static const UINT8 MethodFlagsJitOptimizationTierShift = 7; static const unsigned int MethodFlagsJitOptimizationTierLowMask = 0x7; + static VOID GetR2RGetEntryPointStart(MethodDesc *pMethodDesc); static VOID GetR2RGetEntryPoint(MethodDesc *pMethodDesc, PCODE pEntryPoint); static VOID MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature); static VOID MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature, PCODE pNativeCodeStartAddress, PrepareCodeConfig *pConfig); @@ -928,6 +929,7 @@ namespace ETW static VOID DynamicMethodDestroyed(MethodDesc *pMethodDesc); #else // FEATURE_EVENT_TRACE public: + static VOID GetR2RGetEntryPointStart(MethodDesc *pMethodDesc) {}; static VOID GetR2RGetEntryPoint(MethodDesc *pMethodDesc, PCODE pEntryPoint) {}; static VOID MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature); static VOID MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature, PCODE pNativeCodeStartAddress, PrepareCodeConfig *pConfig); diff --git a/src/coreclr/src/vm/ClrEtwAll.man b/src/coreclr/src/vm/ClrEtwAll.man index c68eac52ac28ea..cf2108b4e56ac3 100644 --- a/src/coreclr/src/vm/ClrEtwAll.man +++ b/src/coreclr/src/vm/ClrEtwAll.man @@ -83,6 +83,8 @@ message="$(string.RuntimePublisher.CompilationDiagnosticKeywordMessage)" symbol="CLR_COMPILATIONDIAGNOSTIC_KEYWORD" /> + @@ -401,7 +403,14 @@ - + + + + + + @@ -1895,6 +1904,34 @@ + + + + + +